eval.cpp File Reference

Implementation of the Block diagram evaluator. More...

#include "eval.hh"
#include <stdio.h>
#include "errormsg.hh"
#include "ppbox.hh"
#include "simplify.hh"
#include "propagate.hh"
#include "patternmatcher.hh"
#include "signals.hh"
#include "xtended.hh"
#include "loopDetector.hh"
#include <assert.h>

Go to the source code of this file.

Functions

static Tree realeval (Tree exp, Tree visited, Tree localValEnv)
 Eval a block diagram expression.
static Tree revEvalList (Tree lexp, Tree visited, Tree localValEnv)
 Eval a list of expression in reverse order.
static Tree applyList (Tree fun, Tree larg)
 Apply a function to a list of arguments.
static Tree iteratePar (Tree id, int num, Tree body, Tree visited, Tree localValEnv)
 Iterate a parallel construction.
static Tree iterateSeq (Tree id, int num, Tree body, Tree visited, Tree localValEnv)
 Iterate a sequential construction.
static Tree iterateSum (Tree id, int num, Tree body, Tree visited, Tree localValEnv)
 Iterate an addition construction.
static Tree iterateProd (Tree id, int num, Tree body, Tree visited, Tree localValEnv)
 Iterate a product construction.
static Tree larg2par (Tree larg)
 Transform a list of expressions in a parallel construction.
static int eval2int (Tree exp, Tree visited, Tree localValEnv)
 Eval a block diagram to an int.
static float eval2float (Tree exp, Tree visited, Tree localValEnv)
 Eval a block diagram to a float.
static Tree pushMultiClosureDefs (Tree ldefs, Tree visited, Tree lenv)
 Push a new layer with multiple definitions creating the appropriate closures.
static Tree evalIdDef (Tree id, Tree visited, Tree lenv)
 Search the environment for the definition of a symbol ID and evaluate it.
static Tree evalCase (Tree rules, Tree env)
 Eval a case expression containing a list of pattern matching rules.
static Tree evalRuleList (Tree rules, Tree env)
 Evaluates each rule of the list.
static Tree evalRule (Tree rule, Tree env)
 Evaluates the list of patterns and closure the rhs.
static Tree evalPatternList (Tree patterns, Tree env)
 Evaluates each pattern of the list.
static Tree evalPattern (Tree pattern, Tree env)
 Evaluates a pattern using a special mode so that free variables are wrapped into a boxPatternVar.
static Tree listn (int n, Tree e)
 Creates a list of n elements.
Tree evalprocess (Tree eqlist)
 Eval "process" from a list of definitions.
static Tree real_a2sb (Tree exp)
 Transform unused (unapplied) closures into symbolic boxes.
bool getDefNameProperty (Tree t, Tree &id)
 Indicates the identifier (if any) the expression was a definition of.
static loopDetector LD (1024, 1)
 Eval a block diagram expression.
void setEvalProperty (Tree box, Tree env, Tree value)
 set the type annotation of sig
bool getEvalProperty (Tree box, Tree env, Tree &value)
 retrieve the value of box in the environment env
Tree simplifyPattern (Tree value)
 Simplify a block-diagram pattern by computing its numerical sub-expressions.
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.
bool searchIdDef (Tree id, Tree &def, Tree lenv)
 Search the environment for the definition of a symbol ID and return it.

Variables

static int gBoxSlotNumber = 0
 counter for unique slot number
Tree DEFNAMEPROPERTY = tree(symbol("DEFNAMEPROPERTY"))
 Definition name property : a property to keep track of the definition name of an expression.
static Node PMPROPERTYNODE (symbol("PMPROPERTY"))
 A property to store the pattern matcher corresponding to a set of rules in a specific environement.


Detailed Description

Implementation of the Block diagram evaluator.

A strict lambda-calculus evaluator for block diagram expressions.

Definition in file eval.cpp.


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 1071 of file eval.cpp.

Referenced by pushMultiClosureDefs(), and pushValueDef().

01072 {
01073     // check for multiple definitions of a symbol in the same layer
01074     Tree olddef;
01075     if (getProperty(lenv, id, olddef)) {
01076         if (def == olddef) {
01077             evalwarning(getDefFileProp(id), getDefLineProp(id), "equivalent re-definitions of", id);
01078         } else {
01079             fprintf(stderr, "%s:%d: ERROR: redefinition of symbols are not allowed : ", getDefFileProp(id), getDefLineProp(id)); 
01080             print(id,stderr); 
01081             fprintf(stderr, " is already defined in file \"%s\" line %d \n", getDefFileProp(id), getDefLineProp(id)); 
01082             gErrorCount++;
01083         }
01084     }
01085     setProperty(lenv, id, def);
01086 }

