anchor.diff:                (consume!)
                 (append! "unquote-splice" start))
               (append! "unquote")))
  -          ((or (between? char "0" "9") (and (= char "-") (between? (string/char-at str (succ offset)) "0" "9")))
  -            (with (start (position))
  -              (while (string/find (string/char-at str (succ offset)) "[0-9.e+-]")
  -                (consume!))
  -              (append! "number" start)))
  +          ((string/find str "^%-?%.?[0-9]" offset)
  +            (let [(start (position))
  +                  (negative (= char "-"))]
  +              ;; Check whether this number is negative
  +              (when negative
  +                (consume!)
  +                (set! char (string/char-at str offset)))
  +
  +              (with (val (cond
  +                           ;; Parse hexadecimal digits
  +                           ((and (= char "0") (= (string/char-at str (succ offset)) "x"))
  +                             (consume!)
  +                             (consume!)
  +                             (with (res (parse-base "hexadecimal" hex-digit? 16))
  +                               (when negative (set! res (- 0 res))
  +                               res)))
  +                           ;; Parse binary digits
  +                           ((and (= char "0") (= (string/char-at str (succ offset)) "b"))
  +                             (consume!)
  +                             (consume!)
  +                             (with (res (parse-base "binary" bin-digit? 2))
  +                               (when negative (set! res (- 0 res))
  +                               res)))
  +                           (true
  +                             ;; Parse leading digits
  +                             (while (between? (string/char-at str (succ offset))  "0" "9")
  +                               (consume!))
  +
  +                             ;; Consume decimal places
  +                             (when (= (string/char-at str (succ offset)) ".")
  +                               (consume!)
  +                               (while (between? (string/char-at str (succ offset))  "0" "9")
  +                                 (consume!)))
  +
  +                             ;; Consume exponent
  +                             (set! char (string/char-at str (succ offset)))
  +                             (when (or (= char "e") (= char "E"))
  +                               (consume!)
  +                               (set! char (string/char-at str (succ offset)))
  +
  +                               ;; Gobble positive/negative bit
  +                               (when (or (= char "-") (= char "+")) (consume!))
  +
  +                               ;; And exponent digits
  +                               (while (between? (string/char-at str (succ offset)) "0" "9")
  +                                 (consume!)))
  +
  +                             (string->number (string/sub str (.> start :offset) offset)))))
  +                (append-with! (struct :tag "number" :value val) start)
  +
  +                ;; Ensure the next character is a terminator of some sort, otherwise we'd allow things like 0x2-2
  +                (set! char (string/char-at str (succ offset)))
  +                (unless (terminator? char)
  +                  (consume!)
  +
  +                  (logger/print-error! (string/format "Expected digit, got %s" (if (= char "")
  +                                                                                 "eof"
  +                                                                                 char)))
  +                  (logger/put-trace! (range (position)))
  +                  (logger/put-lines! false
  +                    (range (position))  "Illegal character here. Are you missing whitespace?")
  +                  (fail! "Lexing failed")))))
             ((= char "\"")
               (with (start (position))
                 (consume!)
  
positive.code: (import string)
  (import urn/logger logger)
  (import function (cut))
  
  (defun lex (str name)
    (let* ((lines (string/split str "\n"))
  
negative.code:             (let ((start (position))
                    (tag (if (= char ":" ) "key" "symbol")))
                (set! char (string/char-at str (succ offset)))
                (while (! (terminator? char))
                  (consume!)
                  (set! char (string/char-at str (succ offset))))
                (append! tag start))))
  