More ?operations
This commit is contained in:
parent
74f38a3213
commit
e7e60b1da9
|
@ -5,7 +5,11 @@
|
||||||
(rename-out [begin #%intef-begin])
|
(rename-out [begin #%intef-begin])
|
||||||
(rename-out [app #%app])
|
(rename-out [app #%app])
|
||||||
??
|
??
|
||||||
|
?if
|
||||||
|
?cond
|
||||||
|
?attr
|
||||||
?@
|
?@
|
||||||
|
?@@
|
||||||
splice-append
|
splice-append
|
||||||
splice-append*
|
splice-append*
|
||||||
splicing-list?
|
splicing-list?
|
||||||
|
@ -94,8 +98,8 @@
|
||||||
(define-syntax/parse (begin stmt:stmt …)
|
(define-syntax/parse (begin stmt:stmt …)
|
||||||
(template (-begin (?@ stmt.expanded) …)))
|
(template (-begin (?@ stmt.expanded) …)))
|
||||||
|
|
||||||
(define-syntax/parse (let ([var . val] …) . body)
|
(define-syntax/parse (let {~optional name:id} ([var . val] …) . body)
|
||||||
(template (-let ([var (begin . val)] …) (begin . body))))
|
(template (-let (?? name) ([var (begin . val)] …) (begin . body))))
|
||||||
|
|
||||||
(begin-for-syntax
|
(begin-for-syntax
|
||||||
(define-splicing-syntax-class arg
|
(define-splicing-syntax-class arg
|
||||||
|
|
68
ddd.rkt
68
ddd.rkt
|
@ -1,6 +1,7 @@
|
||||||
#lang racket
|
#lang racket
|
||||||
|
|
||||||
(provide ddd ?? ?@ splicing-list splicing-list-l splicing-list?)
|
(provide ddd ?? ?if ?cond ?attr ?@ ?@@
|
||||||
|
splicing-list splicing-list-l splicing-list?)
|
||||||
|
|
||||||
(require stxparse-info/current-pvars
|
(require stxparse-info/current-pvars
|
||||||
phc-toolkit/untyped
|
phc-toolkit/untyped
|
||||||
|
@ -38,8 +39,8 @@
|
||||||
(if (syntax-local-value valvar (λ () #f)) ;; is it a macro-ish thing?
|
(if (syntax-local-value valvar (λ () #f)) ;; is it a macro-ish thing?
|
||||||
(begin
|
(begin
|
||||||
(log-warning
|
(log-warning
|
||||||
(string-append "Could not extract the plain variable corresponding to"
|
(string-append "Could not extract the plain variable corresponding"
|
||||||
" the pattern variable or attribute ~a"
|
" to the pattern variable or attribute ~a"
|
||||||
(syntax-e attr)))
|
(syntax-e attr)))
|
||||||
#f)
|
#f)
|
||||||
valvar)))
|
valvar)))
|
||||||
|
@ -54,7 +55,9 @@
|
||||||
|
|
||||||
(define/with-syntax expanded-body
|
(define/with-syntax expanded-body
|
||||||
(local-expand #`(let-values ()
|
(local-expand #`(let-values ()
|
||||||
(quote-syntax #,(stx-map x-pvar-scope #'(pvar-real-valvar …)) #:local)
|
(quote-syntax #,(stx-map x-pvar-scope
|
||||||
|
#'(pvar-real-valvar …))
|
||||||
|
#:local)
|
||||||
body)
|
body)
|
||||||
'expression
|
'expression
|
||||||
'()))
|
'()))
|
||||||
|
@ -132,20 +135,24 @@
|
||||||
#;(define-syntax-rule (?@ v ...)
|
#;(define-syntax-rule (?@ v ...)
|
||||||
(splicing-list (list v ...)))
|
(splicing-list (list v ...)))
|
||||||
(define (?@ . vs) (splicing-list vs))
|
(define (?@ . vs) (splicing-list vs))
|
||||||
|
(define (?@@ . vs) (map splicing-list vs))
|
||||||
|
|
||||||
(define-syntax (?? stx)
|
(define-for-syntax ((?* mode) stx)
|
||||||
(define (parse stx)
|
(define (parse stx)
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[(self a)
|
[(self condition a)
|
||||||
(parse (datum->syntax stx `(,#'self ,#'a ,#'(?@)) stx stx))]
|
(?* (datum->syntax stx `(,#'self ,#'c ,#'a ,#'(?@)) stx stx))]
|
||||||
[(_ a b)
|
[(_ condition a b)
|
||||||
(let ()
|
(let ()
|
||||||
(define/with-syntax (pvar …) (current-pvars-shadowers))
|
(define/with-syntax (pvar …) (current-pvars-shadowers))
|
||||||
|
|
||||||
(define/with-syntax expanded-a
|
(define/with-syntax expanded-condition
|
||||||
(local-expand #'(detect-present-pvars (pvar …) a) 'expression '()))
|
(local-expand #'(detect-present-pvars (pvar …) condition)
|
||||||
|
'expression
|
||||||
|
'()))
|
||||||
|
|
||||||
(define present-variables (extract-present-variables #'expanded-a stx))
|
(define present-variables
|
||||||
|
(extract-present-variables #'expanded-condition stx))
|
||||||
|
|
||||||
(define/with-syntax (test-present-attribute …)
|
(define/with-syntax (test-present-attribute …)
|
||||||
(for/list ([present? (in-list present-variables)]
|
(for/list ([present? (in-list present-variables)]
|
||||||
|
@ -155,12 +162,45 @@
|
||||||
#:when (eq? 'attr (car (attribute-info pv '(pvar attr)))))
|
#:when (eq? 'attr (car (attribute-info pv '(pvar attr)))))
|
||||||
#`(attribute* #,pv)))
|
#`(attribute* #,pv)))
|
||||||
|
|
||||||
|
#`(if (and test-present-attribute …)
|
||||||
#'(if (and test-present-attribute …)
|
#,(if (eq? mode 'if) #'a #'condition)
|
||||||
a
|
|
||||||
b))]))
|
b))]))
|
||||||
(parse stx))
|
(parse stx))
|
||||||
|
|
||||||
|
(define-syntax ?if (?* 'if))
|
||||||
|
|
||||||
|
(define-syntax (?cond stx)
|
||||||
|
(syntax-case stx (else)
|
||||||
|
[(self) #'(raise-syntax-error '?cond
|
||||||
|
"all branches contain omitted elements"
|
||||||
|
self)]
|
||||||
|
[(self [else]) #'(?@)]
|
||||||
|
[(self [else . v]) #'(begin . v)]
|
||||||
|
[(self [condition v . vs] . rest)
|
||||||
|
(not (free-identifier=? #'condition #'else))
|
||||||
|
(let ([else (datum->syntax stx `(,#'self . ,#'rest) stx stx)])
|
||||||
|
(datum->syntax stx
|
||||||
|
`(,#'?if ,#'condition ,#'(begin v . vs) . ,else)
|
||||||
|
stx
|
||||||
|
stx))]))
|
||||||
|
|
||||||
|
(define-syntax (?attr stx)
|
||||||
|
(syntax-case stx ()
|
||||||
|
[(self condition)
|
||||||
|
(datum->syntax stx `(,#'?if ,#'condition #t #f) stx stx)]))
|
||||||
|
|
||||||
|
(define-syntax (?? stx)
|
||||||
|
(define (parse stx)
|
||||||
|
(syntax-case stx ()
|
||||||
|
[(self a)
|
||||||
|
((?* 'or) (datum->syntax stx `(,#'self ,#'a ,#'a ,#'(?@)) stx stx))]
|
||||||
|
[(self a b)
|
||||||
|
((?* 'or) (datum->syntax stx `(,#'self ,#'a ,#'a ,#'b) stx stx))]
|
||||||
|
[(self a b c . rest)
|
||||||
|
(let ([else (datum->syntax stx `(,#'self ,#'b ,#'c . ,#'rest) stx stx)])
|
||||||
|
(datum->syntax stx `(,#'self ,#'a ,else) stx stx))]))
|
||||||
|
(parse stx))
|
||||||
|
|
||||||
(define-syntax/case (ddd body) ()
|
(define-syntax/case (ddd body) ()
|
||||||
(define/with-syntax (pvar …) (current-pvars-shadowers))
|
(define/with-syntax (pvar …) (current-pvars-shadowers))
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
syntax/macro-testing
|
syntax/macro-testing
|
||||||
phc-toolkit/untyped)
|
phc-toolkit/untyped)
|
||||||
|
|
||||||
;; TODO: allow the overridden ?? and ?@ in template.
|
|
||||||
|
|
||||||
(check-equal? (syntax-parse #'(1 #:kw 3)
|
(check-equal? (syntax-parse #'(1 #:kw 3)
|
||||||
[({~and {~or x:nat #:kw}} …)
|
[({~and {~or x:nat #:kw}} …)
|
||||||
(?? x 'missing) …])
|
(?? x 'missing) …])
|
||||||
|
|
45
test/test-or.rkt
Normal file
45
test/test-or.rkt
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#lang racket
|
||||||
|
|
||||||
|
(require subtemplate/ddd
|
||||||
|
subtemplate/unsyntax-preparse
|
||||||
|
stxparse-info/case
|
||||||
|
stxparse-info/parse
|
||||||
|
rackunit)
|
||||||
|
|
||||||
|
(define (test-??-all v)
|
||||||
|
(syntax->datum
|
||||||
|
(syntax-parse v
|
||||||
|
[({~optional a:nat}
|
||||||
|
{~optional b:id}
|
||||||
|
{~optional c:boolean}
|
||||||
|
{~optional d:keyword})
|
||||||
|
(quasitemplate-ddd (?? a b c d))])))
|
||||||
|
|
||||||
|
(check-equal? (test-??-all #'(1 x #f #:kw)) '1)
|
||||||
|
(check-equal? (test-??-all #'(x #f #:kw)) 'x)
|
||||||
|
(check-equal? (test-??-all #'(#f #:kw)) '#f)
|
||||||
|
(check-equal? (test-??-all #'(#:kw)) '#:kw)
|
||||||
|
|
||||||
|
(check-equal? (test-??-all #'(1)) '1)
|
||||||
|
(check-equal? (test-??-all #'(x)) 'x)
|
||||||
|
(check-equal? (test-??-all #'(#f)) '#f)
|
||||||
|
(check-equal? (test-??-all #'(#:kw)) '#:kw)
|
||||||
|
|
||||||
|
(define (test-?cond v)
|
||||||
|
(syntax->datum
|
||||||
|
(syntax-parse v
|
||||||
|
[({~optional a:nat}
|
||||||
|
{~optional b:id}
|
||||||
|
{~optional c:boolean}
|
||||||
|
{~optional d:keyword})
|
||||||
|
(quasitemplate-ddd (?cond [a 10] [b 20] [c 30] [d 40]))])))
|
||||||
|
|
||||||
|
(check-equal? (test-?cond #'(1 x #f #:kw)) 10)
|
||||||
|
(check-equal? (test-?cond #'(x #f #:kw)) 20)
|
||||||
|
(check-equal? (test-?cond #'(#f #:kw)) 30)
|
||||||
|
(check-equal? (test-?cond #'(#:kw)) 40)
|
||||||
|
|
||||||
|
(check-equal? (test-?cond #'(1)) 10)
|
||||||
|
(check-equal? (test-?cond #'(x)) 20)
|
||||||
|
(check-equal? (test-?cond #'(#f)) 30)
|
||||||
|
(check-equal? (test-?cond #'(#:kw)) 40)
|
|
@ -1,13 +1,12 @@
|
||||||
#lang racket
|
#lang racket
|
||||||
|
|
||||||
(require subtemplate/top-subscripts
|
(require subtemplate/ddd-forms
|
||||||
subtemplate/ddd-forms
|
rackunit)
|
||||||
subtemplate/unsyntax-preparse
|
|
||||||
subtemplate/template-subscripts
|
(check-equal? (let ([l '(4 5 6)])
|
||||||
(except-in subtemplate/override ?? ?@)
|
(vector (?@ 1 2 3 . l)))
|
||||||
stxparse-info/case
|
#(1 2 3 4 5 6))
|
||||||
stxparse-info/parse
|
|
||||||
rackunit
|
(check-equal? (let ([l '(4 5 6)])
|
||||||
syntax/macro-testing
|
(vector (?@ 1 2 3 (?@ . l) 7 8 9)))
|
||||||
phc-toolkit/untyped
|
#(1 2 3 4 5 6 7 8 9))
|
||||||
(only-in racket/base [... …]))
|
|
|
@ -11,6 +11,7 @@
|
||||||
(only-in racket/base [... …])
|
(only-in racket/base [... …])
|
||||||
stxparse-info/parse
|
stxparse-info/parse
|
||||||
stxparse-info/case
|
stxparse-info/case
|
||||||
|
syntax/stx
|
||||||
(for-syntax racket/base
|
(for-syntax racket/base
|
||||||
racket/list
|
racket/list
|
||||||
racket/syntax
|
racket/syntax
|
||||||
|
@ -20,7 +21,7 @@
|
||||||
|
|
||||||
(define-for-syntax lifted (make-parameter #f))
|
(define-for-syntax lifted (make-parameter #f))
|
||||||
|
|
||||||
(define-for-syntax (pre-parse-unsyntax tmpl depth escapes)
|
(define-for-syntax (pre-parse-unsyntax tmpl depth escapes quasi? form)
|
||||||
;; TODO: a nested quasisubtemplate should escape an unsyntax!
|
;; TODO: a nested quasisubtemplate should escape an unsyntax!
|
||||||
(define (ds e)
|
(define (ds e)
|
||||||
;; TODO: should preserve the shape of the original stx
|
;; TODO: should preserve the shape of the original stx
|
||||||
|
@ -28,13 +29,12 @@
|
||||||
(datum->syntax tmpl e tmpl tmpl))
|
(datum->syntax tmpl e tmpl tmpl))
|
||||||
(define-syntax-class ooo
|
(define-syntax-class ooo
|
||||||
(pattern {~and ooo {~literal ...}}))
|
(pattern {~and ooo {~literal ...}}))
|
||||||
(define (recur t) (pre-parse-unsyntax t depth escapes))
|
(define (recur t) (pre-parse-unsyntax t depth escapes quasi? form))
|
||||||
(define (stx-length stx) (length (syntax->list stx)))
|
(define (stx-length stx) (length (syntax->list stx)))
|
||||||
(define (lift! e) (set-box! (lifted) (cons e (unbox (lifted)))))
|
(define (lift! e) (set-box! (lifted) (cons e (unbox (lifted)))))
|
||||||
(syntax-parse tmpl
|
(syntax-parse tmpl
|
||||||
#:literals (unsyntax unsyntax-splicing unquote unquote-splicing
|
#:literals (unsyntax unsyntax-splicing unquote unquote-splicing
|
||||||
quasitemplate ?? ?@)
|
quasitemplate ?? ?if ?cond ?attr ?@ ?@@)
|
||||||
[:id tmpl]
|
|
||||||
[({~and u unsyntax} (unquote e)) ;; full unquote with #,,
|
[({~and u unsyntax} (unquote e)) ;; full unquote with #,,
|
||||||
(ds `(,#'u ,#'e))]
|
(ds `(,#'u ,#'e))]
|
||||||
[({~and u unsyntax-splicing} (unquote e)) ;; full unquote with #,@,
|
[({~and u unsyntax-splicing} (unquote e)) ;; full unquote with #,@,
|
||||||
|
@ -42,59 +42,122 @@
|
||||||
[({~and u unsyntax} (unquote-splicing e)) ;; full unquote with #,,@
|
[({~and u unsyntax} (unquote-splicing e)) ;; full unquote with #,,@
|
||||||
(ds `(,(datum->syntax #'here 'unsyntax-splicing #'u) ,#'e))]
|
(ds `(,(datum->syntax #'here 'unsyntax-splicing #'u) ,#'e))]
|
||||||
[({~and u unsyntax} e)
|
[({~and u unsyntax} e)
|
||||||
#:when (= escapes 0)
|
#:when (and (= escapes 0) quasi?)
|
||||||
(with-syntax ([tmp (generate-temporary #'e)]
|
(with-syntax ([tmp (generate-temporary #'e)]
|
||||||
[ooo* (map (λ (_) (quote-syntax …)) (range depth))])
|
[ooo* (map (λ (_) (quote-syntax …)) (range depth))])
|
||||||
(lift! #`(begin (define/with-syntax tmp (splice-append e)) . ooo*))
|
(lift! #`(begin (define/with-syntax tmp (splice-append e)) . ooo*))
|
||||||
(ds `(,#'stxparse:?@ . ,(datum->syntax #'tmp #'tmp #'e))))]
|
(ds `(,#'stxparse:?@ . ,(datum->syntax #'tmp #'tmp #'e))))]
|
||||||
[({~and u unsyntax-splicing} e)
|
[({~and u unsyntax-splicing} e)
|
||||||
#:when (= escapes 0)
|
#:when (and (= escapes 0) quasi?)
|
||||||
(with-syntax ([tmp (generate-temporary #'e)]
|
(with-syntax ([tmp (generate-temporary #'e)]
|
||||||
[ooo* (map (λ (_) (quote-syntax …)) (range depth))])
|
[ooo* (map (λ (_) (quote-syntax …)) (range depth))])
|
||||||
(lift! #`(begin (define/with-syntax tmp (splice-append* e)) . ooo*))
|
(lift! #`(begin (define/with-syntax tmp (splice-append* e)) . ooo*))
|
||||||
#'(stxparse:?@ . tmp))]
|
#'(stxparse:?@ . tmp))]
|
||||||
[({~and u {~or unsyntax unsyntax-splicing}} e)
|
[({~and u {~or unsyntax unsyntax-splicing}} e)
|
||||||
;; when escapes ≠ 0
|
;; when escapes ≠ 0 (or quasi? is #false)
|
||||||
(ds `(,#'u ,(pre-parse-unsyntax e depth (sub1 escapes))))]
|
(ds `(,#'u ,(pre-parse-unsyntax e depth (sub1 escapes) quasi? form)))]
|
||||||
[(quasitemplate t . opts)
|
[(quasitemplate t . opts)
|
||||||
(ds `(,#'quasitemplate ,(pre-parse-unsyntax #'t depth (add1 escapes))
|
(ds `(,#'quasitemplate
|
||||||
|
,(pre-parse-unsyntax #'t depth (add1 escapes) quasi? form)
|
||||||
. ,#'opts))]
|
. ,#'opts))]
|
||||||
[({~var mf (static template-metafunction? "template metafunction")} . args)
|
[({~and self ?if} condition a b)
|
||||||
(ds `(,#'mf . ,(recur #'args)))]
|
(with-syntax ([tmp (generate-temporary #'self)]
|
||||||
|
[ooo* (map (λ (_) (quote-syntax …)) (range depth))])
|
||||||
|
(lift! #`(begin (define/with-syntax tmp (?if #,(form (recur #'condition))
|
||||||
|
#,(form (recur #'(a)))
|
||||||
|
#,(form (recur #'(b)))))
|
||||||
|
. ooo*))
|
||||||
|
#'(stxparse:?@ . tmp))]
|
||||||
|
[({~and self ?cond} [{~and condition {~not {~literal else}}} . v] . rest)
|
||||||
|
(recur (ds `(,#'?if ,#'condition
|
||||||
|
,(ds `(,#'?@ . ,#'v))
|
||||||
|
,(ds `(,#'self . ,#'rest)))))]
|
||||||
|
[({~and self ?cond} [{~literal else}] . rest)
|
||||||
|
#'(stxparse:?@)]
|
||||||
|
[({~and self ?cond} [{~literal else} . v] . rest)
|
||||||
|
(recur #'(?@ . v))]
|
||||||
|
[({~and self ?@@} . e)
|
||||||
|
(with-syntax ([tmp (generate-temporary #'self)]
|
||||||
|
[ooo* (map (λ (_) (quote-syntax …)) (range depth))])
|
||||||
|
(lift! #`(begin (define/with-syntax tmp
|
||||||
|
(append* (stx-map*syntax->list #,(form #'e))))
|
||||||
|
. ooo*))
|
||||||
|
#'(stxparse:?@ . tmp))]
|
||||||
|
[({~and self ?attr} condition)
|
||||||
|
(recur (ds `(,#'?if ,#'condition
|
||||||
|
#t
|
||||||
|
#f)))]
|
||||||
[(:ooo t)
|
[(:ooo t)
|
||||||
tmpl] ;; fully escaped, do not change
|
tmpl] ;; fully escaped, do not change
|
||||||
[(?? . args)
|
[({~and self ??} a b c . rest)
|
||||||
(ds `(,#'stxparse:?? . ,(recur #'args)))]
|
(ds `(,#'stxparse:?? ,(recur #'a)
|
||||||
|
,(recur (ds `(,#'self ,#'b ,#'c . ,#'rest)))))]
|
||||||
|
[(?? a b)
|
||||||
|
(ds `(,#'stxparse:?? ,(recur #'a) ,(recur #'b)))]
|
||||||
|
[(?? a)
|
||||||
|
(ds `(,#'stxparse:?? ,(recur #'a)))]
|
||||||
[(?@ . args)
|
[(?@ . args)
|
||||||
(ds `(,#'stxparse:?@ . ,(recur #'args)))]
|
(ds `(,#'stxparse:?@ . ,(recur #'args)))]
|
||||||
|
[({~var mf (static template-metafunction? "template metafunction")} . args)
|
||||||
|
(ds `(,#'mf . ,(recur #'args)))]
|
||||||
[(hd :ooo ...+ . tl)
|
[(hd :ooo ...+ . tl)
|
||||||
(ds `(,(pre-parse-unsyntax #'hd (+ depth (stx-length #'(ooo …))) escapes)
|
(ds `(,(pre-parse-unsyntax #'hd
|
||||||
|
(+ depth (stx-length #'(ooo …)))
|
||||||
|
escapes
|
||||||
|
quasi?
|
||||||
|
form)
|
||||||
,@(syntax->list #'(ooo ...))
|
,@(syntax->list #'(ooo ...))
|
||||||
. ,(recur #'tl)))]
|
. ,(recur #'tl)))]
|
||||||
[(hd . tl)
|
[(hd . tl)
|
||||||
(ds `(,(recur #'hd) . ,(recur #'tl)))]
|
(ds `(,(recur #'hd) . ,(recur #'tl)))]
|
||||||
[#(t …)
|
[#(t …)
|
||||||
(ds (list->vector (stx-map recur #'(t …))))]
|
(ds (list->vector (stx-map recur #'(t …))))]
|
||||||
[()
|
;; other ids, empty list, numbers, strings, chars, …
|
||||||
tmpl]))
|
[_ tmpl]))
|
||||||
|
|
||||||
(define-for-syntax ((quasi*template-ddd form) stx)
|
(define (check-single-result result stx form)
|
||||||
|
(unless (and (stx-pair? result) (stx-null? (stx-cdr result)))
|
||||||
|
(raise-syntax-error form
|
||||||
|
(string-append "the outer ?@ in the template produced"
|
||||||
|
" more than one syntax object")
|
||||||
|
stx))
|
||||||
|
(stx-car result))
|
||||||
|
|
||||||
|
(define-for-syntax ((*template-ddd quasi? form) stx)
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[(_ tmpl . opts)
|
[(_ tmpl . opts)
|
||||||
(parameterize ([lifted (box '())])
|
(parameterize ([lifted (box '())])
|
||||||
(let ([new-tmpl (pre-parse-unsyntax #'tmpl 0 0)])
|
(let ([new-tmpl (pre-parse-unsyntax #'tmpl 0 0 quasi?
|
||||||
|
(λ (e) #`(#,form #,e . opts)))])
|
||||||
(if (null? (unbox (lifted)))
|
(if (null? (unbox (lifted)))
|
||||||
(datum->syntax stx
|
(datum->syntax stx
|
||||||
`(,form ,new-tmpl . ,#'opts)
|
`(,form ,new-tmpl . ,#'opts)
|
||||||
stx
|
stx
|
||||||
stx)
|
stx)
|
||||||
|
((λ (~)
|
||||||
|
;(local-require racket/pretty)
|
||||||
|
;(pretty-write (syntax->datum ~))
|
||||||
|
~)
|
||||||
(quasisyntax/top-loc stx
|
(quasisyntax/top-loc stx
|
||||||
(let-values ()
|
(let-values ()
|
||||||
#,@(unbox (lifted))
|
#,@(reverse (unbox (lifted)))
|
||||||
|
(define result
|
||||||
#,(datum->syntax stx
|
#,(datum->syntax stx
|
||||||
`(,form ,new-tmpl . ,#'opts)
|
`(,form (,new-tmpl) . ,#'opts)
|
||||||
stx
|
stx
|
||||||
stx))))))]))
|
stx))
|
||||||
|
(check-single-result result (quote-syntax stx) 'form)))))))]))
|
||||||
|
|
||||||
(define-syntax quasitemplate-ddd (quasi*template-ddd #'quasitemplate))
|
(define-syntax quasitemplate-ddd (*template-ddd #t #'quasitemplate))
|
||||||
(define-syntax quasisubtemplate-ddd (quasi*template-ddd #'quasisubtemplate))
|
(define-syntax quasisubtemplate-ddd (*template-ddd #t #'quasisubtemplate))
|
||||||
|
(define-syntax template-ddd (*template-ddd #t #'template))
|
||||||
|
(define-syntax subtemplate-ddd (*template-ddd #t #'subtemplate))
|
||||||
|
|
||||||
|
(define (stx-map*syntax->list e)
|
||||||
|
(let loop ([l (syntax->list e)])
|
||||||
|
(cond
|
||||||
|
[(null? l) l]
|
||||||
|
[(pair? l) (cons (syntax->list (car l)) (loop (cdr l)))]
|
||||||
|
;; Special treatment for the last element of e: it does not need to
|
||||||
|
;; be a list (as long as ?@ is used in tail position).
|
||||||
|
[else l])))
|
Loading…
Reference in New Issue
Block a user