static Tree applyList ( Tree  fun,
Tree  larg 
) [static]

Apply a function to a list of arguments.

Apply a function F to a list of arguments (a,b,c,...). F can be either a closure over an abstraction, or a pattern matcher. If it is not the case then we have : F(a,b,c,...) ==> (a,b,c,...):F

Parameters:
fun the function to apply
larg the list of arguments
Returns:
the resulting expression in normal form

Definition at line 915 of file eval.cpp.

References getDefNameProperty(), larg2par(), and pushValueDef().

Referenced by real_a2sb(), and realeval().

00916 {
00917     Tree abstr;
00918     Tree globalDefEnv;
00919     Tree visited;
00920     Tree localValEnv;
00921     Tree envList;
00922     Tree originalRules;
00923     Tree revParamList;
00924 
00925     Tree id;
00926     Tree body;
00927     
00928     Automaton*  automat;
00929     int         state;
00930 
00931     prim2   p2;
00932 
00933     if (isNil(larg)) return fun;
00934 
00935     if (isBoxError(fun) || isBoxError(larg)) {
00936         return boxError();
00937     }
00938 
00939     if (isBoxPatternMatcher(fun, automat, state, envList, originalRules, revParamList)) {
00940         Tree            result;
00941         int             state2;
00942         vector<Tree>    envVect;
00943         
00944         list2vec(envList, envVect);
00945         state2 = apply_pattern_matcher(automat, state, hd(larg), result, envVect);
00946         if (state2 >= 0 && isNil(result)) {
00947             // we need to continue the pattern matching
00948             return applyList(
00949                         boxPatternMatcher(automat, state2, vec2list(envVect), originalRules, cons(hd(larg),revParamList)),
00950                         tl(larg) );
00951         } else if (state2 < 0) {
00952             cerr << "ERROR : pattern matching failed, no rule of " << boxpp(boxCase(originalRules)) 
00953                  << " matches argument list " << boxpp(reverse(cons(hd(larg), revParamList))) << endl;
00954             exit(1);
00955         } else {
00956             // Pattern Matching was succesful
00957             // the result is a closure that we need to evaluate.
00958             if (isClosure(result, body, globalDefEnv, visited, localValEnv)) {
00959                 // why ??? return simplifyPattern(eval(body, nil, localValEnv));
00960                 //return eval(body, nil, localValEnv);
00961                 return applyList(eval(body, nil, localValEnv), tl(larg));
00962             } else {
00963                 cout << "wrong result from pattern matching (not a closure) : " << boxpp(result) << endl;
00964                 return boxError();
00965             }
00966         }           
00967     }
00968     if (!isClosure(fun, abstr, globalDefEnv, visited, localValEnv)) {
00969         if (isNil(tl(larg)) && isBoxPrim2(fun, &p2) && (p2 != sigPrefix)) {
00970             return boxSeq(boxPar(boxWire(), hd(larg)), fun);
00971         }
00972         return boxSeq(larg2par(larg), fun);
00973     }
00974 
00975     if (!isBoxAbstr(abstr, id, body)) {
00976         evalerror(yyfilename, -1, "(internal) not an abstraction inside closure", fun);
00977         exit(1);
00978     }
00979 
00980     // try to synthetise a  name from the function name and the argument name
00981     {
00982         Tree arg = eval(hd(larg), visited, localValEnv);
00983         Tree narg; if ( isBoxNumeric(arg,narg) ) { arg =  narg; } 
00984         Tree f = eval(body, visited, pushValueDef(id, arg, localValEnv));
00985 
00986         Tree    fname;
00987         if (getDefNameProperty(fun, fname)) {
00988             stringstream s; s << tree2str(fname); if (!gSimpleNames) s << "(" << boxpp(arg) << ")";
00989             setDefNameProperty(f, s.str());
00990         }
00991         return applyList(f, tl(larg));
00992     }
00993 }

static float eval2float ( Tree  exp,
Tree  visited,
Tree  localValEnv 
) [static]

Eval a block diagram to a float.

Eval a block diagram that represent a float constant. This function first eval a block diagram to its normal form, then check it represent a numerical value (a block diagram of type : 0->1) then do a symbolic propagation and try to convert the resulting signal to a float.

Parameters:
exp the expression to evaluate
globalDefEnv the global environment
visited list of visited definition to detect recursive definitions
localValEnv the local environment
Returns:
a block diagram in normal form

Definition at line 670 of file eval.cpp.

References getBoxType().

Referenced by realeval().

