From 361b184bee7d647f26075e47697b746d460ee01d Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Thu, 20 Feb 2014 20:32:51 -0800 Subject: [PATCH] changed to be tail-recursive --- top.rkt | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/top.rkt b/top.rkt index b640464..d5faa5b 100644 --- a/top.rkt +++ b/top.rkt @@ -15,25 +15,26 @@ ;; @foo['shape: "square" 'color: "red"]{hello} (define-syntax-rule (top~ . id) (λ x - (define attrs null) - (define elements - (let chomp ([x x]) + (define reversed-pieces ; list of attribute pairs, and last element holds a list of everything else, then reversed + (reverse (let chomp ([x x]) (define result+regexp (and ((length x) . >= . 2) - (symbol? (car x)) - ;; accept strings only - ;; 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. - (or (string? (cadr x))) - ;; Looking for symbol ending with a colon - (regexp-match #rx"^(.*?):(.*)$" (symbol->string (car x))))) + (symbol? (car x)) + ;; accept strings only + ;; 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. + (or (string? (cadr x))) + ;; Looking for symbol ending with a colon + (regexp-match #rx"^(.*?):$" (symbol->string (car x))))) (if result+regexp - (begin - ; reuse result value cadr is first group in match. - (set! attrs (cons (list (string->symbol (cadr result+regexp))(cadr x)) attrs)) - (chomp (cddr x))) - x))) + ; reuse result value. cadr is first group in match. + (cons (list (string->symbol (cadr result+regexp))(cadr x)) (chomp (cddr x))) + (list 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)