diff --git a/scheme/read.sld b/scheme/read.sld index ec36eb86..aa399f10 100644 --- a/scheme/read.sld +++ b/scheme/read.sld @@ -313,19 +313,25 @@ (parse fp '() (cons #f toks) all? #f parens ptbl) #f)) ;; Numbers -;; TODO: #b (binary), #o (octal), #d (decimal), and #x (hexadecimal) ((eq? #\e next-c) - (parse-number - fp toks all? parens ptbl + (parse-number fp toks all? parens ptbl 10 (lambda (num) (exact (parse-atom num))))) ((eq? #\i next-c) - (parse-number - fp toks all? parens ptbl + (parse-number fp toks all? parens ptbl 10 (lambda (num) (inexact (parse-atom num))))) + ((eq? #\b next-c) + (parse-number fp toks all? parens ptbl + 2 (lambda (num) (list->string num)))) + ((eq? #\o next-c) + (parse-number fp toks all? parens ptbl + 8 (lambda (num) (list->string num)))) + ((eq? #\x next-c) + (parse-number fp toks all? parens ptbl + 16 (lambda (num) (list->string num)))) ;; Vector ((eq? #\( next-c) (let ((sub (parse fp '() '() #t #f (+ parens 1) ptbl)) @@ -467,11 +473,14 @@ (define (parse-number fp toks all? parens ptbl base tok->num) ; (parse-number-rec base fp '() ptbl)) - (let ((num (parse-number-rec 10 fp '() ptbl))) + (let ((num (parse-number-rec base fp '() ptbl))) ;(write `(DEBUG2 ,num ,(string? num))) (cond ((and (not (null? num)) - (token-numeric? num)) + (or (token-numeric? num) + (and (> (length num) 0) + (= base 16) + (hex-digit? (car num))))) (let ((result (tok->num num))) (if all? (parse fp '() (cons result toks) all? #f parens ptbl) @@ -488,11 +497,24 @@ (cond ((sign? c) (next c)) ((eq? #\. c) (next c)) - ((char-numeric? c) (next c)) + ((char-numeric? c) + (if (or (and (= base 2) (char>? c #\1)) + (and (= base 8) (char>? c #\7))) + (parse-error + "Illegal digit" + (in-port:get-lnum ptbl) + (in-port:get-cnum ptbl))) + (next c)) + ((and (= base 16) (hex-digit? c)) + (next c)) (else ;; We are done parsing a number (in-port:set-buf! ptbl c) ;; rebuffer unprocessed char (reverse tok))))) ;; Return token + +(define (hex-digit? c) + (or (and (char>=? c #\a) (char<=? c #\f)) + (and (char>=? c #\A) (char<=? c #\F)))) ;;;;; ;; Main lexer/parser