00671 {
00672     Tree diagram = eval(exp, visited, localValEnv);
00673     int numInputs, numOutputs;
00674     getBoxType(diagram, &numInputs, &numOutputs);
00675     if ( (numInputs > 0) || (numOutputs != 1) ) {
00676         evalerror (yyfilename, yylineno, "not a constant expression of type : (0->1)", exp);
00677         return 1;
00678     } else {
00679         Tree lsignals = boxPropagateSig(nil, diagram , makeSigInputList(numInputs) );
00680         Tree val = simplify(hd(lsignals));
00681         return tree2float(val);
00682     }
00683 }

static int eval2int ( Tree  exp,
Tree  visited,
Tree  localValEnv 
) [static]

Eval a block diagram to an int.

Eval a block diagram that represent an integer constant. This function first eval a block diagram to its normal form, then check it represent a numerical value (a block diagram of type : 0->1) then do a symbolic propagation and try to convert the resulting signal to an int.

Parameters:
exp the expression to evaluate
globalDefEnv the global environment
visited list of visited definition to detect recursive definitions
localValEnv the local environment
Returns:
a block diagram in normal form

Definition at line 699 of file eval.cpp.

References getBoxType().

Referenced by realeval().

00700 {
00701     Tree diagram = eval(exp, visited, localValEnv);
00702     int numInputs, numOutputs;
00703     getBoxType(diagram, &numInputs, &numOutputs);
00704     if ( (numInputs > 0) || (numOutputs != 1) ) {
00705         evalerror (yyfilename, yylineno, "not a constant expression of type : (0->1)", exp);
00706         return 1;
00707     } else {
00708         Tree lsignals = boxPropagateSig(nil, diagram , makeSigInputList(numInputs) );
00709         Tree val = simplify(hd(lsignals));
00710         return tree2int(val);
00711     }
00712 }

static Tree evalCase ( Tree  rules,
Tree  env 
) [static]

Eval a case expression containing a list of pattern matching rules.

Creates a boxPatternMatcher containing a pm autamaton a state and a list of environments.

Parameters:
rules the list of rules
env the environment uused to evaluate the patterns and closure the rhs
Returns:
a boxPatternMatcher ready to be applied

Definition at line 1228 of file eval.cpp.

References evalRuleList(), and listn().

Referenced by realeval().

01229 {
01230     Tree pm;
01231     if (!getPMProperty(rules, env, pm)) {
01232         Automaton*  a = make_pattern_matcher(evalRuleList(rules, env));
01233         pm = boxPatternMatcher(a, 0, listn(len(rules), env), rules, nil);
01234         setPMProperty(rules, env, pm);
01235     }
01236     return pm;
01237 }       

static Tree evalIdDef ( Tree  id,
Tree  visited,
Tree  lenv 
) [static]

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

Detects recursive definitions using a set of visited IDxENV. Associates the symbol as a definition name property of the definition.

Parameters:
id the symbol ID t-o search
visited set of visited symbols (used for recursive definition detection)
lenv the environment where to search
Returns:
the evaluated definition of ID

Definition at line 1158 of file eval.cpp.

References CTree::branch(), and getDefNameProperty().

Referenced by realeval().

01159 {
01160     Tree def, name;
01161 
01162     // search the environment env for a definition of symbol id
01163     while (!isNil(lenv) && !getProperty(lenv, id, def)) {
01164         lenv = lenv->branch(0);
01165     }
01166 
01167     // check that the definition exists
01168     if (isNil(lenv)) {
01169         if (gPatternEvalMode) return boxPatternVar(id);
01170         cerr << "undefined symbol " << *id << endl;
01171         evalerror(getDefFileProp(id), getDefLineProp(id), "undefined symbol ", id);
01172         exit(1);
01173 //      return id;
01174     }
01175 
01176     // check that it is not a recursive definition
01177     Tree p = cons(id,lenv);
01178     // set the definition name property
01179     if (!getDefNameProperty(def, name)) {
01180         // if the definition has no name use the identifier
01181         stringstream s; s << boxpp(id);
01182         //XXXXXX setDefNameProperty(def, s.str());
01183     }
01184 
01185     // return the evaluated definition
01186     return eval(def, addElement(p,visited), nil);
01187 }

Tree evalprocess ( Tree  eqlist  ) 

Eval "process" from a list of definitions.

Eval the definition of 'process'.

Strict evaluation of a block diagram expression by applying beta reduction.

Parameters:
eqlist a list of faust defintions forming the the global environment
Returns:
the process block diagram in normal form

Definition at line 99 of file eval.cpp.

References pushMultiClosureDefs().

