read: add object encapsulating identifier
This commit is contained in:
parent
df69826312
commit
fee4198f2f
|
@ -47,8 +47,3 @@
|
||||||
(begin evaluated ...)
|
(begin evaluated ...)
|
||||||
(cond-expand rest ...)))))
|
(cond-expand rest ...)))))
|
||||||
|
|
||||||
(define %r6rs-error error)
|
|
||||||
|
|
||||||
(define (error . rest)
|
|
||||||
(apply %r6rs-error (cons "UNSLISP" rest)))
|
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
(%set-cdr!
|
(%set-cdr!
|
||||||
(lambda (val)
|
(lambda (val)
|
||||||
(if (null? tail)
|
(if (null? tail)
|
||||||
(error "cannot set cdr of empty list")
|
(error 'linked-list "cannot set cdr of empty list")
|
||||||
(set-cdr! tail val)))))
|
(set-cdr! tail val)))))
|
||||||
(lambda args
|
(lambda args
|
||||||
(let ((op (car args)))
|
(let ((op (car args)))
|
||||||
|
@ -72,7 +72,7 @@
|
||||||
((eq? op 'set-cdr!) (apply %set-cdr! (cdr args)))
|
((eq? op 'set-cdr!) (apply %set-cdr! (cdr args)))
|
||||||
((eq? op 'to-list) head)
|
((eq? op 'to-list) head)
|
||||||
((eq? op 'traverse-from-head) (linked-list-elem:new head))
|
((eq? op 'traverse-from-head) (linked-list-elem:new head))
|
||||||
(else (error (cons "invalid operation" args))))))))))
|
(else (error 'linked-list (cons "invalid operation" args))))))))))
|
||||||
|
|
||||||
(define x (linked-list:new))
|
(define x (linked-list:new))
|
||||||
(x 'push-tail 1)
|
(x 'push-tail 1)
|
||||||
|
|
64
read.scm
64
read.scm
|
@ -82,6 +82,8 @@
|
||||||
;; OFFSET is sometimes set to #F to denote an unknown
|
;; OFFSET is sometimes set to #F to denote an unknown
|
||||||
;; offset.
|
;; offset.
|
||||||
(offset (set! offset (+ 1 offset))))))
|
(offset (set! offset (+ 1 offset))))))
|
||||||
|
(location
|
||||||
|
(lambda () (list filename line-number offset)))
|
||||||
(set-datum-label!
|
(set-datum-label!
|
||||||
(lambda (label value)
|
(lambda (label value)
|
||||||
(set! datum-labels
|
(set! datum-labels
|
||||||
|
@ -107,7 +109,7 @@
|
||||||
(lambda (op . args)
|
(lambda (op . args)
|
||||||
;; TODO: turn into string map?
|
;; TODO: turn into string map?
|
||||||
(cond
|
(cond
|
||||||
((eq? op 'pos) (list filename line-number offset))
|
((eq? op 'location) (location))
|
||||||
((eq? op 'read)
|
((eq? op 'read)
|
||||||
(process
|
(process
|
||||||
(if (null? pushback-buffer)
|
(if (null? pushback-buffer)
|
||||||
|
@ -131,7 +133,7 @@
|
||||||
((eq? op 'fold-case!) (set! fold-case? (car args)))
|
((eq? op 'fold-case!) (set! fold-case? (car args)))
|
||||||
((eq? op 'set-datum-label!) (apply set-datum-label! args))
|
((eq? op 'set-datum-label!) (apply set-datum-label! args))
|
||||||
((eq? op 'get-datum-label) (apply get-datum-label args))
|
((eq? op 'get-datum-label) (apply get-datum-label args))
|
||||||
(else (error "read->port: invalid" (cons op args)))))))
|
(else (error 'read->port 'invalid (cons op args)))))))
|
||||||
port))))
|
port))))
|
||||||
|
|
||||||
;;; ;;;;;;;;;;;;;;
|
;;; ;;;;;;;;;;;;;;
|
||||||
|
@ -283,11 +285,29 @@
|
||||||
;;; Identifier reader
|
;;; Identifier reader
|
||||||
;;; ;;;;;;;;;;;;;;;;;
|
;;; ;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(define read:ident
|
||||||
|
(lambda (name location)
|
||||||
|
(lambda (op . args)
|
||||||
|
(cond
|
||||||
|
((eq? op 'type) 'ident)
|
||||||
|
((eq? op 'value) name)
|
||||||
|
(else (error 'read:ident "invalid operation" op args))))))
|
||||||
|
|
||||||
|
(define read:ident-builder
|
||||||
|
(lambda (start-char location)
|
||||||
|
(let ((char-list (linked-list:new)))
|
||||||
|
(char-list 'push start-char)
|
||||||
|
(lambda (op . args)
|
||||||
|
(cond
|
||||||
|
((eq? op 'finalize->ident)
|
||||||
|
(read:ident (list->string (char-list 'to-list)) location))
|
||||||
|
(else (apply char-list op args)))))))
|
||||||
|
|
||||||
;;; Push back CHAR and return ACC.
|
;;; Push back CHAR and return ACC.
|
||||||
(define readtable:return-acc-keep-char
|
(define readtable:return-acc-as-ident
|
||||||
(lambda (table char acc port)
|
(lambda (table char acc port)
|
||||||
(port 'push char)
|
(port 'push char)
|
||||||
acc))
|
(acc 'finalize->ident)))
|
||||||
|
|
||||||
;;; Push CHAR to ACC and continue reading from TABLE.
|
;;; Push CHAR to ACC and continue reading from TABLE.
|
||||||
(define readtable:push-char
|
(define readtable:push-char
|
||||||
|
@ -300,7 +320,7 @@
|
||||||
(define readtable:exclude-from-identifiers
|
(define readtable:exclude-from-identifiers
|
||||||
(lambda (table excluded)
|
(lambda (table excluded)
|
||||||
(fold (lambda (char table)
|
(fold (lambda (char table)
|
||||||
(readtable:update table char readtable:return-acc-keep-char))
|
(readtable:update table char readtable:return-acc-as-ident))
|
||||||
table
|
table
|
||||||
excluded)))
|
excluded)))
|
||||||
|
|
||||||
|
@ -325,12 +345,11 @@
|
||||||
;;; Read an identifier starting with CHAR.
|
;;; Read an identifier starting with CHAR.
|
||||||
(define readtable:read-ident
|
(define readtable:read-ident
|
||||||
(lambda (table char acc port)
|
(lambda (table char acc port)
|
||||||
(let ((lst (linked-list:new)))
|
(readtable:act readtable:identifier
|
||||||
(lst 'push char)
|
(port 'read)
|
||||||
(list->string
|
(read:ident-builder char
|
||||||
((readtable:act readtable:identifier
|
(port 'location))
|
||||||
(port 'read) lst port)
|
port)))
|
||||||
'to-list)))))
|
|
||||||
|
|
||||||
;;; ;;;;;;;;;;;;;;;;;;;;
|
;;; ;;;;;;;;;;;;;;;;;;;;
|
||||||
;;; Comments and whitespace reader
|
;;; Comments and whitespace reader
|
||||||
|
@ -357,6 +376,7 @@
|
||||||
(readtable:act (readtable:update table
|
(readtable:act (readtable:update table
|
||||||
%eol
|
%eol
|
||||||
(readtable:error
|
(readtable:error
|
||||||
|
'read-improper-cdr
|
||||||
"proper list must have cdr"))
|
"proper list must have cdr"))
|
||||||
(port 'read)
|
(port 'read)
|
||||||
#f
|
#f
|
||||||
|
@ -364,6 +384,7 @@
|
||||||
(acc 'set-cdr! val)
|
(acc 'set-cdr! val)
|
||||||
(let ((table (readtable:process
|
(let ((table (readtable:process
|
||||||
(readtable:empty/default (readtable:error
|
(readtable:empty/default (readtable:error
|
||||||
|
'read-improper-cdr
|
||||||
"improper list has 1 cdr"))
|
"improper list has 1 cdr"))
|
||||||
(list readtable:update-list
|
(list readtable:update-list
|
||||||
readtable:ASCII-whitespace
|
readtable:ASCII-whitespace
|
||||||
|
@ -419,7 +440,9 @@
|
||||||
(lambda (table port)
|
(lambda (table port)
|
||||||
(readtable:read-list-loop (readtable:table-for-list
|
(readtable:read-list-loop (readtable:table-for-list
|
||||||
table
|
table
|
||||||
(readtable:error "expected proper list"))
|
(readtable:error
|
||||||
|
'read-proper-list
|
||||||
|
"expected proper list"))
|
||||||
port)))
|
port)))
|
||||||
|
|
||||||
;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
@ -499,7 +522,8 @@
|
||||||
;;; looks like "#[NUMBER]=" and a reference looks like "#[NUMBER]#".
|
;;; looks like "#[NUMBER]=" and a reference looks like "#[NUMBER]#".
|
||||||
(define readtable:datum-label-next
|
(define readtable:datum-label-next
|
||||||
(readtable:process
|
(readtable:process
|
||||||
(readtable:empty/default (readtable:error "invalid datum label/ref"))
|
(readtable:empty/default (readtable:error 'datum-label-next
|
||||||
|
"invalid datum label/ref"))
|
||||||
(list readtable:update-list readtable:digits readtable:push-char)
|
(list readtable:update-list readtable:digits readtable:push-char)
|
||||||
(list readtable:update #\=
|
(list readtable:update #\=
|
||||||
(lambda (_ __ acc port)
|
(lambda (_ __ acc port)
|
||||||
|
@ -522,7 +546,7 @@
|
||||||
;; the datum label.
|
;; the datum label.
|
||||||
(if (and (pair? next-value)
|
(if (and (pair? next-value)
|
||||||
(equal? (car next-value) label))
|
(equal? (car next-value) label))
|
||||||
(error "datum label cannot be itself")
|
(error 'datum-label-next "datum label cannot be itself")
|
||||||
(set-cdr! datum-label next-value))
|
(set-cdr! datum-label next-value))
|
||||||
next-value)))))
|
next-value)))))
|
||||||
(list readtable:update #\#
|
(list readtable:update #\#
|
||||||
|
@ -530,7 +554,8 @@
|
||||||
(let ((label (list->string (acc 'to-list))))
|
(let ((label (list->string (acc 'to-list))))
|
||||||
(let ((datum-label (port 'get-datum-label label)))
|
(let ((datum-label (port 'get-datum-label label)))
|
||||||
(if (null? datum-label)
|
(if (null? datum-label)
|
||||||
(error "unknown reference to datum label" label)
|
(error 'datum-label-next
|
||||||
|
"unknown reference to datum label" label)
|
||||||
(map:val datum-label))))))))
|
(map:val datum-label))))))))
|
||||||
|
|
||||||
;;; Reads the next toplevel datum, discards it, and then continues at the
|
;;; Reads the next toplevel datum, discards it, and then continues at the
|
||||||
|
@ -546,7 +571,7 @@
|
||||||
|
|
||||||
(define readtable:hash
|
(define readtable:hash
|
||||||
(readtable:process
|
(readtable:process
|
||||||
(readtable:empty/default (readtable:error "unimplemented"))
|
(readtable:empty/default (readtable:error 'hash "unimplemented"))
|
||||||
(list readtable:update #\| (readtable:jump/next readtable:block-comment))
|
(list readtable:update #\| (readtable:jump/next readtable:block-comment))
|
||||||
(list readtable:update #\; readtable:datum-comment)
|
(list readtable:update #\; readtable:datum-comment)
|
||||||
(list readtable:update-list readtable:digits ; Datum labels
|
(list readtable:update-list readtable:digits ; Datum labels
|
||||||
|
@ -571,7 +596,7 @@
|
||||||
readtable:skip)
|
readtable:skip)
|
||||||
(list readtable:update #f (readtable:return 'eof))
|
(list readtable:update #f (readtable:return 'eof))
|
||||||
(list readtable:update %bol readtable:read-list)
|
(list readtable:update %bol readtable:read-list)
|
||||||
(list readtable:update %eol (readtable:error "unbalanced list"))
|
(list readtable:update %eol (readtable:error 'top "unbalanced list"))
|
||||||
(list readtable:update #\# (readtable:next/old-as-acc
|
(list readtable:update #\# (readtable:next/old-as-acc
|
||||||
readtable:hash))
|
readtable:hash))
|
||||||
(list readtable:update #\;
|
(list readtable:update #\;
|
||||||
|
@ -605,6 +630,11 @@
|
||||||
(if (not (null? (intset:in used-counters cur-cntr)))
|
(if (not (null? (intset:in used-counters cur-cntr)))
|
||||||
(list 'def cur-cntr '= returned)
|
(list 'def cur-cntr '= returned)
|
||||||
returned)))))))
|
returned)))))))
|
||||||
|
((procedure? value)
|
||||||
|
(let ((type (value 'type)))
|
||||||
|
(cond
|
||||||
|
((eq? type 'ident) (value 'value))
|
||||||
|
(else (vector 'unrepresentable type)))))
|
||||||
(else value)))))
|
(else value)))))
|
||||||
(uncycle value)))))
|
(uncycle value)))))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue