diff --git a/remix/semi.rkt b/remix/semi.rkt index 20a12fe..abc60d0 100644 --- a/remix/semi.rkt +++ b/remix/semi.rkt @@ -3,15 +3,27 @@ syntax/parse)) (define-syntax (#%semi stx) - (raise-syntax-error '#%semi "illegal outside of block" stx)) + (raise-syntax-error '#%semi "illegal outside of top-level, block, or braces" stx)) (begin-for-syntax + (define-syntax-class not-semi + #:literals (#%semi unquote) + (pattern (~and (~not #%semi) + (~not (unquote #%semi))))) + (define-splicing-syntax-class semi-piece + #:literals (#%semi unquote) + #:attributes (it) + (pattern (~seq #%semi it)) + (pattern (~seq sp:not-semi ... #%semi) + #:attr it #'(sp ...)) + (pattern (~seq sp:not-semi ... (~and uqs (unquote #%semi))) + #:attr it + (with-syntax ([semi-#%braces (datum->syntax #'uqs '#%braces)]) + #'(semi-#%braces sp ...)))) (define-splicing-syntax-class semi-seq - #:literals (#%semi) #:attributes ([semi-form 1] [tail-form 1]) - (pattern (~seq (~seq (~and semi-piece-form (~not #%semi)) ... #%semi) ... - (~and tail-form (~not #%semi)) ...) - #:attr [semi-form 1] (syntax->list #'((semi-piece-form ...) ...))))) + (pattern (~seq s:semi-piece ... tail-form:not-semi ...) + #:attr [semi-form 1] (syntax->list #'(s.it ...))))) (provide #%semi (for-syntax semi-seq)) diff --git a/remix/stx0.rkt b/remix/stx0.rkt index 2a024d1..0c884e4 100644 --- a/remix/stx0.rkt +++ b/remix/stx0.rkt @@ -36,7 +36,8 @@ (def x (remix-λ args . body)))])) (module remix-block racket/base - (require (for-syntax racket/base + (require remix/semi + (for-syntax racket/base racket/generic syntax/parse)) (define-syntax (def* stx) @@ -66,7 +67,7 @@ (syntax/loc stx (def*-internal (x (remix-λ args . def-body)) bind-body))])) - (define-syntax (remix-block stx) + (define-syntax (the-remix-block stx) (syntax-parse stx #:literals (def*) [(_ (~and (~not (def* . _)) before) ... @@ -79,6 +80,12 @@ (syntax/loc stx (let () . body))])) + (define-syntax (remix-block stx) + (syntax-parse stx + [(_ s:semi-seq) + (syntax/loc stx + (the-remix-block s.semi-form ... s.tail-form ...))])) + (define-syntax #%brackets (make-rename-transformer #'remix-block)) @@ -156,7 +163,8 @@ (#,op arg1 arg2)) (syntax->list #'(output ...)))]))) -(define-syntax (#%braces stx) + +(define-syntax (the-#%braces stx) (syntax-parse stx [(_ input-tokens ...) (shunting-yard:consume-input @@ -164,6 +172,17 @@ empty empty)])) +(define-syntax (#%braces stx) + (syntax-parse stx + [(_ s:semi-seq) + (syntax-case #'(s.semi-form ...) () + [() + (syntax/loc stx + (the-#%braces s.tail-form ...))] + [(sf ...) + (syntax/loc stx + (remix-block sf ... (the-#%braces s.tail-form ...)))])])) + (begin-for-syntax (define-generics dot-transformer (dot-transform dot-transformer stx))) diff --git a/remix/tests/simple.rkt b/remix/tests/simple.rkt index 94b767e..827f45a 100644 --- a/remix/tests/simple.rkt +++ b/remix/tests/simple.rkt @@ -5,6 +5,7 @@ require remix/stx0 remix/num/gen0; +; (module+ test ;; This introduces ≡ as a testing form @@ -14,18 +15,45 @@ require remix/stx0 (require remix/test0)) ;; define is replaced with def -(def z 42) -(module+ test - {z ≡ 42}) +def z 42; +module+ test + {z ≡ 42}; ;; when def has more forms than one, they are put inside of a block -(def x - (def a 40) - (def b 2) - (+ a b)) +def x + (def a 40) + (def b 2) + (+ a b) ; +; (module+ test {x ≡ 42}) +;; If you would like to use ;-syntax in the inside of def, then you +;; need more punctuation. You have two choices. +def x2 + [def a 40; + def b 2; + (+ a b)]; +; +(module+ test + {x2 ≡ 42}) + +def x3 + {def a 40; + def b 2; + a + b}; +; +(module+ test + {x3 ≡ 42}) + +def x4 + {a := 40,; + b := 2,; + a + b}; +; +(module+ test + {x4 ≡ 42}) + ;; but of course def supports function definitions. [] is NOT the same ;; as (), it parses as #%brackets and defaults to expanding to a block ;; definition