syntax/parse: added define/syntax-parse, like define/with-syntax

This commit is contained in:
Ryan Culpepper 2011-04-01 02:12:30 -06:00
parent 896cb86dc4
commit c677932baf
3 changed files with 77 additions and 5 deletions

View File

@ -23,6 +23,7 @@
let-attributes
let-attributes*
let/unpack
defattrs/unpack
attribute
attribute-binding
check-list^depth)
@ -146,10 +147,11 @@
(for/and ([part (in-list value)])
(check-syntax (sub1 depth) part)))))
(define-for-syntax (parse-attr x)
(syntax-case x ()
[#s(attr name depth syntax?) #'(name depth syntax?)]))
(define-syntax (let-attributes stx)
(define (parse-attr x)
(syntax-case x ()
[#s(attr name depth syntax?) #'(name depth syntax?)]))
(syntax-case stx ()
[(let-attributes ([a value] ...) . body)
(with-syntax ([((name depth syntax?) ...)
@ -185,6 +187,21 @@
#'(let-values ([(tmp ...) (apply values packed)])
(let-attributes ([a tmp] ...) body)))]))
(define-syntax (defattrs/unpack stx)
(syntax-case stx ()
[(defattrs (a ...) packed)
(with-syntax ([((name depth syntax?) ...)
(map parse-attr (syntax->list #'(a ...)))])
(with-syntax ([(vtmp ...) (generate-temporaries #'(name ...))]
[(stmp ...) (generate-temporaries #'(name ...))])
#'(begin (define-values (vtmp ...) (apply values packed))
(define-syntax stmp
(make-attribute-mapping (quote-syntax vtmp)
'name 'depth 'syntax?))
...
(define-syntax name (make-syntax-mapping 'depth (quote-syntax stmp)))
...)))]))
(define-syntax (attribute stx)
(parameterize ((current-syntax-context stx))
(syntax-case stx ()

View File

@ -6,14 +6,14 @@
"rep.rkt")
"parse.rkt"
"keywords.rkt"
"runtime.rkt")
"runtime.rkt"
"runtime-report.rkt")
(provide define-syntax-class
define-splicing-syntax-class
syntax-parse
syntax-parser
syntax-parser/template
(except-out (all-from-out "keywords.rkt")
~reflect
@ -23,7 +23,10 @@
attribute
this-syntax
define/syntax-parse
;;----
syntax-parser/template
parser/rhs)
(begin-for-syntax
@ -144,3 +147,37 @@
(lambda (x)
(let ([x (datum->syntax #f x)])
(parse:clauses x clauses one-template ctx))))]))
;; ====
(define-syntax (define/syntax-parse stx)
(syntax-case stx ()
[(define/syntax-parse pattern . rest)
(let-values ([(rest pattern defs)
(parse-pattern+sides #'pattern
#'rest
#:splicing? #f
#:decls (new-declenv null)
#:context stx)])
(let ([expr
(syntax-case rest ()
[( expr ) #'expr]
[_ (raise-syntax-error #f "bad syntax" stx)])]
[attrs (pattern-attrs pattern)])
(with-syntax ([(a ...) attrs]
[(#s(attr name _ _) ...) attrs]
[pattern pattern]
[(def ...) defs]
[expr expr])
#'(defattrs/unpack (a ...)
(let* ([x expr]
[cx x]
[pr (ps-empty x x)]
[es null]
[fh0 (syntax-patterns-fail x)])
def ...
(#%expression
(with ([fail-handler fh0]
[cut-prompt fh0])
(parse:S x cx pattern pr es
(list (attribute name) ...)))))))))]))

View File

@ -137,3 +137,21 @@ Suppresses the ``colon notation'' for annotated pattern variables.
Like @scheme[syntax-parse], but produces a matching procedure. The
procedure accepts a single argument, which should be a syntax object.
}
@defform[(define/syntax-parse syntax-pattern pattern-directive ... stx-expr)
#:contracts ([stx-expr syntax?])]{
Definition form of @racket[syntax-parse]. That is, it matches the
syntax object result of @racket[stx-expr] against
@racket[syntax-pattern] and creates pattern variable definitions for
the attributes of @racket[syntax-pattern].
@myexamples[
(define/syntax-parse ((~seq kw:keyword arg:expr) ...)
#'(#:a 1 #:b 2 #:c 3))
#'(kw ...)
]
Compare with @racket[define/with-syntax], a similar definition form
that uses the simpler @racket[syntax-case] patterns.
}