00100 {
00101     return a2sb(eval(boxIdent("process"), nil, pushMultiClosureDefs(eqlist, nil, nil)));
00102 }

bool getDefNameProperty ( Tree  t,
Tree id 
)

Indicates the identifier (if any) the expression was a definition of.

Eval the definition of 'process' in the environment passed as argument

Parameters:
t the expression
id reference to the identifier
Returns:
true if the expression t was a definition of id

Definition at line 227 of file eval.cpp.

Referenced by applyList(), evalIdDef(), generateDiagramSchema(), generateInputSlotSchema(), generateInsideSchema(), generateOutputSlotSchema(), legalFileName(), real_a2sb(), and writeSchemaFile().

00228 {
00229     //cerr << "getDefNameProperty of : " << t << endl;
00230     return getProperty(t, DEFNAMEPROPERTY, id);
00231 }

bool getEvalProperty ( Tree  box,
Tree  env,
Tree value 
)

retrieve the value of box in the environment env

Parameters:
box the expression we want to retrieve the value
env the lexical environment
value the returned value if any
Returns:
true if a value already exist

Definition at line 281 of file eval.cpp.

00282 {
00283     return getProperty(box, tree(EVALPROPERTY,env), value);
00284 }

static Tree iteratePar ( Tree  id,
int  num,
Tree  body,
Tree  visited,
Tree  localValEnv 
) [static]

Iterate a parallel construction.

Iterate a parallel construction such that : par(i,10,E) --> E(i<-0),E(i<-1),...,E(i<-9)

Parameters:
id the formal parameter of the iteration
num the number of iterartions
body the body expression of the iteration
globalDefEnv the global environment
visited list of visited definition to detect recursive definitions
localValEnv the local environment
Returns:
a block diagram in normal form

Definition at line 809 of file eval.cpp.

References pushValueDef().

Referenced by realeval().

00810 {
00811     assert (num>0);
00812 
00813     Tree res = eval(body, visited, pushValueDef(id, tree(0), localValEnv));
00814     for (int i = 1; i < num; i++) {
00815         res = boxPar(res, eval(body, visited, pushValueDef(id, tree(i), localValEnv)));
00816     }
00817 
00818     return res;
00819 }

static Tree iterateProd ( Tree  id,
int  num,
Tree  body,
Tree  visited,
Tree  localValEnv 
) [static]

Iterate a product construction.

Iterate a product construction such that : par(i,10,E) --> E(i<-0)*E(i<-1)*...*E(i<-9)

Parameters:
id the formal parameter of the iteration
num the number of iterartions
body the body expression of the iteration
globalDefEnv the global environment
visited list of visited definition to detect recursive definitions
localValEnv the local environment
Returns:
a block diagram in normal form

Definition at line 891 of file eval.cpp.

References pushValueDef().

Referenced by realeval().

00892 {
00893     assert (num>0);
00894 
00895     Tree res = eval(body, visited, pushValueDef(id, tree(0), localValEnv));
00896 
00897     for (int i = 1; i < num; i++) {
00898         res = boxSeq(boxPar(res, eval(body, visited, pushValueDef(id, tree(i), localValEnv))),boxPrim2(sigMul)) ;
00899     }
00900 
00901     return res;
00902 }

static Tree iterateSeq ( Tree  id,
int  num,
Tree  body,
Tree  visited,
Tree  localValEnv 
) [static]

Iterate a sequential construction.

Iterate a sequential construction such that : seq(i,10,E) --> E(i<-0):E(i<-1):...:E(i<-9)

Parameters:
id the formal parameter of the iteration
num the number of iterartions
body the body expression of the iteration
globalDefEnv the global environment
visited list of visited definition to detect recursive definitions
Returns:
a block diagram in normal form

Definition at line 835 of file eval.cpp.

References pushValueDef().

Referenced by realeval().

00836 {
00837     assert (num>0);
00838 
00839     Tree res = eval(body, visited, pushValueDef(id, tree(0), localValEnv));
00840 
00841     for (int i = 1; i < num; i++) {
00842         res = boxSeq(res, eval(body, visited, pushValueDef(id, tree(i), localValEnv)));
00843     }
00844 
00845     return res;
00846 }

static Tree iterateSum ( Tree  id,
int  num,
Tree  body,
Tree  visited,
Tree  localValEnv 
) [static]

Iterate an addition construction.

Iterate an addition construction such that : par(i,10,E) --> E(i<-0)+E(i<-1)+...+E(i<-9)

Parameters:
id the formal parameter of the iteration
num the number of iterartions
body the body expression of the iteration
globalDefEnv the global environment
visited list of visited definition to detect recursive definitions
localValEnv the local environment
Returns:
a block diagram in normal form

