Next: Nested environments
Up: Identifier classification
Previous: Tracking current context
Binding identifier occurrences
IdnOrType saves information about the identifier it classifies.
If this is a defining occurrence of an ordinary identifier, and binding is
permitted, then the given identifier should be bound in the current scope
with the appropriate classification.
State variable declarations[37]
:
typedef struct {
int BindingOK; /* 1 if binding is allowed */
int Symbol; /* Identifier to be bound */
Environment Env; /* Environment in which to bind */
int SynCode; /* Identifier classification */
} BindData;
extern BindData CurrentId;
This macro is defined in definitions 30, 37, and 39.
This macro is invoked in definition 56.
Scope rules are embodied in the concept of an environment, which is a
set of bindings for identifiers.
The Eli library's envmod module implements a countour-model environment
suitable for classifying C identifiers:
Instantiate an environment module for identifier analysis[38]
:
$/Name/envmod.specs
This macro is invoked in definition 57.
State variable declarations[39]
:
extern Environment CurrentEnv;
This macro is defined in definitions 30, 37, and 39.
This macro is invoked in definition 56.
Initialize the set of bindings[40]
:
CurrentEnv = NewEnv();
This macro is invoked in definition 59.
IdnOrType captures the current state, adds the specific identifier, and
determines the appropriate classification:
Instance information for binding[41]
:
CurrentId.BindingOK = Context.BindingOK;
CurrentId.Symbol = *rep;
CurrentId.Env = CurrentEnv;
CurrentId.SynCode = Context.SynCode == typedef_def ? typedef_name
: identifier;
This macro is invoked in definition 28.
The environment module binds the identifier to a definition table key;
the classification must be stored as a property of that key:
SynCode: int;
This macro is attached to a product file.
{
if (CurrentId.BindingOK)
ResetSynCode(DefineIdn(CurrentId.Env, CurrentId.Symbol), CurrentId.SynCode);
}
This macro is invoked in definition 55.
In some constructs the state must be saved and the actual binding made
when the end of that construct is reached; in other cases the binding must
be done immediately.
Deferred bindings are nested, so they can be stored on a stack:
Instantiate a stack module for deferred bindings[44]
:
$/Adt/Stack.gnrc +instance=Bind +referto=BindData :inst
This macro is invoked in definition 57.
BindStackPush(CurrentId);
This macro is invoked in definition 17.
CurrentId = BindStackTop; BindStackPop; Bind();
This macro is invoked in definitions 12, 17, and 27.
Bind();
This macro is invoked in definitions 15 and 17.
Next: Nested environments
Up: Identifier classification
Previous: Tracking current context
2008-08-30