Programming Language for Old Timers


by David A. Moon
February 2006 .. September 2008

Comments and criticisms to dave underscore moon atsign alum dot mit dot edu.


Previous page   Table of Contents   Next page


Definitions At Macro Expansion Time

It is sometimes necessary to deal explicitly with local scopes in macros. For example, the block macro must establish a new scope before parsing its body, so that local definitions of macros in the body get recorded in the correct scope and can assist in the parsing of expressions later in the body.

The following macro and functions provide the necessary programming interface to the compiler's internal data structures. These should only be called at compile time, not at run time. These names are in the compiler module.

defmacro with-new-compiler-scope ?:block => ...
Establishes a new local scope while evaluating the block. This is a local scope for parsing that occurs while evaluating the block. Thus it is a scope for compiling code produced by the block, not for compiling the block itself. The new scope is nested inside the compiler's current local scope.

def get-local-compiler-scope() ...
Returns the current local scope established by with-new-compiler-scope or by the compiler itself.

def known-definition(name is name) ...
Returns the value of the known definition of the specified name that is visible in the current local scope, or false if there is no definition or the definition does not have a known value because it is not a constant-definition. defclass, defmacro, defmodule, and defoperator create constant-definitions.

def lookup(scope is scope, name is name, result: x is definition or false) ...
Returns the definition of the specified name that is visible in the specified scope, or false if there is no visible definition.

def add-definition(scope is scope, name is name, definition is definition,
                   result: definition) ...
Adds the specified definition to the specified scope under the specified name. Returns its third argument. Usually this is called implicitly by the constructor of a definition.

Anaphoric macros require access to the context of the macro's caller. This is defined to be the context of the name of the macro in the macro call. For a macro call that appears directly in source code, this context is false. For a macro call produced by macro expansion, this context is the context of the first macro. The following macro and function provide the necessary programming interface to the compiler's internal data structures. These should only be called at compile time, not at run time. These names are in the compiler module.

defmacro with-previous-context ?context ?:block => ...
Establishes a new previous context while evaluating the block. The macro expander inside of parse-expression uses this to make the context of the macro's name in a macro call available to the macro in case the macro uses anaphora.

def get-previous-context() ...
Returns the previous context dynamically established by with-previous-context. Anaphoric macros call this, either directly or by using the ?= template syntax.


Previous page   Table of Contents   Next page