: parse-digit ( u -- u -1 | 0 0 ) { DUP $30 $3a WITHIN } { $30 - TRUE } { DUP $41 $5b WITHIN } { $37 - TRUE } { DUP $61 $7b WITHIN } { $57 - TRUE } { ." parse-digit 1: " TODO } 3 CASE ; : add-digit ( u u -- u flag ) ." add-digit 0: " TODO ; : parse-digits-0 ( u addr len -- u flag ) { OVER B@ -ROT { parse-digit } 2DIP ROT { { SWAP base B@ * + } 2DIP 1 /STRING parse-digits-0 } WHEN } { DROP TRUE } ?COND ; : parse-digits ( u addr len -- u flag ) { parse-digits-0 } { DROP FALSE } ?COND ; : parse-prefix-if-exists ( addr len -- addr len 0|1|2 ) DUP { OVER B@ { DUP $2d = } { DROP 1 /STRING 1 } { DUP $7e = } { DROP 1 /STRING 2 } { DROP 0 } 2 CASE } { 0 } COND ; : parse-base-if-exists ( addr len -- addr len base ) DUP { OVER B@ { DUP $23 = } { DROP 1 /STRING #10 } { DUP $24 = } { DROP 1 /STRING $10 } { DUP $25 = } { DROP 1 /STRING %10 } { DUP $5e = } { DROP 1 /STRING ^10 } { DROP 2DUP $3a SCAN DUP } { 1 /STRING { NIP - 1- 10 BASE B! 0 -ROT parse-digits } 2KEEP ROT { ROT } { ." parse-base-if-exists 1: " TODO } COND \ ." parse-base-if-exists 2: " TODO } { 2DROP base B@ } 5 CASE } { base B@ } COND ; : with-saved-base ( x*i { x*i -- x*j } -- x*j ) base B@ SWAP DIP base B! ; : apply-prefix ( u 0|1|2 -- n ) { } { NEGATE } { INVERT } 3 SWITCH ; : parse-number ( addr len -- u -1 | 0 0 ) { parse-base-if-exists base B! parse-prefix-if-exists { 0 -ROT parse-digits } DIP SWAP { apply-prefix TRUE } { DROP FALSE } COND } with-saved-base ;