@c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual.
-@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010, 2011, 2012
-@c Free Software Foundation, Inc.
+@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010, 2011,
+@c 2012, 2013, 2014 Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions.
@node Macros
exp)
((my-or exp rest ...)
(let ((t exp))
- (if exp
- exp
+ (if t
+ t
(my-or rest ...)))))))
(my-or #f "rockaway beach"))
@result{} "rockaway beach"
@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
((_ #((var val) ...) exp exp* ...)
(let ((var val) ...) exp exp* ...))))
(letv #((foo 'bar)) foo)
-@result{} foo
+@result{} bar
@end example
Literals are used to match specific datums in an expression, like the use of
exp)
((my-or exp rest ...)
(let ((t exp))
- (if exp
- exp
+ (if t
+ t
(my-or rest ...))))))
@end example
(if c (begin e ...)))
@end example
+@subsubsection Reporting Syntax Errors in Macros
+
+@deffn {Syntax} syntax-error message [arg ...]
+Report an error at macro-expansion time. @var{message} must be a string
+literal, and the optional @var{arg} operands can be arbitrary expressions
+providing additional information.
+@end deffn
+
+@code{syntax-error} is intended to be used within @code{syntax-rules}
+templates. For example:
+
+@example
+(define-syntax simple-let
+ (syntax-rules ()
+ ((_ (head ... ((x . y) val) . tail)
+ body1 body2 ...)
+ (syntax-error
+ "expected an identifier but got"
+ (x . y)))
+ ((_ ((name val) ...) body1 body2 ...)
+ ((lambda (name ...) body1 body2 ...)
+ val ...))))
+@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 specified by SRFI-46 and 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
@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
@code{syntax-case} it is easy:
@deffn {Scheme Procedure} identifier? syntax-object
-Returns @code{#t} iff @var{syntax-object} is an identifier.
+Returns @code{#t} if @var{syntax-object} is an identifier, or @code{#f}
+otherwise.
@end deffn
@example
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
@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
type.
@deffn {Scheme Procedure} bound-identifier=? a b
-Return @code{#t} iff the syntax objects @var{a} and @var{b} refer to the
-same lexically-bound identifier.
+Return @code{#t} if the syntax objects @var{a} and @var{b} refer to the
+same lexically-bound identifier, or @code{#f} otherwise.
@end deffn
@deffn {Scheme Procedure} free-identifier=? a b
-Return @code{#t} iff the syntax objects @var{a} and @var{b} refer to the
-same free identifier.
+Return @code{#t} if the syntax objects @var{a} and @var{b} refer to the
+same free identifier, or @code{#f} otherwise.
@end deffn
@deffn {Scheme Procedure} generate-temporaries ls
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
(set! foo @var{val})
;; expands via
(foo-transformer #'(set! foo @var{val}))
-;; iff foo-transformer is a "variable transformer"
+;; if foo-transformer is a "variable transformer"
@end example
As the example notes, the transformer procedure must be explicitly
@deffn {Scheme Procedure} macro? obj
@deffnx {C Function} scm_macro_p (obj)
-Return @code{#t} iff @var{obj} is a syntax transformer.
+Return @code{#t} if @var{obj} is a syntax transformer, or @code{#f}
+otherwise.
Note that it's a bit difficult to actually get a macro as a first-class object;
simply naming it (like @code{case}) will produce a syntax error. But it is