253 lines
8.5 KiB
Racket
253 lines
8.5 KiB
Racket
#lang racket
|
|
|
|
(require subtemplate/private/ddd-forms
|
|
stxparse-info/case
|
|
stxparse-info/parse
|
|
rackunit
|
|
syntax/macro-testing
|
|
phc-toolkit/untyped)
|
|
|
|
;; case, let + begin, define
|
|
(check-equal? (syntax-case #'((1 2 3) (4 5)) ()
|
|
[((x …) …)
|
|
(let ()
|
|
(begin
|
|
(define y (- (syntax-e #'x))) … …
|
|
y))])
|
|
'((-1 -2 -3) (-4 -5)))
|
|
|
|
;; case, let + begin, define/with-syntax
|
|
(check-equal? (syntax->datum
|
|
(syntax-case #'((1 2 3) (4 5)) ()
|
|
[((x …) …)
|
|
(let ()
|
|
(begin
|
|
(define/with-syntax y (- (syntax-e #'x))) … …
|
|
#'((y …) …)))]))
|
|
'((-1 -2 -3) (-4 -5)))
|
|
|
|
;; case, let, define
|
|
(check-equal? (syntax-case #'((1 2 3) (4 5)) ()
|
|
[((x …) …)
|
|
(let ()
|
|
(define y (- (syntax-e #'x))) … …
|
|
y)])
|
|
'((-1 -2 -3) (-4 -5)))
|
|
|
|
;; case, let, define/with-syntax
|
|
(check-equal? (syntax->datum
|
|
(syntax-case #'((1 2 3) (4 5)) ()
|
|
[((x …) …)
|
|
(let ()
|
|
(define/with-syntax y (- (syntax-e #'x))) … …
|
|
#'((y …) …))]))
|
|
'((-1 -2 -3) (-4 -5)))
|
|
|
|
;; parse, let + begin, define
|
|
(check-equal? (syntax-parse #'((1 2 3) (4 5))
|
|
[((x …) …)
|
|
(let ()
|
|
(begin
|
|
(define y (- (syntax-e #'x))) … …
|
|
y))])
|
|
'((-1 -2 -3) (-4 -5)))
|
|
|
|
;; parse, let + begin, define/with-syntax
|
|
(check-equal? (syntax->datum
|
|
(syntax-parse #'((1 2 3) (4 5))
|
|
[((x …) …)
|
|
(let ()
|
|
(begin
|
|
(define/with-syntax y (- (syntax-e #'x))) … …
|
|
#'((y …) …)))]))
|
|
'((-1 -2 -3) (-4 -5)))
|
|
|
|
;; parse, let, define
|
|
(check-equal? (syntax-parse #'((1 2 3) (4 5))
|
|
[((x …) …)
|
|
(let ()
|
|
(define y (- (syntax-e #'x))) … …
|
|
y)])
|
|
'((-1 -2 -3) (-4 -5)))
|
|
|
|
;; parse, let, define/with-syntax
|
|
(check-equal? (syntax->datum
|
|
(syntax-parse #'((1 2 3) (4 5))
|
|
[((x …) …)
|
|
(let ()
|
|
(define/with-syntax y (- (syntax-e #'x))) … …
|
|
#'((y …) …))]))
|
|
'((-1 -2 -3) (-4 -5)))
|
|
|
|
;; parse, begin, define
|
|
(check-equal? (syntax-parse #'((1 2 3) (4 5))
|
|
[((x …) …)
|
|
(begin
|
|
(define y (- (syntax-e #'x))) … …)
|
|
y])
|
|
'((-1 -2 -3) (-4 -5)))
|
|
|
|
;; parse, begin, define/with-syntax
|
|
(check-equal? (syntax->datum
|
|
(syntax-parse #'((1 2 3) (4 5))
|
|
[((x …) …)
|
|
(begin
|
|
(define/with-syntax y (- (syntax-e #'x))) … …)
|
|
#'((y …) …)]))
|
|
'((-1 -2 -3) (-4 -5)))
|
|
|
|
;; parse, directly in the body, define
|
|
(check-equal? (syntax-parse #'((1 2 3) (4 5))
|
|
[((x …) …)
|
|
(define y (- (syntax-e #'x))) … …
|
|
y])
|
|
'((-1 -2 -3) (-4 -5)))
|
|
|
|
;; parse, directly in the body, define/with-syntax
|
|
(check-equal? (syntax->datum
|
|
(syntax-parse #'((1 2 3) (4 5))
|
|
[((x …) …)
|
|
(define/with-syntax y (- (syntax-e #'x))) … …
|
|
#'((y …) …)]))
|
|
'((-1 -2 -3) (-4 -5)))
|
|
|
|
;; #%app
|
|
(check-equal? (syntax-case #'([1 2 3] [a]) ()
|
|
[([x …] [y …])
|
|
(vector (syntax-e #'x) … 'then (syntax-e #'y) …)])
|
|
#(1 2 3 then a))
|
|
|
|
;; #%app, depth 2 → flat
|
|
(check-equal? (syntax-case #'(([1 2 3] [4 5 6]) [a]) ()
|
|
[(([x …] …) [y …])
|
|
(vector (syntax-e #'x) … … 'then (syntax-e #'y) …)])
|
|
#(1 2 3 4 5 6 then a))
|
|
|
|
;; #%app, depth 2 → nested
|
|
(check-equal? (syntax-case #'(([1 2 3] [4 5 6]) [a]) ()
|
|
[(([x …] …) [y …])
|
|
(vector ((syntax-e #'x) …) … 'then (syntax-e #'y) …)])
|
|
#((1 2 3) (4 5 6) then a))
|
|
|
|
;; #%app, with auto-syntax-e behaviour :)
|
|
(check-equal? (syntax-case #'([1 2 3] [a]) ()
|
|
[([x …] [y …])
|
|
(vector x … 'then y …)])
|
|
#(1 2 3 then a))
|
|
|
|
;; #%app, with auto-syntax-e behaviour, same variable iterated twice
|
|
(check-equal? (syntax-case #'([1 2 3] [a]) ()
|
|
[([x …] [y …])
|
|
(vector x … 'then x …)])
|
|
#(1 2 3 then 1 2 3))
|
|
|
|
;; #%app, depth 2 → flat, with auto-syntax-e behaviour :)
|
|
(check-equal? (syntax-case #'(([1 2 3] [4 5 6]) [a]) ()
|
|
[(([x …] …) [y …])
|
|
(vector x … … 'then y …)])
|
|
#(1 2 3 4 5 6 then a))
|
|
|
|
;; #%app, depth 2 → nested, with auto-syntax-e behaviour :)
|
|
(check-equal? (syntax-case #'(([1 2 3] [4 5 6]) [a]) ()
|
|
[(([x …] …) [y …])
|
|
(vector (x …) … 'then y …)])
|
|
#((1 2 3) (4 5 6) then a))
|
|
|
|
(check-equal? (syntax-parse #'(([1 2 3] [4 5 6]) [a])
|
|
[(([x …] …) [y …])
|
|
(vector (x … …) 'then y …)])
|
|
#((1 2 3 4 5 6) then a))
|
|
|
|
(check-equal? (syntax-parse #'(([1 2 3] [4 5 6]) [a])
|
|
[(([x …] …) [y …])
|
|
(y …)])
|
|
'(a))
|
|
|
|
(check-equal? (syntax-parse #'(([1 2 3] [4 5 6]) [a])
|
|
[(([x …] …) [y …])
|
|
(x … …)])
|
|
'(1 2 3 4 5 6))
|
|
|
|
;; Implicit (list _), could also be changed to an implicit (values).
|
|
(check-equal? (list ;; unwrap the splice
|
|
(syntax-parse #'(([1 2 3] [4 5 6]) [a])
|
|
[(([x …] …) [y …])
|
|
x … …]))
|
|
'(1 2 3 4 5 6))
|
|
|
|
;; TODO: expr … inside begin and let
|
|
(check-equal? (list ;; unwrap the splice
|
|
(syntax-case #'((1 2 3) (4 5)) ()
|
|
[((x …) …)
|
|
(let ()
|
|
(list (length (syntax->list #'(x …)))
|
|
(+ (syntax-e #'x) 3) …)
|
|
…)]))
|
|
'([3 4 5 6]
|
|
[2 7 8]))
|
|
|
|
(check-equal? (list ;; unwrap the splice
|
|
(syntax-parse #'([1 2 3] [4 5 6])
|
|
[([x …] …)
|
|
x … …]))
|
|
'(1 2 3 4 5 6))
|
|
(check-equal? (list ;; unwrap the splice
|
|
(syntax-parse #'([1 2 3] [4 5 6])
|
|
[([x …] …)
|
|
(x …) …]))
|
|
'((1 2 3) (4 5 6)))
|
|
(check-equal? (list ;; unwrap the splice
|
|
(syntax-parse #'([1 2 3] [4 5 6])
|
|
[([x …] …)
|
|
((list x) …) …]))
|
|
'(((1) (2) (3)) ((4) (5) (6))))
|
|
(check-equal? (list ;; unwrap the splice
|
|
(syntax-parse #'([1 2 3] [4 5 6])
|
|
[([x …] …)
|
|
((+ x 10) …) …]))
|
|
'((11 12 13) (14 15 16)))
|
|
(check-equal? (list ;; unwrap the splice
|
|
(syntax-parse #'([1 2 3] [4 5 6])
|
|
[([x …] …)
|
|
(begin ((+ x 10) …) …)]))
|
|
'((11 12 13) (14 15 16)))
|
|
(check-equal? (list ;; unwrap the splice
|
|
(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 … …])
|
|
|
|
|
|
;; omitted element in the tree = not ok under ellipses
|
|
(check-exn
|
|
#rx"attribute contains an omitted element"
|
|
(λ ()
|
|
(syntax-parse #'([1 2 3] #:kw [4 5 6])
|
|
[({~and {~or [x …] #:kw}} …)
|
|
((x …) …)])))
|
|
|
|
;; omitted element in the tree = ok as auto-syntax-e
|
|
(check-equal? (syntax-parse #'([1 2 3] #:kw [4 5 6])
|
|
[({~and {~or [x …] #:kw}} …)
|
|
(x …)])
|
|
'((1 2 3) #f (4 5 6))) |