guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: syntax-local-binding


From: Andy Wingo
Subject: Re: syntax-local-binding
Date: Thu, 19 Jan 2012 12:41:13 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux)

Hello,

I have now pushed an implementation of syntax-local-binding to
stable-2.0, with the following documentation.  In the spirit of Eli's
note on Racket's syntax-local-value, it also works with identifiers that
are bound at the module level or the top level.  Comments and patches
welcome.

Cheers,

Andy

 -- Scheme Procedure: syntax-local-binding id
     Resolve the identifer ID, a syntax object, within the current
     lexical environment, and return two values, the binding type and a
     binding value.  The binding type is a symbol, which may be one of
     the following:

    `lexical'
          A lexically-bound variable.  The value is a unique token (in
          the sense of `eq?') identifying this binding.

    `macro'
          A syntax transformer, either local or global.  The value is
          the transformer procedure.

    `pattern-variable'
          A pattern variable, bound via syntax-case.  The value is an
          opaque object, internal to the expander.

    `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 introduce it in a context in which
          it is unbound.  The value is `#f'.

    `global'
          A global binding.  The value is a pair, whose head is the
          symbol, and whose tail is the name of the module in which to
          resolve the symbol.

    `other'
          Some other binding, like `lambda' or other core bindings.  The
          value is `#f'.

     This is a very low-level procedure, with limited uses.  One case in
     which it is useful is to build abstractions that associate
     auxiliary information with macros:

          (define aux-property (make-object-property))
          (define-syntax-rule (with-aux aux value)
            (let ((trans value))
              (set! (aux-property trans) aux)
              trans)))
          (define-syntax retrieve-aux
            (lambda (x)
              (syntax-case x ()
                ((x id)
                 (call-with-values (lambda () (syntax-local-binding #'id))
                   (lambda (type val)
                     (with-syntax ((aux (datum->syntax #'here
                                                       (and (eq? type 'macro)
                                                            (aux-property 
val)))))
                       #''aux)))))))
          (define-syntax foo
            (with-aux 'bar
              (syntax-rules () ((_) 'foo))))
          (foo)
          => foo
          (retrieve-aux foo)
          => bar

     `syntax-local-binding' must be called within the dynamic extent of
     a syntax transformer; to call it otherwise will signal an error.

-- 
http://wingolog.org/



reply via email to

[Prev in Thread] Current Thread [Next in Thread]