Definition at line 863 of file eval.cpp.

References pushValueDef().

Referenced by realeval().

00864 {
00865     assert (num>0);
00866 
00867     Tree res = eval(body, visited, pushValueDef(id, tree(0), localValEnv));
00868 
00869     for (int i = 1; i < num; i++) {
00870         res = boxSeq(boxPar(res, eval(body, visited, pushValueDef(id, tree(i), localValEnv))),boxPrim2(sigAdd)) ;
00871     }
00872 
00873     return res;
00874 }

static Tree larg2par ( Tree  larg  )  [static]

Transform a list of expressions in a parallel construction.

Parameters:
larg list of expressions
Returns:
parallel construction

Definition at line 1026 of file eval.cpp.

Referenced by applyList().

01027 {
01028     if (isNil(larg)) {
01029         evalerror(yyfilename, -1, "empty list of arguments", larg);
01030         exit(1);
01031     }
01032     if (isNil(tl(larg))) {
01033         return hd(larg);
01034     }
01035     return boxPar(hd(larg), larg2par(tl(larg)));
01036 }

static loopDetector LD ( 1024  ,
 
) [static]

Eval a block diagram expression.

Wrap the realeval function in order to propagate the name property

Parameters:
exp the expression to evaluate
visited list of visited definition to detect recursive definitions
localValEnv the local environment
Returns:
a block diagram in normal form

static Tree listn ( int  n,
Tree  e 
) [static]

Creates a list of n elements.

Parameters:
n number of elements
e element to be repeated
Returns:
[e e e ...] n times

Definition at line 1197 of file eval.cpp.

Referenced by evalCase().

01198 {
01199     return (n<= 0) ? nil : cons(e, listn(n-1,e));
01200 }

static Tree pushMultiClosureDefs ( Tree  ldefs,
Tree  visited,
Tree  lenv 
) [static]

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 1111 of file eval.cpp.

References addLayerDef(), and pushNewLayer().

Referenced by evalprocess(), and realeval().

01112 {
01113     Tree lenv2 = pushNewLayer(lenv);
01114     while (!isNil(ldefs)) {
01115         Tree def = hd(ldefs);
01116         Tree id = hd(def);
01117         Tree rhs= tl(def);
01118         Tree cl = closure(tl(def),nil,visited,lenv2);
01119         stringstream s; s << boxpp(id);
01120         if (!isBoxCase(rhs)) setDefNameProperty(cl,s.str());
01121         addLayerDef( id, cl, lenv2 );
01122         ldefs = tl(ldefs);
01123     }
01124     return lenv2;
01125 }

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 1058 of file eval.cpp.

References unique().

Referenced by pushMultiClosureDefs(), and pushValueDef().

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

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 1096 of file eval.cpp.

References addLayerDef(), and pushNewLayer().

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

01097 {
01098     Tree lenv2 = pushNewLayer(lenv);
01099     addLayerDef(id, def, lenv2);
01100     return lenv2;
01101 }

static Tree real_a2sb ( Tree  exp  )  [static]

Transform unused (unapplied) closures into symbolic boxes.

Parameters:
exp the expression to transform
Returns:
an expression where abstractions have been replaced by symbolic boxes

Definition at line 129 of file eval.cpp.

References applyList(), CTree::arity(), CTree::branch(), getDefNameProperty(), CTree::make(), name(), CTree::node(), and pushValueDef().

