mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-30 06:50:31 +02:00
add settable identifier syntax docs
* doc/ref/api-macros.texi (Identifier Macros): Add documentation for settable identifier syntax.
This commit is contained in:
parent
935c7acac7
commit
69724dde0a
1 changed files with 62 additions and 4 deletions
|
@ -772,10 +772,68 @@ following to replace @code{fx+} with @code{+}:
|
||||||
(define-syntax fx+ (identifier-syntax +))
|
(define-syntax fx+ (identifier-syntax +))
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
Later versions of the @code{psyntax} @code{syntax-case} expander, on which
|
There is also special support for recognizing identifiers on the
|
||||||
Guile's syntax expander is based, include @code{identifier-syntax} support for
|
left-hand side of a @code{set!} expression, as in the following:
|
||||||
recognizing identifiers on the left-hand side of a @code{set!} expression as
|
|
||||||
well. Guile should port that code to its expander.
|
@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
|
@node Eval When
|
||||||
@subsection Eval-when
|
@subsection Eval-when
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue