syntax/parse: added define/syntax-parse, like define/with-syntax
This commit is contained in:
parent
896cb86dc4
commit
c677932baf
|
@ -23,6 +23,7 @@
|
||||||
let-attributes
|
let-attributes
|
||||||
let-attributes*
|
let-attributes*
|
||||||
let/unpack
|
let/unpack
|
||||||
|
defattrs/unpack
|
||||||
attribute
|
attribute
|
||||||
attribute-binding
|
attribute-binding
|
||||||
check-list^depth)
|
check-list^depth)
|
||||||
|
@ -146,10 +147,11 @@
|
||||||
(for/and ([part (in-list value)])
|
(for/and ([part (in-list value)])
|
||||||
(check-syntax (sub1 depth) part)))))
|
(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-syntax (let-attributes stx)
|
||||||
(define (parse-attr x)
|
|
||||||
(syntax-case x ()
|
|
||||||
[#s(attr name depth syntax?) #'(name depth syntax?)]))
|
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[(let-attributes ([a value] ...) . body)
|
[(let-attributes ([a value] ...) . body)
|
||||||
(with-syntax ([((name depth syntax?) ...)
|
(with-syntax ([((name depth syntax?) ...)
|
||||||
|
@ -185,6 +187,21 @@
|
||||||
#'(let-values ([(tmp ...) (apply values packed)])
|
#'(let-values ([(tmp ...) (apply values packed)])
|
||||||
(let-attributes ([a tmp] ...) body)))]))
|
(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)
|
(define-syntax (attribute stx)
|
||||||
(parameterize ((current-syntax-context stx))
|
(parameterize ((current-syntax-context stx))
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
|
|
|
@ -6,14 +6,14 @@
|
||||||
"rep.rkt")
|
"rep.rkt")
|
||||||
"parse.rkt"
|
"parse.rkt"
|
||||||
"keywords.rkt"
|
"keywords.rkt"
|
||||||
"runtime.rkt")
|
"runtime.rkt"
|
||||||
|
"runtime-report.rkt")
|
||||||
|
|
||||||
(provide define-syntax-class
|
(provide define-syntax-class
|
||||||
define-splicing-syntax-class
|
define-splicing-syntax-class
|
||||||
|
|
||||||
syntax-parse
|
syntax-parse
|
||||||
syntax-parser
|
syntax-parser
|
||||||
syntax-parser/template
|
|
||||||
|
|
||||||
(except-out (all-from-out "keywords.rkt")
|
(except-out (all-from-out "keywords.rkt")
|
||||||
~reflect
|
~reflect
|
||||||
|
@ -23,7 +23,10 @@
|
||||||
attribute
|
attribute
|
||||||
this-syntax
|
this-syntax
|
||||||
|
|
||||||
|
define/syntax-parse
|
||||||
|
|
||||||
;;----
|
;;----
|
||||||
|
syntax-parser/template
|
||||||
parser/rhs)
|
parser/rhs)
|
||||||
|
|
||||||
(begin-for-syntax
|
(begin-for-syntax
|
||||||
|
@ -144,3 +147,37 @@
|
||||||
(lambda (x)
|
(lambda (x)
|
||||||
(let ([x (datum->syntax #f x)])
|
(let ([x (datum->syntax #f x)])
|
||||||
(parse:clauses x clauses one-template ctx))))]))
|
(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) ...)))))))))]))
|
||||||
|
|
|
@ -137,3 +137,21 @@ Suppresses the ``colon notation'' for annotated pattern variables.
|
||||||
Like @scheme[syntax-parse], but produces a matching procedure. The
|
Like @scheme[syntax-parse], but produces a matching procedure. The
|
||||||
procedure accepts a single argument, which should be a syntax object.
|
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.
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user