Improved #%app support for ddd
This commit is contained in:
parent
a08c491baa
commit
a46326c300
|
@ -27,7 +27,7 @@
|
||||||
-v
|
-v
|
||||||
(-nest* before
|
(-nest* before
|
||||||
after
|
after
|
||||||
(datum->syntax before `(,@(syntax->list before) ,-v . ,after))
|
#`(#,@(syntax->list before) #,-v . #,after)
|
||||||
(stx-cdr -ooo*)
|
(stx-cdr -ooo*)
|
||||||
(add1 depth))))
|
(add1 depth))))
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@
|
||||||
(define-syntax-class ooo
|
(define-syntax-class ooo
|
||||||
(pattern {~and ooo {~literal …}}))
|
(pattern {~and ooo {~literal …}}))
|
||||||
|
|
||||||
(define-splicing-syntax-class ooo*
|
(define-splicing-syntax-class ooo+
|
||||||
#:attributes (ooo*)
|
#:attributes (ooo*)
|
||||||
(pattern {~seq {~and ooo {~literal …}} …+}
|
(pattern {~seq {~and ooo {~literal …}} …+}
|
||||||
#:with ooo* #'(ooo …)))
|
#:with ooo* #'(ooo …)))
|
||||||
|
@ -68,15 +68,15 @@
|
||||||
|
|
||||||
(define-splicing-syntax-class stmt
|
(define-splicing-syntax-class stmt
|
||||||
#:literals (define define/with-syntax)
|
#:literals (define define/with-syntax)
|
||||||
(pattern {~seq (define name:id e:expr) :ooo*}
|
(pattern {~seq (define name:id e:expr) :ooo+}
|
||||||
#:with expanded
|
#:with expanded
|
||||||
#`(-define name
|
#`(-define name
|
||||||
#,(nest* (ddd %) e ooo*)))
|
#,(nest* (ddd %) e ooo*)))
|
||||||
(pattern {~seq (define/with-syntax pat e:expr) :ooo*}
|
(pattern {~seq (define/with-syntax pat e:expr) :ooo+}
|
||||||
#:with expanded
|
#:with expanded
|
||||||
#`(-define/with-syntax #,(nest* (% …) pat ooo*)
|
#`(-define/with-syntax #,(nest* (% …) pat ooo*)
|
||||||
#,(nest* (ddd %) e ooo*)))
|
#,(nest* (ddd %) e ooo*)))
|
||||||
(pattern {~seq e:not-macro-expr :ooo*}
|
(pattern {~seq e :ooo+}
|
||||||
;#:with expanded #`(apply values #,(ddd* e ooo*))
|
;#:with expanded #`(apply values #,(ddd* e ooo*))
|
||||||
#:with expanded (ddd* e ooo*))
|
#:with expanded (ddd* e ooo*))
|
||||||
(pattern other
|
(pattern other
|
||||||
|
@ -90,7 +90,7 @@
|
||||||
|
|
||||||
(begin-for-syntax
|
(begin-for-syntax
|
||||||
(define-splicing-syntax-class arg
|
(define-splicing-syntax-class arg
|
||||||
(pattern {~seq e:expr ooo*:ooo*}
|
(pattern {~seq e:expr ooo*:ooo+}
|
||||||
#:with expanded (ddd* e ooo*))
|
#:with expanded (ddd* e ooo*))
|
||||||
(pattern other
|
(pattern other
|
||||||
#:with expanded #'(#%app list other))))
|
#:with expanded #'(#%app list other))))
|
||||||
|
|
18
ddd.rkt
18
ddd.rkt
|
@ -81,6 +81,16 @@
|
||||||
(quote-syntax #,(x-pvar-present-marker #'present-variables))
|
(quote-syntax #,(x-pvar-present-marker #'present-variables))
|
||||||
body))
|
body))
|
||||||
|
|
||||||
|
(define (map#f* f l*)
|
||||||
|
(cond [(andmap (λ (l) (eq? l #f)) l*)
|
||||||
|
'(#f)]
|
||||||
|
[(andmap (or/c null? #f) l*)
|
||||||
|
'()]
|
||||||
|
[else (let ([cars (map (λ (l) (if l (car l) #f)) l*)]
|
||||||
|
[cdrs (map (λ (l) (if l (cdr l) #f)) l*)])
|
||||||
|
(cons (apply f cars)
|
||||||
|
(map#f* f cdrs)))]))
|
||||||
|
|
||||||
(define-syntax/case (ddd body) ()
|
(define-syntax/case (ddd body) ()
|
||||||
(define/with-syntax (pvar …)
|
(define/with-syntax (pvar …)
|
||||||
(remove-duplicates
|
(remove-duplicates
|
||||||
|
@ -96,7 +106,7 @@
|
||||||
(define-temp-ids "~aᵢ" (pvar …))
|
(define-temp-ids "~aᵢ" (pvar …))
|
||||||
(define/with-syntax f
|
(define/with-syntax f
|
||||||
#`(#%plain-lambda (pvarᵢ …)
|
#`(#%plain-lambda (pvarᵢ …)
|
||||||
(shadow pvar pvarᵢ) …
|
(shadow pvar pvarᵢ) … ;; TODO: find a way to make the variable marked as "missing" if it is #f ? So that it triggers an error if used outside of ??
|
||||||
(let-values ()
|
(let-values ()
|
||||||
(detect-present-pvars (pvar …)
|
(detect-present-pvars (pvar …)
|
||||||
body))))
|
body))))
|
||||||
|
@ -150,10 +160,10 @@
|
||||||
[(list #f pv pvᵢ #f _) #'#f])
|
[(list #f pv pvᵢ #f _) #'#f])
|
||||||
present?+pvars)))
|
present?+pvars)))
|
||||||
|
|
||||||
#'(map (λ (iterated-pvarᵢ …)
|
#'(map#f* (λ (iterated-pvarᵢ …)
|
||||||
(expanded-f filling-pvar …))
|
(expanded-f filling-pvar …))
|
||||||
(attribute* iterated-pvar)
|
(list (attribute* iterated-pvar)
|
||||||
…))
|
…)))
|
||||||
|
|
||||||
(define-syntax/case (shadow pvar new-value) ()
|
(define-syntax/case (shadow pvar new-value) ()
|
||||||
(match (attribute-info #'pvar '(pvar attr))
|
(match (attribute-info #'pvar '(pvar attr))
|
||||||
|
|
|
@ -174,7 +174,6 @@
|
||||||
x … …])
|
x … …])
|
||||||
'(1 2 3 4 5 6))
|
'(1 2 3 4 5 6))
|
||||||
|
|
||||||
#|
|
|
||||||
;; TODO: expr … inside begin and let
|
;; TODO: expr … inside begin and let
|
||||||
(check-equal? (syntax-case #'((1 2 3) (4 5)) ()
|
(check-equal? (syntax-case #'((1 2 3) (4 5)) ()
|
||||||
[((x …) …)
|
[((x …) …)
|
||||||
|
@ -182,7 +181,65 @@
|
||||||
(list (length (syntax->list #'(x …)))
|
(list (length (syntax->list #'(x …)))
|
||||||
(+ (syntax-e #'x) 3) …)
|
(+ (syntax-e #'x) 3) …)
|
||||||
…)])
|
…)])
|
||||||
'([3 (4 5 6)]
|
'([3 4 5 6]
|
||||||
[2 (7 8)]))
|
[2 7 8]))
|
||||||
|#
|
|
||||||
|
|
||||||
|
(check-equal? (syntax-parse #'([1 2 3] [4 5 6])
|
||||||
|
[([x …] …)
|
||||||
|
x … …])
|
||||||
|
'(1 2 3 4 5 6))
|
||||||
|
(check-equal? (syntax-parse #'([1 2 3] [4 5 6])
|
||||||
|
[([x …] …)
|
||||||
|
(x …) …])
|
||||||
|
'((1 2 3) (4 5 6)))
|
||||||
|
(check-equal? (syntax-parse #'([1 2 3] [4 5 6])
|
||||||
|
[([x …] …)
|
||||||
|
((list x) …) …])
|
||||||
|
'(((1) (2) (3)) ((4) (5) (6))))
|
||||||
|
(check-equal? (syntax-parse #'([1 2 3] [4 5 6])
|
||||||
|
[([x …] …)
|
||||||
|
((+ x 10) …) …])
|
||||||
|
'((11 12 13) (14 15 16)))
|
||||||
|
(check-equal? (syntax-parse #'([1 2 3] [4 5 6])
|
||||||
|
[([x …] …)
|
||||||
|
(begin ((+ x 10) …) …)])
|
||||||
|
'((11 12 13) (14 15 16)))
|
||||||
|
(check-equal? (syntax-parse #'([1 2 3] [4 5 6])
|
||||||
|
[([x …] …)
|
||||||
|
(define/with-syntax y (+ x 10)) … …
|
||||||
|
y … …])
|
||||||
|
'(11 12 13 14 15 16))
|
||||||
|
|
||||||
|
;; Implicit apply with (+ y … …)
|
||||||
|
(check-equal? (syntax-parse #'([1 2 3] [4 5 6])
|
||||||
|
[([x …] …)
|
||||||
|
(define/with-syntax y (+ x 10)) … …
|
||||||
|
(+ y … …)])
|
||||||
|
81)
|
||||||
|
|
||||||
|
;; Implicit apply with (+ (* x 2) … …)
|
||||||
|
(check-equal? (syntax-parse #'([1 2 3] [4 5 6])
|
||||||
|
[([x …] …)
|
||||||
|
(+ (* x 2) … …)])
|
||||||
|
42)
|
||||||
|
|
||||||
|
;; TODO: (define ) … … should register the variable with current-pvars.
|
||||||
|
#;(syntax-parse #'([1 2 3] [4 5 6])
|
||||||
|
[([x …] …)
|
||||||
|
(define y (+ x 10)) … …
|
||||||
|
y … …])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#lang racket
|
||||||
|
|
||||||
|
(require subtemplate/ddd-forms
|
||||||
|
stxparse-info/case
|
||||||
|
stxparse-info/parse
|
||||||
|
rackunit
|
||||||
|
syntax/macro-testing
|
||||||
|
phc-toolkit/untyped)
|
||||||
|
|
||||||
|
(syntax-parse #'([1 2 3] #:kw [4 5 6])
|
||||||
|
[({~and {~or [x …] #:kw}} …)
|
||||||
|
((x …) …)])
|
Loading…
Reference in New Issue
Block a user