changed to be tail-recursive

pull/9/head
Matthew Butterick 11 years ago
parent 57a991622e
commit 361b184bee

@ -15,25 +15,26 @@
;; @foo['shape: "square" 'color: "red"]{hello} ;; @foo['shape: "square" 'color: "red"]{hello}
(define-syntax-rule (top~ . id) (define-syntax-rule (top~ . id)
(λ x (λ x
(define attrs null) (define reversed-pieces ; list of attribute pairs, and last element holds a list of everything else, then reversed
(define elements (reverse (let chomp ([x x])
(let chomp ([x x])
(define result+regexp (and ((length x) . >= . 2) (define result+regexp (and ((length x) . >= . 2)
(symbol? (car x)) (symbol? (car x))
;; accept strings only ;; accept strings only
;; numbers are difficult because they don't parse as cleanly. ;; numbers are difficult because they don't parse as cleanly.
;; string will read as a string even if there's no space to the left. ;; string will read as a string even if there's no space to the left.
(or (string? (cadr x))) (or (string? (cadr x)))
;; Looking for symbol ending with a colon ;; Looking for symbol ending with a colon
(regexp-match #rx"^(.*?):(.*)$" (symbol->string (car x))))) (regexp-match #rx"^(.*?):$" (symbol->string (car x)))))
(if result+regexp (if result+regexp
(begin ; reuse result value. cadr is first group in match.
; reuse result value cadr is first group in match. (cons (list (string->symbol (cadr result+regexp))(cadr x)) (chomp (cddr x)))
(set! attrs (cons (list (string->symbol (cadr result+regexp))(cadr x)) attrs)) (list x)))))
(chomp (cddr x)))
x)))
`(id ,@(if (equal? attrs null) null (list (reverse attrs))) ,@elements))) (define-values (body attrs) (if (equal? null reversed-pieces)
(values null null)
(values (car reversed-pieces) (cdr reversed-pieces))))
`(id ,@(if (equal? attrs null) null (list (reverse attrs))) ,@body)))
(define-syntax (bound/c stx) (define-syntax (bound/c stx)

Loading…
Cancel
Save