Next: , Previous: , Up: expander lexenv   [Index]


15.3.6 Internal syntactic bindings

The internal syntactic bindings are the ones established by the code being expanded, both at the top level and in a local context. The association between their label gensyms and their descriptors is maintained in the LEXENV.

A LEXENV is an alist managed somewhat like a stack; while the expansion proceeds, visiting the code in breadth–first order: the LEXENV is updated by pushing new entries on the stack. A LEXENV entry has the following format:

(?label . ?syntactic-binding-descriptor)

where: ?label is a label gensym uniquely associated to a syntactic binding; ?syntactic-binding-descriptor is a syntactic binding descriptor.

Function: current-inferior-lexenv

Return an alist representing the current LEXENV used at the inferior expansion level; mutating the returned value leads to undefined behaviour. It is to be used from the body of a macro transformer.

As example, to just print the LEXENV we can do:

(import (vicare))

(define-syntax (print-lexenv stx)
  (import (prefix (vicare expander) xp::))
  (print-gensym #f)
  (pretty-print (xp::current-inferior-lexenv)
                (current-error-port))
  #'(void))

(define a 1)

(print-lexenv)

and we will see two entries:

((lab.a            . (lexical . (lex.a . #f)))
 (lab.print-lexenv . (local-macro . (#<procedure> . ?sexp))))

where ?sexp is the symbolic expression representing the transformer function of print-lexenv fully expanded to the core language.

Top level and local syntactic bindings are represented in the same way in the LEXENV; the difference between them is that top level syntactic bindings have the association between the source name and the label gensym stored in the top level rib object.


Next: , Previous: , Up: expander lexenv   [Index]