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