implemented read-delimited-list to be used for reading attributes one-by-one
svn: r6703
This commit is contained in:
parent
513726af9e
commit
94c820de78
|
@ -1,13 +1,18 @@
|
|||
;; temporary copy of the scribble reader, so that we can experiment
|
||||
;; without having to modify the main PLT tree
|
||||
|
||||
;; ============================================================================
|
||||
;; Implements the @-reader macro for embedding text in Scheme code.
|
||||
|
||||
(module reader mzscheme
|
||||
(require (lib "string.ss") (lib "kw.ss") (lib "readerr.ss" "syntax"))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; customization
|
||||
|
||||
(provide read-insert-indents)
|
||||
(define read-insert-indents (make-parameter #t))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; syntax
|
||||
|
||||
(define cmd-char #\@)
|
||||
|
||||
(define bars-quoted #rx#"^[ \t\r\n]*\\|([^|]*)\\|")
|
||||
|
@ -18,6 +23,7 @@
|
|||
(define open-lines-special ; a special ending expected: @foo{<{ ... }>} etc
|
||||
#rx#"^[ \t\r\n]*([|][^a-zA-Z0-9 \t\r\n@\\]*?[{])(?:[ \t]*\r?\n[ \t]*)?")
|
||||
(define open-attr/lines #rx#"^[ \t\r\n]*[[{][ \t\r\n]*")
|
||||
(define close-attrs #rx#"^[]]")
|
||||
(define close-lines #rx#"^(?:[ \t]*\r?\n[ \t]*)?[}]") ; swallow 1 newline
|
||||
(define close-lines* '(#"^(?:[ \t]*\r?\n[ \t]*)?" #""))
|
||||
(define comment-start #rx#"^[ \t]*;")
|
||||
|
@ -34,6 +40,9 @@
|
|||
(map (lambda (b) (cons (bytes-ref b 0) (bytes-ref b 1)))
|
||||
'(#"()" #"[]" #"{}" #"<>")))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; utilities
|
||||
|
||||
(define make-spaces
|
||||
(let ([t (make-hash-table)])
|
||||
(lambda (n)
|
||||
|
@ -67,7 +76,7 @@
|
|||
plain-spaces)])
|
||||
(hash-table-put! plain-readtables rt #t)
|
||||
rt))))
|
||||
(lambda/kw (#:optional [port (current-input-port)])
|
||||
(lambda (port)
|
||||
(let* ([rt (current-readtable)] [plain? (plain-readtable? rt)])
|
||||
(let loop ()
|
||||
(when plain? (skip-plain-spaces port))
|
||||
|
@ -93,16 +102,33 @@
|
|||
(datum->syntax-object #f d (placeholder-loc sp))
|
||||
(datum->syntax-object sp d sp)))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; main reader function for @ constructs
|
||||
|
||||
(define ((dispatcher start-inside?)
|
||||
char inp source-name line-num col-num position)
|
||||
|
||||
(define (read-error msg . xs)
|
||||
(let-values ([(line col pos) (port-next-location inp)])
|
||||
(raise-read-error (apply format msg xs) source-name line col pos #f)))
|
||||
|
||||
(define (cur-pos)
|
||||
(let-values ([(line col pos) (port-next-location inp)])
|
||||
pos))
|
||||
|
||||
(define (span-from start)
|
||||
(and start (- (cur-pos) start)))
|
||||
|
||||
(define (read-delimited-list end-re)
|
||||
(let loop ([r '()])
|
||||
(skip-whitespace inp)
|
||||
(if (regexp-match/fail-without-reading end-re inp)
|
||||
(reverse! r)
|
||||
(let ([x (read-syntax/recursive source-name inp)])
|
||||
(if (eof-object? x)
|
||||
(read-error "expected a ']'")
|
||||
(loop (cons x r)))))))
|
||||
|
||||
(define (read-from-bytes-exact-or-identifier bs)
|
||||
(let ([inp (open-input-bytes bs)]
|
||||
[default (lambda _ (string->symbol (bytes->string/utf-8 bs)))])
|
||||
|
@ -110,6 +136,7 @@
|
|||
(let ([x (read inp)])
|
||||
;; must match all -- otherwise: default
|
||||
(if (regexp-match #rx#"^[ \t\r\n]*$" inp) x (default))))))
|
||||
|
||||
(define (reverse-bytes bytes)
|
||||
(define (rev-byte b)
|
||||
(cond [(assq b byte-pairs) => cdr]
|
||||
|
@ -120,10 +147,13 @@
|
|||
(bytes-set! r i (rev-byte (bytes-ref bytes (- len i 1))))
|
||||
(loop (sub1 i))))
|
||||
r))
|
||||
|
||||
(define eol-token "\n")
|
||||
|
||||
(define (get-attrs)
|
||||
(and (regexp-match-peek-positions open-attrs inp)
|
||||
(syntax->list (read-syntax/recursive source-name inp))))
|
||||
(and (regexp-match/fail-without-reading open-attrs inp)
|
||||
(read-delimited-list close-attrs)))
|
||||
|
||||
(define ((get-line open open-re close close-re item-re unquote-re level))
|
||||
(let-values ([(line col pos) (port-next-location inp)])
|
||||
(define (make-stx sexpr)
|
||||
|
@ -165,6 +195,7 @@
|
|||
[(regexp-match/fail-without-reading #rx#"^$" inp)
|
||||
(if start-inside? #f (read-error "missing `~a'" close))]
|
||||
[else (read-error "internal error [get-line]")])))
|
||||
|
||||
;; adds stx (new syntax) to the list of stxs, merging it if both are
|
||||
;; strings, except for newline markers
|
||||
(define (maybe-merge stx stxs)
|
||||
|
@ -183,6 +214,7 @@
|
|||
(span-from (syntax-position fst))))
|
||||
(cdr stxs)))
|
||||
(cons stx stxs)))
|
||||
|
||||
(define (add-indents stxs)
|
||||
(unless (andmap (lambda (x)
|
||||
(or (and (syntax? x) (syntax-line x) (syntax-column x))
|
||||
|
@ -206,6 +238,7 @@
|
|||
(make-spaces (- stxcol mincol)))
|
||||
r)
|
||||
(cons stx* r))))))))))
|
||||
|
||||
(define (get-lines)
|
||||
(define get
|
||||
(cond [start-inside?
|
||||
|
@ -241,6 +274,7 @@
|
|||
[(special-comment? line) (loop lines more)]
|
||||
[(list? line) (loop lines (append line more))]
|
||||
[else (loop (maybe-merge line lines) more)])))))
|
||||
|
||||
(define (get-rprefixes) ; return punctuation prefixes in reverse
|
||||
(cond
|
||||
[(regexp-match/fail-without-reading
|
||||
|
@ -265,6 +299,7 @@
|
|||
r)))]
|
||||
[else (read-error "internal error [rpfxs]")])))]
|
||||
[else '()]))
|
||||
|
||||
(define (get-command) ; #f means no command
|
||||
(let-values ([(line col pos) (port-next-location inp)])
|
||||
(cond [(regexp-match-peek-positions open-attr/lines inp)
|
||||
|
@ -281,6 +316,7 @@
|
|||
(let ([x (read-syntax/recursive source-name inp)])
|
||||
(if (special-comment? x) (loop) x))))
|
||||
#f)])))
|
||||
|
||||
(cond
|
||||
[start-inside?
|
||||
(datum->syntax-object #f (get-lines)
|
||||
|
@ -311,6 +347,9 @@
|
|||
(list source-name line-num col-num position
|
||||
(span-from position))))]))
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; readtables
|
||||
|
||||
(define at-readtable
|
||||
(make-readtable #f cmd-char 'terminating-macro (dispatcher #f)))
|
||||
|
||||
|
@ -334,9 +373,7 @@
|
|||
|
||||
(define default-src (gensym))
|
||||
(define (src-name src port)
|
||||
(if (eq? src default-src)
|
||||
(object-name port)
|
||||
src))
|
||||
(if (eq? src default-src) (object-name port) src))
|
||||
|
||||
(define/kw (*read #:optional [inp (current-input-port)])
|
||||
(parameterize ([current-readtable at-readtable])
|
||||
|
|
Loading…
Reference in New Issue
Block a user