00130 {
00131     Tree abstr, visited, unusedEnv, localValEnv, var, name, body;
00132 
00133     if (isClosure(exp, abstr, unusedEnv, visited, localValEnv)) {
00134 
00135         if (isBoxIdent(abstr)) {
00136             // special case introduced with access and components
00137             Tree result = a2sb(eval(abstr, visited, localValEnv));
00138 
00139             // propagate definition name property when needed
00140             if (getDefNameProperty(exp, name))  setDefNameProperty(result, name);
00141             return result;
00142 
00143         } else if (isBoxAbstr(abstr, var, body)) {
00144             // Here we have remaining abstraction that we will try to 
00145             // transform in a symbolic box by applying it to a slot
00146 
00147             Tree slot = boxSlot(++gBoxSlotNumber); 
00148             stringstream s; s << boxpp(var);
00149             setDefNameProperty(slot, s.str() ); // ajout YO
00150             
00151             // Apply the abstraction to the slot
00152             Tree result = boxSymbolic(slot, a2sb(eval(body, visited, pushValueDef(var, slot, localValEnv))));
00153 
00154             // propagate definition name property when needed
00155             if (getDefNameProperty(exp, name)) setDefNameProperty(result, name);
00156             return result;
00157     
00158         } else {
00159             evalerror(yyfilename, -1, " a2sb : internal error : not an abstraction inside closure ", exp);
00160             exit(1);
00161         }
00162         
00163     } else if (isBoxPatternMatcher(exp)) {
00164         // Here we have remaining PM rules that we will try to 
00165         // transform in a symbolic box by applying it to a slot
00166         
00167         Tree slot = boxSlot(++gBoxSlotNumber);          
00168         stringstream s; s << "PM" << gBoxSlotNumber;
00169         setDefNameProperty(slot, s.str() ); 
00170         
00171         // apply the PM rules to the slot and transfoms the result in a symbolic box
00172         Tree result = boxSymbolic(slot, a2sb(applyList(exp, cons(slot,nil))));
00173 
00174         // propagate definition name property when needed
00175         if (getDefNameProperty(exp, name)) setDefNameProperty(result, name);
00176         return result;
00177 
00178     } else {
00179         // it is a constructor : transform each branches
00180         Tree B[4];
00181         for (int i = 0; i < exp->arity(); i++) {
00182             B[i] = a2sb(exp->branch(i));
00183         }
00184         return replaceBoxNumeric(CTree::make(exp->node(), exp->arity(), B));
00185     }
00186 }

static Tree realeval ( Tree  exp,
Tree  visited,
Tree  localValEnv 
) [static]

Eval a block diagram expression.

Strict evaluation of a block diagram expression by applying beta reduction.

Parameters:
exp the expression to evaluate
visited list of visited definition to detect recursive definitions
localValEnv the local environment
Returns:
a block diagram in normal form

Definition at line 317 of file eval.cpp.

References applyList(), eval2float(), eval2int(), evalCase(), evalIdDef(), getUserData(), iteratePar(), iterateProd(), iterateSeq(), iterateSum(), pushMultiClosureDefs(), and revEvalList().

