 : number-char? ( char -- ? )
     "0123456789ABCDEFabcdef." member? ; inline
 
+: last-unsafe ( seq -- elt )
+    [ length 1 - ] [ nth-unsafe ] bi ; inline
+
 : numeric-looking? ( str -- ? )
-    "-" ?head drop
     dup empty? [ drop f ] [
-        dup first number-char? [
-            last number-char?
-        ] [ drop f ] if
-    ] if ;
+        dup first-unsafe number-char? [
+            last-unsafe number-char?
+        ] [
+            dup first-unsafe CHAR: - eq? [
+                dup length 1 eq? [ drop f ] [
+                    1 over nth-unsafe number-char? [
+                        last-unsafe number-char?
+                    ] [ drop f ] if
+                ] if
+            ] [ drop f ] if
+        ] if
+    ] if ; inline
 
 PRIVATE>
 

IN: math.parser

: digit> ( ch -- n )
    H{
        { CHAR: 0 0 }
        { CHAR: 1 1 }
        { CHAR: 2 2 }
        { CHAR: 3 3 }
        { CHAR: 4 4 }
        { CHAR: 5 5 }
        { CHAR: 6 6 }
        { CHAR: 7 7 }
        { CHAR: 8 8 }
        { CHAR: 9 9 }
        { CHAR: A 10 }
        { CHAR: B 11 }
        { CHAR: C 12 }
        { CHAR: D 13 }
        { CHAR: E 14 }
        { CHAR: F 15 }
        { CHAR: a 10 }
        { CHAR: b 11 }
        { CHAR: c 12 }
        { CHAR: d 13 }
        { CHAR: e 14 }
        { CHAR: f 15 }
        { CHAR: , f }
    } at* [ drop 255 ] unless ; inline

: string>digits ( str -- digits )
    [ digit> ] B{ } map-as ; inline

: (digits>integer) ( valid? accum digit radix -- valid? accum )
    over [
        2dup < [ swapd * + ] [ 2drop 2drop f 0 ] if
    ] [ 2drop ] if ; inline

: each-digit ( seq radix quot -- n/f )
    [ t 0 ] 3dip curry each swap [ drop f ] unless ; inline


: string>natural ( seq radix -- n/f )
    over empty? [ 2drop f ] [
        [ over CHAR: , eq? [ 2drop ] [ [ digit> ] dip (digits>integer) ] if ] each-digit
    ] if ;

: sign ( -- str ) negative? get "-" "+" ? ;

