read: block comments
This commit is contained in:
parent
e109c255ad
commit
2e43f36471
78
read.scm
78
read.scm
|
@ -120,6 +120,18 @@
|
||||||
|
|
||||||
;;; ;;;;;;;;;;;;;;;;;;;;;;
|
;;; ;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;; Readtable constructors
|
;;; Readtable constructors
|
||||||
|
;;;
|
||||||
|
;;; Readtables are composed of a CHARMAP, which is a map from characters
|
||||||
|
;;; to actions, and a DEFAULT-ACTION, which is taken when there is no
|
||||||
|
;;; match in CHARMAP.
|
||||||
|
;;;
|
||||||
|
;;; An "action" is a procedure that takes four arguments:
|
||||||
|
;;;
|
||||||
|
;;; TABLE: The current table.
|
||||||
|
;;; CHAR: The character that was matched against the CHARMAP in TABLE.
|
||||||
|
;;; ACC: An arbitrary "accumulator" value that is different depending
|
||||||
|
;;; on the readtable in question.
|
||||||
|
;;; PORT: A port reader object.
|
||||||
;;; ;;;;;;;;;;;;;;;;;;;;;;
|
;;; ;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
;;; (READTABLE:NEW DEFAULT-ACTION CHARMAP)
|
;;; (READTABLE:NEW DEFAULT-ACTION CHARMAP)
|
||||||
|
@ -167,7 +179,7 @@
|
||||||
functions)))
|
functions)))
|
||||||
|
|
||||||
;;; ;;;;;;;;;;;;;;;;;;
|
;;; ;;;;;;;;;;;;;;;;;;
|
||||||
;;; Default readtables
|
;;; Default actions
|
||||||
;;; ;;;;;;;;;;;;;;;;;;
|
;;; ;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
;;; Return an error.
|
;;; Return an error.
|
||||||
|
@ -208,6 +220,12 @@
|
||||||
(lambda (oldtable __ _ port)
|
(lambda (oldtable __ _ port)
|
||||||
(readtable:next newtable oldtable port))))
|
(readtable:next newtable oldtable port))))
|
||||||
|
|
||||||
|
;;; Jump to a new readtable, reading the new character.
|
||||||
|
(define readtable:jump/next
|
||||||
|
(lambda (newtable)
|
||||||
|
(lambda (oldtable _ acc port)
|
||||||
|
(readtable:next newtable acc port))))
|
||||||
|
|
||||||
;;; ;;;;;;;;;;;;;;;;;
|
;;; ;;;;;;;;;;;;;;;;;
|
||||||
;;; Identifier reader
|
;;; Identifier reader
|
||||||
;;; ;;;;;;;;;;;;;;;;;
|
;;; ;;;;;;;;;;;;;;;;;
|
||||||
|
@ -359,16 +377,69 @@
|
||||||
port)))
|
port)))
|
||||||
|
|
||||||
;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;; Reader for datum that start with "#"
|
;;; Reader for stuff that start with "#"
|
||||||
;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(define readtable:vector
|
(define readtable:vector
|
||||||
(lambda (_ __ toplevel port)
|
(lambda (_ __ toplevel port)
|
||||||
(list 'vector (readtable:read-proper-list toplevel port))))
|
(list 'vector (readtable:read-proper-list toplevel port))))
|
||||||
|
|
||||||
|
;;; Block comment reader.
|
||||||
|
;;;
|
||||||
|
;;; The outermost block comment reader is passed the toplevel reader as
|
||||||
|
;;; ACC. When the outermost block is finished, it will tail-call ACC.
|
||||||
|
;;; (It is basically the continuation of the reader.)
|
||||||
|
;;;
|
||||||
|
;;; When a nested block comment is found, it is passed #F as ACC, which
|
||||||
|
;;; it will not call. It will return an unspecified value.
|
||||||
|
;;;
|
||||||
|
;;; Since the read tables are not procedures, references to other tables
|
||||||
|
;;; in the same LETREC declaration must be protected with explicit LAMBDAs.
|
||||||
|
;;; Macros could make this much easier to read.
|
||||||
|
(define readtable:block-comment
|
||||||
|
(letrec ((potential-end
|
||||||
|
(readtable:process
|
||||||
|
(readtable:empty/default
|
||||||
|
(lambda (this char acc port) (readtable:act
|
||||||
|
loop
|
||||||
|
char
|
||||||
|
acc
|
||||||
|
port)))
|
||||||
|
(list readtable:update #\#
|
||||||
|
(lambda (this char acc port)
|
||||||
|
(if acc
|
||||||
|
(readtable:next acc #f port))))))
|
||||||
|
(potential-start
|
||||||
|
(readtable:process
|
||||||
|
(readtable:empty/default
|
||||||
|
(lambda (this char acc port) (readtable:act
|
||||||
|
loop
|
||||||
|
char
|
||||||
|
acc
|
||||||
|
port)))
|
||||||
|
(list readtable:update #\|
|
||||||
|
(lambda (this char acc port)
|
||||||
|
(readtable:next loop #f port)
|
||||||
|
(readtable:next loop acc port)))))
|
||||||
|
(loop
|
||||||
|
(readtable:process
|
||||||
|
(readtable:empty/default readtable:skip)
|
||||||
|
(list readtable:update #\#
|
||||||
|
(lambda (this char acc port)
|
||||||
|
(readtable:next potential-start
|
||||||
|
acc
|
||||||
|
port)))
|
||||||
|
(list readtable:update #\|
|
||||||
|
(lambda (this char acc port)
|
||||||
|
(readtable:next potential-end
|
||||||
|
acc
|
||||||
|
port))))))
|
||||||
|
loop))
|
||||||
|
|
||||||
(define readtable:hash
|
(define readtable:hash
|
||||||
(readtable:process
|
(readtable:process
|
||||||
(readtable:empty/default (readtable:error "unimplemented"))
|
(readtable:empty/default (readtable:error "unimplemented"))
|
||||||
|
(list readtable:update #\| (readtable:jump/next readtable:block-comment))
|
||||||
(list readtable:update %bol readtable:vector)))
|
(list readtable:update %bol readtable:vector)))
|
||||||
|
|
||||||
;;; ;;;;;;;;;;;;;;;;
|
;;; ;;;;;;;;;;;;;;;;
|
||||||
|
@ -424,3 +495,6 @@
|
||||||
(read-all "( a . b )")
|
(read-all "( a . b )")
|
||||||
(read-all "( a .b . c)")
|
(read-all "( a .b . c)")
|
||||||
(read-all "#( a b y)")
|
(read-all "#( a b y)")
|
||||||
|
(read-all "(x y #| this is a block\n comment\n |# z w)")
|
||||||
|
(read-all "#( a b #| this is a #| nested block |# comment|# z w)")
|
||||||
|
(read-all "#(a b #(c #|close#|comment|#|#y))")
|
||||||
|
|
Loading…
Reference in New Issue