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. |
Implementation of the Block diagram evaluator.
A strict lambda-calculus evaluator for block diagram expressions.
Definition in file eval.cpp.
Add a definition (as a property) to the current top level layer.
Check and warn for multiple definitions.
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 }
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
fun | the function to apply | |
larg | the list of arguments |
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 }
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.
exp | the expression to evaluate | |
globalDefEnv | the global environment | |
visited | list of visited definition to detect recursive definitions | |
localValEnv | the local environment |
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 }
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.
exp | the expression to evaluate | |
globalDefEnv | the global environment | |
visited | list of visited definition to detect recursive definitions | |
localValEnv | the local environment |
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 }
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.
rules | the list of rules | |
env | the environment uused to evaluate the patterns and closure the rhs |
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 }
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.
id | the symbol ID t-o search | |
visited | set of visited symbols (used for recursive definition detection) | |
lenv | the environment where to search |
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 }
Eval "process" from a list of definitions.
Eval the definition of 'process'.
Strict evaluation of a block diagram expression by applying beta reduction.
eqlist | a list of faust defintions forming the the global environment |
Definition at line 99 of file eval.cpp.
References pushMultiClosureDefs().
00100 { 00101 return a2sb(eval(boxIdent("process"), nil, pushMultiClosureDefs(eqlist, nil, nil))); 00102 }
Indicates the identifier (if any) the expression was a definition of.
Eval the definition of 'process' in the environment passed as argument
t | the expression | |
id | reference to the identifier |
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 }
retrieve the value of box in the environment env
box | the expression we want to retrieve the value | |
env | the lexical environment | |
value | the returned value if any |
Iterate a parallel construction.
Iterate a parallel construction such that : par(i,10,E) --> E(i<-0),E(i<-1),...,E(i<-9)
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 |
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 }
Iterate a product construction.
Iterate a product construction such that : par(i,10,E) --> E(i<-0)*E(i<-1)*...*E(i<-9)
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 |
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 }
Iterate a sequential construction.
Iterate a sequential construction such that : seq(i,10,E) --> E(i<-0):E(i<-1):...:E(i<-9)
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 |
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 }
Iterate an addition construction.
Iterate an addition construction such that : par(i,10,E) --> E(i<-0)+E(i<-1)+...+E(i<-9)
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 |
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 }
Transform a list of expressions in a parallel construction.
larg | list of expressions |
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 | , | |
1 | ||||
) | [static] |
Eval a block diagram expression.
Wrap the realeval function in order to propagate the name property
exp | the expression to evaluate | |
visited | list of visited definition to detect recursive definitions | |
localValEnv | the local environment |
Creates a list of n elements.
n | number of elements | |
e | element to be repeated |
Definition at line 1197 of file eval.cpp.
Referenced by evalCase().
01198 { 01199 return (n<= 0) ? nil : cons(e, listn(n-1,e)); 01200 }
Push a new layer with multiple definitions creating the appropriate closures.
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 |
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 }
Push a new (unique) empty layer (where multiple definitions can be stored) on top of an existing environment.
lenv | the old 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 }
Push a new layer and add a single definition.
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 |
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 }
Transform unused (unapplied) closures into symbolic boxes.
exp | the expression to transform |
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 }
Eval a block diagram expression.
Strict evaluation of a block diagram expression by applying beta reduction.
exp | the expression to evaluate | |
visited | list of visited definition to detect recursive definitions | |
localValEnv | the local environment |
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 }
Eval a list of expression in reverse order.
Eval a list of expressions returning the list of results in reverse order.
lexp | list of expressions to evaluate | |
globalDefEnv | the global environment | |
visited | list of visited definition to detect recursive definitions | |
localValEnv | the local environment |
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 }
Search the environment for the definition of a symbol ID and return it.
id | the symbol ID to search | |
def | where to store the definition if any | |
lenv | the environment |
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 }
Simplify a block-diagram pattern by computing its numerical sub-expressions.
pattern | an evaluated block-diagram |
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 }
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.