00318 {
00319     //Tree  def;
00320     Tree    fun;
00321     Tree    arg;
00322     Tree    var, num, body, ldef;
00323     Tree    label;
00324     Tree    cur, lo, hi, step;
00325     Tree    e1, e2, exp2, notused, visited2, lenv2;
00326     Tree    rules;
00327     Tree    id;
00328 
00329     //cerr << "EVAL " << *exp << " (visited : " << *visited << ")" << endl;
00330     //cerr << "REALEVAL of " << boxpp(exp) << endl;
00331     
00332     xtended* xt = (xtended*) getUserData(exp);
00333 
00334 
00335     // constants
00336     //-----------
00337     
00338     if (    xt || 
00339             isBoxInt(exp) || isBoxReal(exp) || 
00340             isBoxWire(exp) || isBoxCut(exp) ||
00341             isBoxPrim0(exp) || isBoxPrim1(exp) || 
00342             isBoxPrim2(exp) || isBoxPrim3(exp) || 
00343             isBoxPrim4(exp) || isBoxPrim5(exp) ||
00344             isBoxFFun(exp) || isBoxFConst(exp) || isBoxFVar(exp) ) {
00345         return exp;
00346 
00347     // block-diagram constructors
00348     //---------------------------
00349     
00350     } else if ( isBoxSeq(exp, e1, e2) ) {
00351         return boxSeq(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));
00352 
00353     } else if ( isBoxPar(exp, e1, e2) ) {
00354         return boxPar(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));
00355 
00356     } else if ( isBoxRec(exp, e1, e2) ) {
00357         return boxRec(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));
00358 
00359     } else if ( isBoxSplit(exp, e1, e2) ) {
00360         return boxSplit(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));
00361 
00362     } else if ( isBoxMerge(exp, e1, e2) ) {
00363         return boxMerge(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));
00364         
00365     // Modules
00366     //--------
00367 
00368     } else if (isBoxAccess(exp, body, var)) {
00369         Tree val = eval(body, visited, localValEnv);
00370         if (isClosure(val, exp2, notused, visited2, lenv2)) {
00371             // it is a closure, we have an environment to access
00372             return eval(closure(var,notused,visited2,lenv2), visited, localValEnv);
00373         } else {
00374             evalerror(getDefFileProp(exp), getDefLineProp(exp), "No environment to access ", exp);
00375             exit(1);
00376         }
00377 
00378     } else if (isBoxComponent(exp, label)) {
00379         string  fname   = tree2str(label);
00380         Tree    eqlst   = gReader.expandlist(gReader.getlist(fname));
00381         Tree    res     = closure(boxIdent("process"), nil, nil, pushMultiClosureDefs(eqlst, nil, nil));
00382         setDefNameProperty(res, label);
00383         //cerr << "component is " << boxpp(res) << endl;
00384         return res;
00385 
00386 
00387     // user interface elements
00388     //------------------------
00389     
00390     } else if (isBoxButton(exp, label)) {
00391         const char* l1 = tree2str(label);
00392         const char* l2= evalLabel(l1, visited, localValEnv);
00393         //cout << "button label : " << l1 << " become " << l2 << endl;
00394         return ((l1 == l2) ? exp : boxButton(tree(l2)));
00395 
00396     } else if (isBoxCheckbox(exp, label)) {
00397         const char* l1 = tree2str(label);
00398         const char* l2= evalLabel(l1, visited, localValEnv);
00399         //cout << "check box label : " << l1 << " become " << l2 << endl;
00400         return ((l1 == l2) ? exp : boxCheckbox(tree(l2)));
00401 
00402     } else if (isBoxVSlider(exp, label, cur, lo, hi, step)) {
00403         const char* l1 = tree2str(label);
00404         const char* l2= evalLabel(l1, visited, localValEnv);
00405         return ( boxVSlider(tree(l2),
00406                     tree(eval2float(cur, visited, localValEnv)),
00407                     tree(eval2float(lo, visited, localValEnv)),
00408                     tree(eval2float(hi, visited, localValEnv)),
00409                     tree(eval2float(step, visited, localValEnv))));
00410 
00411     } else if (isBoxHSlider(exp, label, cur, lo, hi, step)) {
00412         const char* l1 = tree2str(label);
00413         const char* l2= evalLabel(l1, visited, localValEnv);
00414         return ( boxHSlider(tree(l2),
00415                     tree(eval2float(cur, visited, localValEnv)),
00416                     tree(eval2float(lo, visited, localValEnv)),
00417                     tree(eval2float(hi, visited, localValEnv)),
00418                     tree(eval2float(step, visited, localValEnv))));
00419 
00420     } else if (isBoxNumEntry(exp, label, cur, lo, hi, step)) {
00421         const char* l1 = tree2str(label);
00422         const char* l2= evalLabel(l1, visited, localValEnv);
00423         return (boxNumEntry(tree(l2),
00424                     tree(eval2float(cur, visited, localValEnv)),
00425                     tree(eval2float(lo, visited, localValEnv)),
00426                     tree(eval2float(hi, visited, localValEnv)),
00427                     tree(eval2float(step, visited, localValEnv))));
00428 
00429     } else if (isBoxVGroup(exp, label, arg)) {
00430         const char* l1 = tree2str(label);
00431         const char* l2= evalLabel(l1, visited, localValEnv);
00432         return boxVGroup(tree(l2),  eval(arg, visited, localValEnv) );
00433 
00434     } else if (isBoxHGroup(exp, label, arg)) {
00435         const char* l1 = tree2str(label);
00436         const char* l2= evalLabel(l1, visited, localValEnv);
00437         return boxHGroup(tree(l2),  eval(arg, visited, localValEnv) );
00438 
00439     } else if (isBoxTGroup(exp, label, arg)) {
00440         const char* l1 = tree2str(label);
00441         const char* l2= evalLabel(l1, visited, localValEnv);
00442         return boxTGroup(tree(l2),  eval(arg, visited, localValEnv) );
00443 
00444     } else if (isBoxHBargraph(exp, label, lo, hi)) {
00445         const char* l1 = tree2str(label);
00446         const char* l2= evalLabel(l1, visited, localValEnv);
00447         return boxHBargraph(tree(l2),
00448                     tree(eval2float(lo, visited, localValEnv)),
00449                     tree(eval2float(hi, visited, localValEnv)));
00450 
00451     } else if (isBoxVBargraph(exp, label, lo, hi)) {
00452         const char* l1 = tree2str(label);
00453         const char* l2= evalLabel(l1, visited, localValEnv);
00454         return boxVBargraph(tree(l2),
00455                     tree(eval2float(lo, visited, localValEnv)),
00456                     tree(eval2float(hi, visited, localValEnv)));
00457 
00458     // lambda calculus
00459     //----------------
00460         
00461     } else if (isBoxIdent(exp)) {
00462         return evalIdDef(exp, visited, localValEnv);
00463 
00464     } else if (isBoxWithLocalDef(exp, body, ldef)) {
00465         return eval(body, visited, pushMultiClosureDefs(ldef, visited, localValEnv));
00466     
00467     } else if (isBoxAppl(exp, fun, arg)) {
00468         return applyList(   eval(fun, visited, localValEnv),
00469                             revEvalList(arg, visited, localValEnv) );
00470 
00471     } else if (isBoxAbstr(exp)) {
00472         // it is an abstraction : return a closure
00473         return closure(exp, nil, visited, localValEnv);
00474 
00475     } else if (isClosure(exp, exp2, notused, visited2, lenv2)) {
00476 
00477         if (isBoxAbstr(exp2)) {
00478             // a 'real' closure
00479             return closure(exp2, nil, setUnion(visited,visited2), lenv2);
00480         } else {
00481             // it was a suspended evaluation
00482             return eval(exp2, setUnion(visited,visited2), lenv2);
00483         }
00484 
00485     // Algorithmic constructions
00486     //--------------------------
00487     
00488     } else if (isBoxIPar(exp, var, num, body)) {
00489         int n = eval2int(num, visited, localValEnv);
00490         return iteratePar(var, n, body, visited, localValEnv);
00491 
00492     } else if (isBoxISeq(exp, var, num, body)) {
00493         int n = eval2int(num, visited, localValEnv);
00494         return iterateSeq(var, n, body, visited, localValEnv);
00495 
00496     } else if (isBoxISum(exp, var, num, body)) {
00497         int n = eval2int(num, visited, localValEnv);
00498         return iterateSum(var, n, body, visited, localValEnv);
00499 
00500     } else if (isBoxIProd(exp, var, num, body)) {
00501         int n = eval2int(num, visited, localValEnv);
00502         return iterateProd(var, n, body, visited, localValEnv);
00503         
00504     } else if (isBoxSlot(exp))      { 
00505         return exp; 
00506     
00507     } else if (isBoxSymbolic(exp))  {
00508      
00509         return exp;
00510     
00511 
00512     // Pattern matching extension
00513     //---------------------------
00514     
00515     } else if (isBoxCase(exp, rules)) {
00516         return evalCase(rules, localValEnv);
00517 
00518     } else if (isBoxPatternVar(exp, id)) {
00519         return exp;
00520         //return evalIdDef(id, visited, localValEnv);
00521 
00522     } else if (isBoxPatternMatcher(exp)) {
00523         return exp;
00524 
00525     } else {
00526         cout << "ERROR : EVAL don't intercept : " << *exp << endl;
00527         exit(1);
00528     }
00529 }

