expand semi support

This commit is contained in:
Jay McCarthy 2015-12-18 20:55:06 -05:00
parent f177276df1
commit c127ed7b80
3 changed files with 74 additions and 15 deletions

View File

@ -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))

View File

@ -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)))

View File

@ -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