summaryrefslogtreecommitdiff
path: root/doc/ref/api-macros.texi
diff options
context:
space:
mode:
authorMark H Weaver <mhw@netris.org>2013-12-18 18:49:37 -0500
committerMark H Weaver <mhw@netris.org>2014-01-09 17:41:19 -0500
commit1624e149f75747310c9ce15db7db5324a538f8f8 (patch)
tree066f945459667eef41bf29e9d8c3cbe972b13a88 /doc/ref/api-macros.texi
parent8de355d08e25a877326489c4b0eb09d313c548dc (diff)
downloadguile-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.texi71
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