environment.cpp File Reference

#include "environment.hh"
#include "tlib.hh"
#include "errormsg.hh"
#include "boxes.hh"
#include "ppbox.hh"
#include "names.hh"
Include dependency graph for environment.cpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

static Tree pushNewLayer (Tree lenv)
 Push a new (unique) empty layer (where multiple definitions can be stored) on top of an existing environment.
static void addLayerDef (Tree id, Tree def, Tree lenv)
 Add a definition (as a property) to the current top level layer.
Tree pushValueDef (Tree id, Tree def, Tree lenv)
 Push a new layer and add a single definition.
Tree pushMultiClosureDefs (Tree ldefs, Tree visited, Tree lenv)
 Push a new layer with multiple definitions creating the appropriate closures.
bool searchIdDef (Tree id, Tree &def, Tree lenv)
 Search the environment for the definition of a symbol ID and return it.
static void updateClosures (vector< Tree > &clos, Tree oldEnv, Tree newEnv)
 Replace closure that point to oldEnv with closure on newEnv.
Tree copyEnvReplaceDefs (Tree anEnv, Tree ldefs, Tree visited, Tree curEnv)
 Create a new environment by copying an existing one and replacing some definitions.

Function Documentation

static void addLayerDef ( Tree  id,
Tree  def,
Tree  lenv 
) [static]

Add a definition (as a property) to the current top level layer.

Check and warn for multiple definitions.

Parameters:
id the symbol id to be defined
def the definition to be binded to the symbol id
lenv the environment where to add this new definition

Definition at line 39 of file environment.cpp.

References evalwarning(), gErrorCount, getDefFileProp(), getDefLineProp(), getProperty(), print(), and setProperty().

Referenced by pushMultiClosureDefs(), and pushValueDef().

00040 {
00041     // check for multiple definitions of a symbol in the same layer
00042     Tree olddef;
00043     if (getProperty(lenv, id, olddef)) {
00044         if (def == olddef) {
00045             evalwarning(getDefFileProp(id), getDefLineProp(id), "equivalent re-definitions of", id);
00046         } else {
00047             fprintf(stderr, "%s:%d: ERROR: redefinition of symbols are not allowed : ", getDefFileProp(id), getDefLineProp(id));
00048             print(id,stderr);
00049             fprintf(stderr, " is already defined in file \"%s\" line %d \n", getDefFileProp(id), getDefLineProp(id));
00050             gErrorCount++;
00051         }
00052     }
00053     setProperty(lenv, id, def);
00054 }

Here is the call graph for this function:

Here is the caller graph for this function:

Tree copyEnvReplaceDefs ( Tree  anEnv,
Tree  ldefs,
Tree  visited,
Tree  curEnv 
)

Create a new environment by copying an existing one and replacing some definitions.

Parameters:
xenv existing environment we will copy
ldefs list of pairs (symbol id x definition) that will replace old definitions
visited set of visited symbols (used for recursive definition detection)
lenv the current environment to evaluate the definitions
Returns:
the new environment

Definition at line 137 of file environment.cpp.

References CTree::branch(), closure(), CTree::exportProperties(), hd(), isBoxCase(), isNil(), nil, pushNewLayer(), setDefNameProperty(), setProperty(), tl(), and updateClosures().

Referenced by realeval().

00138 {
00139     vector<Tree>    ids, clos;
00140     Tree            copyEnv;
00141 
00142     anEnv->exportProperties(ids, clos);             // get the definitions of the environment
00143     copyEnv = pushNewLayer(anEnv->branch(0));       // create new environment with same stack
00144     updateClosures(clos, anEnv, copyEnv);           // update the closures replacing oldEnv with newEnv
00145 
00146     for (unsigned int i=0; i < clos.size(); i++) {           // transfers the updated definitions to the new environment
00147         setProperty(copyEnv, ids[i], clos[i]);
00148     }
00149 
00150     while (!isNil(ldefs)) {                         // replace the old definitions with the new ones
00151         Tree def = hd(ldefs);
00152         Tree id = hd(def);
00153         Tree rhs= tl(def);
00154         Tree cl = closure(rhs,nil,visited,curEnv);
00155         stringstream s; s << boxpp(id);
00156         if (!isBoxCase(rhs)) setDefNameProperty(cl,s.str());
00157         setProperty(copyEnv, id, cl);
00158         ldefs = tl(ldefs);
00159     }
00160     return copyEnv;
00161 }

