-(include "loop.scm")
-(declare (unit lexer)
- (uses parse-utils)
- (uses buf))
+(declare (unit lexer) (uses parse-utils))
(define (dlang/lexer input)
(buf (buf input read-char) dlang/tokenize))
tok))
(define (dlang/whitespace in)
- (while (char-whitespace? (buf-lookahead! in 1))
- (buf-consume! in))
+ (consume-all in dlang/whitespace?)
(dlang/tokenize in))
+(define (dlang/whitespace? in)
+ (char-whitespace? (buf-lookahead! in 1)))
+
(define (dlang/comment in)
(char-match in #\#)
- (while (and (not (char=? (buf-lookahead! in 1) #\newline))
- (not (eof-object? (buf-lookahead! in 1))))
- (buf-consume! in))
+ (consume-all in dlang/comment?)
(dlang/tokenize in))
+(define (dlang/comment? in)
+ (and (not (char=? (buf-lookahead! in 1) #\newline))
+ (not (eof-object? (buf-lookahead! in 1)))))
+
(define (dlang/number in)
(token 'number
(string-append
(dlang/exponent in) ""))))
(define (dlang/integer in)
- (define text "")
(if (and
(not (eof-object? (buf-lookahead! in 1)))
(char-numeric? (buf-lookahead! in 1)))
- (while (char-numeric? (buf-lookahead! in 1))
- (set! text (string-append text (string (buf-consume! in)))))
- (abort "Expected an integer"))
- text)
+ (collect-char in dlang/integer? "")
+ (abort "Expected an integer")))
+
+(define (dlang/integer? in)
+ (char-numeric? (buf-lookahead! in 1)))
(define (dlang/decimal in)
(string-append
(define (dlang/exponent in)
(string-append
- ;(string (char-match-one-of in "eE"))
(string
(if (char=? (buf-lookahead! in 1) #\e)
(char-match in #\e) (char-match in #\E)))
(string (char-match in #\')) )))
(define (dlang/string in)
- (define text (string (char-match in #\")))
- (while (dlang/string-char? in)
- (set! text (string-append text (string (buf-consume! in)))))
- (set! text (string-append text (string (char-match in #\"))))
+ (define text
+ (string-append
+ (string (char-match in #\"))
+ (collect-char in dlang/string-char? "")
+ (string (char-match in #\"))))
(token 'string text))
(define (dlang/string-char? in)
(token-text (dlang/id in)))))
(define (dlang/id in)
- (define acc "")
- (while (dlang/id-char? in)
- (set! acc (string-append acc (string (buf-consume! in)))))
- (if (> (string-length acc) 0)
- (token 'id acc)
+ (define str(collect-char in dlang/id-char? ""))
+ (if (> (string-length str) 0)
+ (token 'id str)
(abort "An Id was expected but none found.")))
(define (dlang/id-char? in)
(lambda () (apply fn (append (list buf) args)))))))
(buf-release! buf)
(not (null? result)))
+
+(define (collect-char in fn str)
+ (if (fn in)
+ (collect-char in fn (string-append str (string (buf-consume! in))))
+ str))
+
+(define (consume-all in fn)
+ (when (fn in)
+ (buf-consume! in)
+ (consume-all in fn)))
+
+(define (collect in fn rulefn lst)
+ (if (fn in)
+ (collect in fn rulefn (append lst (list (rulefn in))))
+ lst))
-(include "loop.scm")
-(declare (unit parser)
- (uses buf))
+(declare (unit parser) (uses buf))
;------------------------------------------------------------------------------
; Formal EBNF Syntax:
;------------------------------------------------------------------------------
(define (dlang/program in)
- (define result '())
- (while (not (eof-object? (buf-lookahead! in 1)))
- (set! result (append result (list (dlang/expression in)))))
- result)
+ (collect in dlang/has-expression? dlang/expression '()))
+
+(define (dlang/has-expression? in)
+ (not (eof-object? (buf-lookahead! in 1))))
(define (dlang/expression in)
(if (dlang/core-form? in)
(define (dlang/arg-list in)
(define tree (syntree 'arglist "" '()))
- (define chldrn '())
(token-match in 'lpar)
- (if (not (token-matches? in 'rpar))
- (begin
- (set! chldrn
- (append chldrn (list (dlang/expression in))))
- (while (not (token-matches? in 'rpar))
- (token-match in 'comma)
- (set! chldrn
- (append chldrn (list (dlang/expression in)))))))
+ (syntree-children-set! tree
+ (collect in dlang/list-end? dlang/arg-list-item '()))
(token-match in 'rpar)
- (syntree-children-set! tree chldrn)
tree)
+(define (dlang/arg-list-item in)
+ (define itm (dlang/expression in))
+ (if (dlang/list-end? in) (token-match in 'comma))
+ itm)
+
(define (dlang/arg-list? in)
(test-apply dlang/arg-list in))
(define (dlang/id-list in)
(define tree (syntree 'args "" '()))
- (define chldrn '())
(token-match in 'lpar)
- (if (not (token-matches? in 'rpar))
- (begin
- (set! chldrn
- (append chldrn (list (token->syntree (token-match in 'id)))))
- (while (not (token-matches? in 'rpar))
- (token-match in 'comma)
- (set! chldrn
- (append chldrn (list (token->syntree (token-match in 'id))))))))
+ (syntree-children-set! tree
+ (collect in dlang/list-end? dlang/id-list-item '()))
(token-match in 'rpar)
- (syntree-children-set! tree chldrn)
tree)
+(define (dlang/id-list-item in)
+ (define itm (token->syntree (token-match in 'id)))
+ (if (dlang/list-end? in) (token-match in 'comma))
+ itm)
+
+(define (dlang/list-end? in)
+ (not (token-matches? in 'rpar)))
+
(define (dlang/expr-block in term)
- (define tree (syntree 'block "" '()))
- (define chldrn '())
- (while (not (token-matches? in term))
- (set! chldrn (append chldrn (list (dlang/expression in)))))
- (syntree-children-set! tree chldrn)
- tree)
+ (syntree 'block ""
+ (collect
+ in
+ (lambda (buf) (not (token-matches? buf term)))
+ dlang/expression
+ '() )))