diff options
author | Mark H Weaver <mhw@netris.org> | 2013-12-18 18:49:37 -0500 |
---|---|---|
committer | Mark H Weaver <mhw@netris.org> | 2014-01-09 17:41:19 -0500 |
commit | 1624e149f75747310c9ce15db7db5324a538f8f8 (patch) | |
tree | 066f945459667eef41bf29e9d8c3cbe972b13a88 /doc/ref/api-macros.texi | |
parent | 8de355d08e25a877326489c4b0eb09d313c548dc (diff) | |
download | guile-1624e149f75747310c9ce15db7db5324a538f8f8.tar.gz |
psyntax: custom ellipses using 'with-ellipsis' or R7RS syntax-rules.
* module/ice-9/psyntax.scm (binding-type): Update the header comment
to mention the new 'ellipsis' binding type.
(macros-only-env): Preserve ellipsis bindings.
(ellipsis?): Add 'r' and 'mod' as arguments. Search the lexical
environment for an ellipsis binding, and use it.
(gen-syntax): Adapt to the additional arguments of 'ellipsis?'.
(with-ellipsis): New core syntax.
(convert-pattern): Add unary 'ellipsis?' procedure as an argument.
(gen-clause): Adapt to the additional arguments of 'ellipsis?'.
Pass unary 'ellipsis?' procedure to 'convert-pattern'.
(syntax-case): Adapt to the additional arguments of 'ellipsis?'.
(syntax-local-binding): Support new 'ellipsis' binding type.
(syntax-rules): Add support for a custom ellipsis identifier as
the first operand, as per R7RS. Collect common code within new
local procedure 'expand-syntax-rules'.
* module/ice-9/psyntax-pp.scm: Regenerate.
* module/ice-9/local-eval.scm (analyze-identifiers): Add support for
'ellipsis' binding type.
* doc/ref/api-macros.texi (Syntax Rules): Add docs for R7RS custom
ellipsis syntax. Use @dots{}.
(Syntax Case): Add docs for 'with-ellipsis'. Use @dots{}.
(Syntax Transformer Helpers): Update to include new 'ellipsis'
binding type.
* test-suite/tests/syntax.test: Add tests.
Diffstat (limited to 'doc/ref/api-macros.texi')
-rw-r--r-- | doc/ref/api-macros.texi | 71 |
1 files changed, 65 insertions, 6 deletions
diff --git a/doc/ref/api-macros.texi b/doc/ref/api-macros.texi index a3fa83f5a..0d604004f 100644 --- a/doc/ref/api-macros.texi +++ b/doc/ref/api-macros.texi @@ -136,7 +136,7 @@ same @var{letrec-syntax}. @code{syntax-rules} macros are simple, pattern-driven syntax transformers, with a beauty worthy of Scheme. -@deffn {Syntax} syntax-rules literals (pattern template)... +@deffn {Syntax} syntax-rules literals (pattern template) @dots{} Create a syntax transformer that will rewrite an expression using the rules embodied in the @var{pattern} and @var{template} clauses. @end deffn @@ -363,6 +363,26 @@ Cast into this form, our @code{when} example is significantly shorter: (if c (begin e ...))) @end example +@subsubsection Specifying a Custom Ellipsis Identifier + +When writing macros that generate macro definitions, it is convenient to +use a different ellipsis identifier at each level. Guile allows the +desired ellipsis identifier to be specified as the first operand to +@code{syntax-rules}, as per R7RS. For example: + +@example +(define-syntax define-quotation-macros + (syntax-rules () + ((_ (macro-name head-symbol) ...) + (begin (define-syntax macro-name + (syntax-rules ::: () + ((_ x :::) + (quote (head-symbol x :::))))) + ...)))) +(define-quotation-macros (quote-a a) (quote-b b) (quote-c c)) +(quote-a 1 2 3) @result{} (a 1 2 3) +@end example + @subsubsection Further Information For a formal definition of @code{syntax-rules} and its pattern language, see @@ -389,7 +409,7 @@ Primer for the Merely Eccentric}. @code{syntax-case} macros are procedural syntax transformers, with a power worthy of Scheme. -@deffn {Syntax} syntax-case syntax literals (pattern [guard] exp)... +@deffn {Syntax} syntax-case syntax literals (pattern [guard] exp) @dots{} Match the syntax object @var{syntax} against the given patterns, in order. If a @var{pattern} matches, return the result of evaluating the associated @var{exp}. @end deffn @@ -631,9 +651,9 @@ variable environment, and we can do so using @code{syntax-case} itself: However there are easier ways to write this. @code{with-syntax} is often convenient: -@deffn {Syntax} with-syntax ((pat val)...) exp... +@deffn {Syntax} with-syntax ((pat val) @dots{}) exp @dots{} Bind patterns @var{pat} from their corresponding values @var{val}, within the -lexical context of @var{exp...}. +lexical context of @var{exp} @enddots{}. @example ;; better @@ -681,6 +701,42 @@ edition 3 or 4, in the chapter on syntax. Dybvig was the primary author of the @code{syntax-case} system. The book itself is available online at @uref{http://scheme.com/tspl4/}. +@subsubsection Custom Ellipsis Identifiers for syntax-case Macros + +When writing procedural macros that generate macro definitions, it is +convenient to use a different ellipsis identifier at each level. Guile +supports this for procedural macros using the @code{with-ellipsis} +special form: + +@deffn {Syntax} with-ellipsis ellipsis body @dots{} +@var{ellipsis} must be an identifier. Evaluate @var{body} in a special +lexical environment such that all macro patterns and templates within +@var{body} will use @var{ellipsis} as the ellipsis identifier instead of +the usual three dots (@code{...}). +@end deffn + +For example: + +@example +(define-syntax define-quotation-macros + (lambda (x) + (syntax-case x () + ((_ (macro-name head-symbol) ...) + #'(begin (define-syntax macro-name + (lambda (x) + (with-ellipsis ::: + (syntax-case x () + ((_ x :::) + #'(quote (head-symbol x :::))))))) + ...))))) +(define-quotation-macros (quote-a a) (quote-b b) (quote-c c)) +(quote-a 1 2 3) @result{} (a 1 2 3) +@end example + +Note that @code{with-ellipsis} does not affect the ellipsis identifier +of the generated code, unless @code{with-ellipsis} is included around +the generated code. + @node Syntax Transformer Helpers @subsection Syntax Transformer Helpers @@ -740,8 +796,11 @@ of @code{eq?}) identifying this binding. A syntax transformer, either local or global. The value is the transformer procedure. @item pattern-variable -A pattern variable, bound via syntax-case. The value is an opaque -object, internal to the expander. +A pattern variable, bound via @code{syntax-case}. The value is an +opaque object, internal to the expander. +@item ellipsis +An internal binding, bound via @code{with-ellipsis}. The value is the +(anti-marked) local ellipsis identifier. @item displaced-lexical A lexical variable that has gone out of scope. This can happen if a badly-written procedural macro saves a syntax object, then attempts to |