FAUST compiler  0.9.9.6b8
Functions | Variables
environment.cpp File Reference
#include "environment.hh"
#include "errormsg.hh"
#include "boxes.hh"
#include "ppbox.hh"
#include "names.hh"
Include dependency graph for environment.cpp:

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.
Tree pushEnvBarrier (Tree lenv)
bool isEnvBarrier (Tree lenv)
 Test if the environment is a barrier (or nil) so that searchIdDef will know where to stop when searching an 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 (until first barrier) 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.

Variables

Sym BARRIER = symbol ("BARRIER")
 Push a new environment barrier on top of an existing environment so that searchIdDef (used by the pattern matcher) will not look after the barrier.

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:
idthe symbol id to be defined
defthe definition to be binded to the symbol id
lenvthe environment where to add this new definition

Definition at line 69 of file environment.cpp.

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

Referenced by pushMultiClosureDefs(), and pushValueDef().

{
    // check for multiple definitions of a symbol in the same layer
    Tree olddef;
    if (getProperty(lenv, id, olddef)) {
        if (def == olddef) {
            evalwarning(getDefFileProp(id), getDefLineProp(id), "equivalent re-definitions of", id);
        } else {
            fprintf(stderr, "%s:%d: ERROR: redefinition of symbols are not allowed : ", getDefFileProp(id), getDefLineProp(id));
            print(id,stderr);
            fprintf(stderr, " is already defined in file \"%s\" line %d \n", getDefFileProp(id), getDefLineProp(id));
            gErrorCount++;
        }
    }
    setProperty(lenv, id, def);
}

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:
xenvexisting environment we will copy
ldefslist of pairs (symbol id x definition) that will replace old definitions
visitedset of visited symbols (used for recursive definition detection)
lenvthe current environment to evaluate the definitions
Returns:
the new environment

Definition at line 169 of file environment.cpp.

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

Referenced by realeval().

{
    vector<Tree>    ids, clos;
    Tree            copyEnv;

    anEnv->exportProperties(ids, clos);             // get the definitions of the environment
    copyEnv = pushNewLayer(anEnv->branch(0));       // create new environment with same stack
    updateClosures(clos, anEnv, copyEnv);           // update the closures replacing oldEnv with newEnv

    for (unsigned int i=0; i < clos.size(); i++) {           // transfers the updated definitions to the new environment
        setProperty(copyEnv, ids[i], clos[i]);
    }

    while (!isNil(ldefs)) {                         // replace the old definitions with the new ones
        Tree def = hd(ldefs);
        Tree id = hd(def);
        Tree rhs= tl(def);
        Tree cl = closure(rhs,nil,visited,curEnv);
        stringstream s; s << boxpp(id);
        if (!isBoxCase(rhs)) setDefNameProperty(cl,s.str());
        setProperty(copyEnv, id, cl);
        ldefs = tl(ldefs);
    }
    return copyEnv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool isEnvBarrier ( Tree  lenv)

Test if the environment is a barrier (or nil) so that searchIdDef will know where to stop when searching an environment.

Parameters:
lenvthe environment to test
Returns:
true is barrier reached

Definition at line 56 of file environment.cpp.

References isNil(), and CTree::node().

Referenced by searchIdDef().

{
    return isNil(lenv) || (lenv->node() == Node(BARRIER));
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 43 of file environment.cpp.

References tree().

Referenced by evalCase().

{
    return tree(BARRIER, lenv);
}

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:
ldefslist of pairs (symbol id x definition) to be binded to the symbol id
visitedset of visited symbols (used for recursive definition detection)
lenvthe environment where to push the layer and add all the definitions
Returns:
the new environment

Definition at line 109 of file environment.cpp.

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

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

{
    Tree lenv2 = pushNewLayer(lenv);
    while (!isNil(ldefs)) {
        Tree def = hd(ldefs);
        Tree id = hd(def);
        Tree rhs= tl(def);
        Tree cl = closure(tl(def),nil,visited,lenv2);
        stringstream s; s << boxpp(id);
        if (!isBoxCase(rhs)) setDefNameProperty(cl,s.str());
        addLayerDef( id, cl, lenv2 );
        ldefs = tl(ldefs);
    }
    return lenv2;
}

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:
lenvthe old environment
Returns:
the new environment

Definition at line 26 of file environment.cpp.

References tree(), and unique().

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

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

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:
idthe symbol id to be defined
defthe definition to be binded to the symbol id
lenvthe environment where to push the layer and add the definition
Returns:
the new environment

Definition at line 94 of file environment.cpp.

References addLayerDef(), and pushNewLayer().

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

{
    Tree lenv2 = pushNewLayer(lenv);
    addLayerDef(id, def, lenv2);
    return lenv2;
}

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 (until first barrier) for the definition of a symbol ID and return it.

Used by the pattern matcher.

Parameters:
idthe symbol ID to search
defwhere to store the definition if any
lenvthe environment
Returns:
true if a definition was found

Definition at line 135 of file environment.cpp.

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

Referenced by apply_pattern_matcher().

{
    // search the environment until a definition is found
    // or a barrier (or nil) is reached

    while (!isEnvBarrier(lenv) && !getProperty(lenv, id, def)) {
        lenv = lenv->branch(0);
    }
    return !isEnvBarrier(lenv);
}

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 149 of file environment.cpp.

References closure(), and isClosure().

Referenced by copyEnvReplaceDefs().

{
    for (unsigned int i=0; i < clos.size(); i++) {
        Tree exp, genv, visited, lenv;
        if (isClosure(clos[i], exp, genv, visited, lenv)) {
            if (lenv == oldEnv) {
                clos[i] = closure(exp, genv, visited, newEnv);
            }
        }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Sym BARRIER = symbol ("BARRIER")

Push a new environment barrier on top of an existing environment so that searchIdDef (used by the pattern matcher) will not look after the barrier.

This barrier will not any influence on regular environment lookup.

Parameters:
lenvthe old environment
Returns:
the new environment

Definition at line 41 of file environment.cpp.