aboutsummaryrefslogtreecommitdiffstats
path: root/read.scm
diff options
context:
space:
mode:
authorGravatar Peter McGoron 2024-09-27 15:40:30 -0400
committerGravatar Peter McGoron 2024-09-27 15:40:30 -0400
commitb94e12ee33090d398caeac957de83c5039225272 (patch)
treef6b7fa5e64c8529e0c99274d2afee7c0bfc2fc54 /read.scm
parentread: properly restore state when reading datum comments (diff)
read: hash constants and directives
Diffstat (limited to 'read.scm')
-rw-r--r--read.scm49
1 files changed, 37 insertions, 12 deletions
diff --git a/read.scm b/read.scm
index c430240..df2f97c 100644
--- a/read.scm
+++ b/read.scm
@@ -35,7 +35,6 @@
;;; All tokens are procedure-encapsulated objects, since the reader should
;;; never return a literal procedure. Each procedure has a TYPE message.
-
(load "chez-compat.scm")
(load "util.scm")
(load "set.scm")
@@ -515,16 +514,6 @@
port))))))
loop))
-;;; Encapsulate LINKED-LIST object with an additional value for the
-;;; toplevel table.
-(define linked-list/toplevel:new
- (lambda (toplevel)
- (let ((ll (linked-list:new)))
- (lambda (op . args)
- (cond
- ((eq? op 'toplevel) toplevel)
- (else (apply ll op args)))))))
-
(define read:datum-label
(lambda (location toplevel)
(let ((finalized? #f)
@@ -597,9 +586,42 @@
(port 'restore-mutable! mutable))
(readtable:next toplevel #f port)))
+;;; String map from constants to procedures with formal arguments
+;;; (TOPLEVEL PORT)
+;;; with TOPLEVEL being the current toplevel table and PORT being the
+;;; current port being read from.
+;;;
+;;; Each one must return something. Directives that return nothing must
+;;; call the toplevel again.
+(define read:hash-constants
+ (smap:insert-many
+ '()
+ (cons "true" (lambda unused #t))
+ (cons "false" (lambda unused #f))
+ (cons "t" (lambda unused #t))
+ (cons "f" (lambda unused #f))
+ (cons "!fold-case"
+ (lambda (toplevel port)
+ (port 'fold-case! #t)
+ (readtable:act toplevel (port 'read) #f port)))
+ (cons "!no-fold-case"
+ (lambda (toplevel port)
+ (port 'fold-case! #f)
+ (readtable:act toplevel (port 'read) #f port)))))
+
+(define read:read-hash-constants
+ (lambda (_ char acc port)
+ (let ((ident (readtable:read-ident #f char #f port)))
+ (let ((container (smap:search read:hash-constants
+ (ident 'value))))
+ (if (null? container)
+ (error 'read-hash-constants 'unknown-constant
+ (ident 'value))
+ ((map:val container) acc port))))))
+
(define readtable:hash
(readtable:process
- (readtable:empty/default (readtable:error 'hash "unimplemented"))
+ (readtable:empty/default read:read-hash-constants)
(list readtable:update #\| (readtable:jump/next readtable:block-comment))
(list readtable:update #\; readtable:datum-comment)
(list readtable:update-list readtable:digits ; Datum labels
@@ -712,3 +734,6 @@
(read-all "#(a b #(c #|close#|comment|#|#y))")
(read-all "(this has a #;(call with (current continuation)) datum comment)")
(read-all "#0=(#0# not unix)")
+(read-all "#!no-fold-case #!fold-case #!NO-FOLD-CASE #false")
+(read-all "#!fold-case #TRUE")
+