summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2010-08-06 12:16:49 +0200
committerAndy Wingo <wingo@pobox.com>2010-08-06 12:16:49 +0200
commit69724dde0aaa00e356502554c6bb587c1088563b (patch)
tree0d9a3a5bdc6e1008054589040ee85625412d5504
parent935c7acac73667d0e3a9239f8a156f163baed6ce (diff)
downloadguile-69724dde0aaa00e356502554c6bb587c1088563b.tar.gz
add settable identifier syntax docs
* doc/ref/api-macros.texi (Identifier Macros): Add documentation for settable identifier syntax.
-rw-r--r--doc/ref/api-macros.texi66
1 files changed, 62 insertions, 4 deletions
diff --git a/doc/ref/api-macros.texi b/doc/ref/api-macros.texi
index 51f54ed07..fba14f3c8 100644
--- a/doc/ref/api-macros.texi
+++ b/doc/ref/api-macros.texi
@@ -772,10 +772,68 @@ following to replace @code{fx+} with @code{+}:
(define-syntax fx+ (identifier-syntax +))
@end example
-Later versions of the @code{psyntax} @code{syntax-case} expander, on which
-Guile's syntax expander is based, include @code{identifier-syntax} support for
-recognizing identifiers on the left-hand side of a @code{set!} expression as
-well. Guile should port that code to its expander.
+There is also special support for recognizing identifiers on the
+left-hand side of a @code{set!} expression, as in the following:
+
+@example
+(define-syntax foo foo-transformer)
+(set! foo @var{val})
+;; expands via
+(foo-transformer #'(set! foo @var{val}))
+;; iff foo-transformer is a "variable transformer"
+@end example
+
+As the example notes, the transformer procedure must be explicitly
+marked as being a ``variable transformer'', as most macros aren't
+written to discriminate on the form in the operand position.
+
+@deffn {Scheme Procedure} make-variable-transformer transformer
+Mark the @var{transformer} procedure as being a ``variable
+transformer''. In practice this means that, when bound to a syntactic
+keyword, it may detect references to that keyword on the left-hand-side
+of a @code{set!}.
+
+@example
+(define bar 10)
+(define-syntax bar-alias
+ (make-variable-transformer
+ (lambda (x)
+ (syntax-case x (set!)
+ ((set! var val) #'(set! bar val))
+ ((var arg ...) #'(bar arg ...))
+ (var (identifier? #'var) #'bar)))))
+
+bar-alias @result{} 10
+(set! bar-alias 20)
+bar @result{} 20
+(set! bar 30)
+bar-alias @result{} 30
+@end example
+@end deffn
+
+There is an extension to identifer-syntax which allows it to handle the
+@code{set!} case as well:
+
+@deffn {Syntax} identifier-syntax (var exp1) ((set! var val) exp2)
+Create a variable transformer. The first clause is used for references
+to the variable in operator or operand position, and the second for
+appearances of the variable on the left-hand-side of an assignment.
+
+For example, the previous @code{bar-alias} example could be expressed
+more succinctly like this:
+
+@example
+(define-syntax bar-alias
+ (identifier-syntax
+ (var bar)
+ ((set! var val) (set! bar val))))
+@end example
+
+@noindent
+As before, the templates in @code{identifier-syntax} forms do not need
+wrapping in @code{#'} syntax forms.
+@end deffn
+
@node Eval When
@subsection Eval-when