(module acl2-readtable mzscheme
(require (lib "readerr.ss" "syntax")
(lib "port.ss"))
(provide acl2-readtable)
(define (hash-minus char port w x y z)
(parameterize ([read-case-sensitive #f])
(let ([test-expr (read port)])
(if (memq test-expr '(gcl non-standard-analysis :non-standard-analysis))
(make-special-comment test-expr)
(make-special-comment (list test-expr (read port)))))))
(define (hash-plus char port w x y z)
(parameterize ([read-case-sensitive #f])
(let ([test-expr (read port)])
(if (memq test-expr '(non-standard-analysis :non-standard-analysis))
(make-special-comment (list test-expr (read port)))
(make-special-comment (list test-expr (read port)))))))
(define hash-bool
(lambda (char port w x y z)
(parameterize ([read-case-sensitive #f])
(raise-read-error (string-append (string #\# char) " is not a valid ACL2 datum. "
"The booleans are t and nil.")
w x y z 2))))
(define (hash-c char port w x y z)
(parameterize ([read-case-sensitive #f])
(case (peek-char port)
[(#\() (let ([expr (read port)])
(if (and (list? expr) (= 2 (length expr)))
(let ([fst (car expr)]
[snd (cadr expr)])
(if (and (number? fst) (number? snd))
(+ fst (* snd 0+i))
(raise-read-error "Expected #c(x y) where x and y are both numerals"
w x y z 1)))
(raise-read-error "Expected #c(x y) where x and y are both numerals"
w x y z 1)))]
[else (read-syntax/recursive w (input-port-append #f (open-input-string (string char)) port)
#\# #f)])))
(define (hash-double-quote char port w x y z)
(raise-read-error (string-append (string #\# char) " is not a valid ACL2 reader syntax. ")
w x y z 2))
(define (hash-semicolon char port w x y z)
(raise-read-error (string-append (string #\# char) " cannot be used for ACL2 comments. ")
w x y z 2))
(define check-infinity
(let ([inf-str "inf.0"])
(lambda (char port src x y z)
(parameterize ([read-case-sensitive #f])
(let* ([next-ch (peek-char port)]
[next (if (and (char? next-ch) (char-ci=? next-ch #\i)) (read port) #f)])
(cond [(and (symbol? next) (string-ci=? inf-str (symbol->string next)))
(raise-read-error "ACL2 cannot perform floating-point arithmetic"
src x y z 6)]
[(eof-object? next) (read-syntax/recursive src port char #f)]
[(char-ci=? next-ch #\i)
(let ([prefix (open-input-string (let ([x (open-output-string)])
(write next x)
(get-output-string x)))])
(read-syntax/recursive src (input-port-append #f prefix port) char #f))]
[else (read-syntax/recursive src port char #f)])))
)))
(define acl2-readtable
(make-readtable (current-readtable)
#\; 'dispatch-macro hash-semicolon
#\t 'dispatch-macro hash-bool
#\T 'dispatch-macro hash-bool
#\f 'dispatch-macro hash-bool
#\F 'dispatch-macro hash-bool
#\" 'dispatch-macro hash-double-quote
#\c 'dispatch-macro hash-c
#\C 'dispatch-macro hash-c
#\- 'dispatch-macro hash-minus
#\+ 'dispatch-macro hash-plus
#\+ 'non-terminating-macro check-infinity
#\- 'non-terminating-macro check-infinity
))
)