diff --git a/pkgs/racket-doc/syntax/scribblings/parse/lib.scrbl b/pkgs/racket-doc/syntax/scribblings/parse/lib.scrbl index be6a92e1d6..3e1da952fc 100644 --- a/pkgs/racket-doc/syntax/scribblings/parse/lib.scrbl +++ b/pkgs/racket-doc/syntax/scribblings/parse/lib.scrbl @@ -1,28 +1,39 @@ #lang scribble/doc @(require (for-syntax racket/base) + syntax/parse/define scribble/manual scribble/struct scribble/decode scribble/eval "../common.rkt" "parse-common.rkt" - (for-label racket/base racket/contract racket/syntax syntax/kerncase)) + (for-label racket/base racket/contract racket/syntax + syntax/kerncase syntax/parse/lib/function-header)) @(define the-eval (make-sp-eval)) -@(the-eval `(require syntax/parse/lib/function-header)) +@(the-eval '(require syntax/parse/lib/function-header)) @title{Library Syntax Classes and Literal Sets} @section{Syntax Classes} @(begin - (define-syntax (defstxclass stx) - (syntax-case stx () - [(defstxclass name . pre-flows) - (identifier? #'name) - #'(defidform #:kind "syntax class" name . pre-flows)] - [(defstxclass datum . pre-flows) - #'(defproc #:kind "syntax class" datum @#,tech{syntax class} . pre-flows)]))) + (begin-for-syntax + (define-splicing-syntax-class stxclass-option + #:attributes (type) + (pattern {~seq #:splicing} + #:with type #'"splicing syntax class") + (pattern {~seq} + #:with type #'"syntax class"))) + (define-syntax-parser defstxclass + [(_ name:id :stxclass-option . pre-flows) + #'(defidform #:kind type name . pre-flows)] + [(_ datum . pre-flows) + #'(defproc #:kind "syntax class" datum @#,tech{syntax class} . pre-flows)]) + (define-syntax-parser defattribute + [(_ name:id . pre-flows) + #'(subdefthing #:kind "attribute" #:link-target? #f name + . pre-flows)])) @defstxclass[expr]{ @@ -221,18 +232,37 @@ Note that the literal-set uses the names @racket[#%plain-lambda] and @defmodule[syntax/parse/lib/function-header] @defstxclass[function-header]{ - Matches the formals found in function headers. Including - keyword and rest arguments.} -@defstxclass[formal]{ - Matches a single formal that can be used in a function - header.} + Matches a name and formals found in function header. + It also supports the curried function shorthand. + @defattribute[name syntax?]{ + The name part in the function header. + } + @defattribute[params syntax?]{ + The list of parameters in the function header. + } +} +@defstxclass[formal #:splicing]{ + Matches a single formal that can be used in a function header. + @defattribute[name syntax?]{ + The name part in the formal. + } + @defattribute[kw (or/c syntax? #f)]{ + The keyword part in the formal, if it exists. + } + @defattribute[default (or/c syntax? #f)]{ + The default expression part in the formal, if it exists. + } +} @defstxclass[formals]{ - Matches a list of formals that would be used in a function - header.} + Matches a list of formals that would be used in a function header. + @defattribute[params syntax?]{ + The list of parameters in the formals. + } +} @interaction[#:eval the-eval (syntax-parse #'(define ((foo x) y) 1) - [(_ header:function-header body ...+) #'(header header.params)]) + [(_ header:function-header body ...+) #'(header header.name header.params)]) (syntax-parse #'(lambda xs xs) [(_ fmls:formals body ...+) #'(fmls fmls.params)]) (syntax-parse #'(lambda (x y #:kw [kw 42] . xs) xs) diff --git a/pkgs/racket-doc/syntax/scribblings/parse/parse-common.rkt b/pkgs/racket-doc/syntax/scribblings/parse/parse-common.rkt index 61e4343f36..8beedf3a73 100644 --- a/pkgs/racket-doc/syntax/scribblings/parse/parse-common.rkt +++ b/pkgs/racket-doc/syntax/scribblings/parse/parse-common.rkt @@ -104,9 +104,13 @@ (racket id) #|(superscript (symbol->string 'suffix)) ...|# )])) +(define-syntax-rule (subdefthing . xs) + (nested #:style "leftindent" (defthing . xs))) + (provide defhere ref - def) + def + subdefthing) ;; ---- diff --git a/pkgs/racket-test/tests/stxparse/function-header.rkt b/pkgs/racket-test/tests/stxparse/function-header.rkt index 42db582d29..dfa508b6ee 100644 --- a/pkgs/racket-test/tests/stxparse/function-header.rkt +++ b/pkgs/racket-test/tests/stxparse/function-header.rkt @@ -81,10 +81,12 @@ (syntax-parse #'(f a b c) [a:function-header (s= a '(f a b c )) - (s= a.params '(a b c))])) + (s= a.params '(a b c)) + (s= a.name 'f)])) (test-case "function header: curried" (syntax-parse #'((f doing) currying) [a:function-header (s= a '((f doing) currying)) - (s= a.params '(doing currying))])) + (s= a.params '(doing currying)) + (s= a.name 'f)])) diff --git a/racket/collects/syntax/parse/lib/function-header.rkt b/racket/collects/syntax/parse/lib/function-header.rkt index 686bc0568a..b0f49be7fd 100644 --- a/racket/collects/syntax/parse/lib/function-header.rkt +++ b/racket/collects/syntax/parse/lib/function-header.rkt @@ -6,9 +6,10 @@ (provide function-header formal formals) (define-syntax-class function-header - (pattern ((~or header:function-header name:id) . args:formals) - #:attr params - #'((~@ . (~? header.params ())) . args.params))) + #:attributes (name params) + (pattern ((~or header:function-header name*:id) . args:formals) + #:attr params #'((~@ . (~? header.params ())) . args.params) + #:attr name #'(~? header.name name*))) (define-syntax-class formals #:attributes (params)