Here is the call graph for this function:

Here is the caller graph for this function:

Tree pushMultiClosureDefs ( Tree  ldefs,
Tree  visited,
Tree  lenv 
)

Push a new layer with multiple definitions creating the appropriate closures.

Parameters:
ldefs list of pairs (symbol id x definition) to be binded to the symbol id
visited set of visited symbols (used for recursive definition detection)
lenv the environment where to push the layer and add all the definitions
Returns:
the new environment

Definition at line 79 of file environment.cpp.

References addLayerDef(), closure(), hd(), isBoxCase(), isNil(), nil, pushNewLayer(), setDefNameProperty(), and tl().

Referenced by evaldocexpr(), evalprocess(), and realeval().

00080 {
00081     Tree lenv2 = pushNewLayer(lenv);
00082     while (!isNil(ldefs)) {
00083         Tree def = hd(ldefs);
00084         Tree id = hd(def);
00085         Tree rhs= tl(def);
00086         Tree cl = closure(tl(def),nil,visited,lenv2);
00087         stringstream s; s << boxpp(id);
00088         if (!isBoxCase(rhs)) setDefNameProperty(cl,s.str());
00089         addLayerDef( id, cl, lenv2 );
00090         ldefs = tl(ldefs);
00091     }
00092     return lenv2;
00093 }

Here is the call graph for this function:

Here is the caller graph for this function:

static Tree pushNewLayer ( Tree  lenv  )  [static]

Push a new (unique) empty layer (where multiple definitions can be stored) on top of an existing environment.

Parameters:
lenv the old environment
Returns:
the new environment

Definition at line 26 of file environment.cpp.

References tree(), and unique().

Referenced by copyEnvReplaceDefs(), pushMultiClosureDefs(), and pushValueDef().

00027 {
00028     return tree(unique("ENV_LAYER"), lenv);
00029 }

Here is the call graph for this function:

Here is the caller graph for this function:

Tree pushValueDef ( Tree  id,
Tree  def,
Tree  lenv 
)

Push a new layer and add a single definition.

Parameters:
id the symbol id to be defined
def the definition to be binded to the symbol id
lenv the environment where to push the layer and add the definition
Returns:
the new environment

Definition at line 64 of file environment.cpp.

References addLayerDef(), and pushNewLayer().

Referenced by apply_pattern_matcher(), applyList(), iteratePar(), iterateProd(), iterateSeq(), iterateSum(), and real_a2sb().

00065 {
00066     Tree lenv2 = pushNewLayer(lenv);
00067     addLayerDef(id, def, lenv2);
00068     return lenv2;
00069 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool searchIdDef ( Tree  id,
Tree def,
Tree  lenv 
)

Search the environment for the definition of a symbol ID and return it.

Parameters:
id the symbol ID to search
def where to store the definition if any
lenv the environment
Returns:
true if a definition was found

Definition at line 104 of file environment.cpp.

References CTree::branch(), getProperty(), and isNil().

Referenced by apply_pattern_matcher().

00105 {
00106     // search the environment until a definition is found
00107     // or nil (the empty environment) is reached
00108     while (!isNil(lenv) && !getProperty(lenv, id, def)) {
00109         lenv = lenv->branch(0);
00110     }
00111     return !isNil(lenv);
00112 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void updateClosures ( vector< Tree > &  clos,
Tree  oldEnv,
Tree  newEnv 
) [static]

Replace closure that point to oldEnv with closure on newEnv.

Definition at line 117 of file environment.cpp.

References closure(), and isClosure().

Referenced by copyEnvReplaceDefs().

00118 {
00119     for (unsigned int i=0; i < clos.size(); i++) {
00120         Tree exp, genv, visited, lenv;
00121         if (isClosure(clos[i], exp, genv, visited, lenv)) {
00122             if (lenv == oldEnv) {
00123                 clos[i] = closure(exp, genv, visited, newEnv);
00124             }
00125         }
00126     }
00127 }

Here is the call graph for this function:

Here is the caller graph for this function:

Generated on Tue Aug 10 08:04:12 2010 for FAUST compiler by  doxygen 1.6.3