static Tree revEvalList ( Tree  lexp,
Tree  visited,
Tree  localValEnv 
) [static]

Eval a list of expression in reverse order.

Eval a list of expressions returning the list of results in reverse order.

Parameters:
lexp list of expressions to evaluate
globalDefEnv the global environment
visited list of visited definition to detect recursive definitions
localValEnv the local environment
Returns:
list of evaluated expressions in reverse order

Definition at line 1008 of file eval.cpp.

Referenced by realeval().

01009 {
01010     Tree result = nil;
01011     while (!isNil(lexp)) {
01012         result = cons(eval(hd(lexp), visited, localValEnv), result);
01013         lexp = tl(lexp);
01014     }
01015     return result;
01016 }

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 1136 of file eval.cpp.

References CTree::branch().

01137 {
01138     // search the environment until a definition is found
01139     // or nil (the empty environment) is reached
01140     while (!isNil(lenv) && !getProperty(lenv, id, def)) {
01141         lenv = lenv->branch(0);
01142     }
01143     return !isNil(lenv);
01144 }

void setEvalProperty ( Tree  box,
Tree  env,
Tree  value 
)

set the type annotation of sig

Parameters:
sig the signal we want to type
t the type of the signal

Definition at line 267 of file eval.cpp.

00268 {
00269     //cerr << "setSigType(" << *sig << ", " << t << ")" << endl;
00270     setProperty(box, tree(EVALPROPERTY,env), value);
00271 }

Tree simplifyPattern ( Tree  value  ) 

Simplify a block-diagram pattern by computing its numerical sub-expressions.

Parameters:
pattern an evaluated block-diagram
Returns:
a simplified pattern

Definition at line 598 of file eval.cpp.

00599 {
00600     Tree num;
00601     if (!getNumericProperty(value,num)) {
00602         if (!isBoxNumeric(value,num)) {
00603             num = value;
00604         }
00605         setNumericProperty(value,num);
00606     }
00607     return num;
00608 }


Variable Documentation

Tree DEFNAMEPROPERTY = tree(symbol("DEFNAMEPROPERTY"))

Definition name property : a property to keep track of the definition name of an expression.

Whenever an identifier is evaluated, it is attached as a property of its definitionObviously there is no perfect solution since a same definition quand be given to different names.

Definition at line 194 of file eval.cpp.


Generated on Sun Mar 22 16:25:04 2009 for FAUST compiler by  doxygen 1.5.7.1