FAUST compiler  0.9.9.6b8
eval.cpp
Go to the documentation of this file.
1 /************************************************************************
2  ************************************************************************
3  FAUST compiler
4  Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
5  ---------------------------------------------------------------------
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  ************************************************************************
20  ************************************************************************/
21  #define TRACE
22 
32 #include "eval.hh"
33 #include <stdio.h>
34 #include "errormsg.hh"
35 #include "ppbox.hh"
36 #include "simplify.hh"
37 #include "propagate.hh"
38 #include "patternmatcher.hh"
39 #include "signals.hh"
40 #include "xtended.hh"
41 #include "loopDetector.hh"
42 #include "property.hh"
43 #include "names.hh"
44 #include "compatibility.hh"
45 #include <assert.h>
46 
47 extern SourceReader gReader;
48 extern int gMaxNameSize;
49 extern bool gSimpleNames;
50 extern bool gSimplifyDiagrams;
51 // History
52 // 23/05/2005 : New environment management
53 
54 
55 //-------------- prototypes ---------------------------------------------------------
56 static Tree a2sb(Tree exp);
57 static Tree eval (Tree exp, Tree visited, Tree localValEnv);
58 static Tree realeval (Tree exp, Tree visited, Tree localValEnv);
59 static Tree revEvalList (Tree lexp, Tree visited, Tree localValEnv);
60 static Tree applyList (Tree fun, Tree larg);
61 static Tree iteratePar (Tree var, int num, Tree body, Tree visited, Tree localValEnv);
62 static Tree iterateSeq (Tree id, int num, Tree body, Tree visited, Tree localValEnv);
63 static Tree iterateSum (Tree id, int num, Tree body, Tree visited, Tree localValEnv);
64 static Tree iterateProd (Tree id, int num, Tree body, Tree visited, Tree localValEnv);
65 static Tree larg2par (Tree larg);
66 static int eval2int (Tree exp, Tree visited, Tree localValEnv);
67 static double eval2double (Tree exp, Tree visited, Tree localValEnv);
68 static const char * evalLabel (const char* l, Tree visited, Tree localValEnv);
69 
70 static Tree evalIdDef(Tree id, Tree visited, Tree env);
71 
72 
73 
74 static Tree evalCase(Tree rules, Tree env);
75 static Tree evalRuleList(Tree rules, Tree env);
76 static Tree evalRule(Tree rule, Tree env);
77 static Tree evalPatternList(Tree patterns, Tree env);
78 static Tree evalPattern(Tree pattern, Tree env);
79 
80 static Tree patternSimplification (Tree pattern);
81 static bool isBoxNumeric (Tree in, Tree& out);
82 
83 static Tree vec2list(const vector<Tree>& v);
84 static void list2vec(Tree l, vector<Tree>& v);
85 static Tree listn (int n, Tree e);
86 
87 static Tree boxSimplification(Tree box);
88 
89 // Public Interface
90 //----------------------
91 
92 
101 {
102  Tree b = a2sb(eval(boxIdent("process"), nil, pushMultiClosureDefs(eqlist, nil, nil)));
103 
104  if (gSimplifyDiagrams) {
105  b = boxSimplification(b);
106  }
107 
108  return b;
109 }
110 
111 
112 /* Eval a documentation expression. */
113 
114 Tree evaldocexpr (Tree docexpr, Tree eqlist)
115 {
116  return a2sb(eval(docexpr, nil, pushMultiClosureDefs(eqlist, nil, nil)));
117 }
118 
119 
120 
121 // Private Implementation
122 //------------------------
123 
132 
133 static Tree real_a2sb(Tree exp);
134 
135 static Tree a2sb(Tree exp)
136 {
137  Tree result;
138  Tree id;
139 
140  if (gSymbolicBoxProperty.get(exp, result)) {
141  return result;
142  }
143 
144  result = real_a2sb(exp);
145  if (result != exp && getDefNameProperty(exp, id)) {
146  setDefNameProperty(result, id); // propagate definition name property when needed
147  }
148  gSymbolicBoxProperty.set(exp, result);
149  return result;
150 }
151 
152 static int gBoxSlotNumber = 0;
153 
154 static Tree real_a2sb(Tree exp)
155 {
156  Tree abstr, visited, unusedEnv, localValEnv, var, name, body;
157 
158  if (isClosure(exp, abstr, unusedEnv, visited, localValEnv)) {
159 
160  if (isBoxIdent(abstr)) {
161  // special case introduced with access and components
162  Tree result = a2sb(eval(abstr, visited, localValEnv));
163 
164  // propagate definition name property when needed
165  if (getDefNameProperty(exp, name)) setDefNameProperty(result, name);
166  return result;
167 
168  } else if (isBoxAbstr(abstr, var, body)) {
169  // Here we have remaining abstraction that we will try to
170  // transform in a symbolic box by applying it to a slot
171 
172  Tree slot = boxSlot(++gBoxSlotNumber);
173  stringstream s; s << boxpp(var);
174  setDefNameProperty(slot, s.str() ); // ajout YO
175 
176  // Apply the abstraction to the slot
177  Tree result = boxSymbolic(slot, a2sb(eval(body, visited, pushValueDef(var, slot, localValEnv))));
178 
179  // propagate definition name property when needed
180  if (getDefNameProperty(exp, name)) setDefNameProperty(result, name);
181  return result;
182 
183  } else if (isBoxEnvironment(abstr)) {
184  return abstr;
185 
186  } else {
187  evalerror(yyfilename, -1, " a2sb : internal error : not an abstraction inside closure ", exp);
188  exit(1);
189  }
190 
191  } else if (isBoxPatternMatcher(exp)) {
192  // Here we have remaining PM rules that we will try to
193  // transform in a symbolic box by applying it to a slot
194 
195  Tree slot = boxSlot(++gBoxSlotNumber);
196  stringstream s; s << "PM" << gBoxSlotNumber;
197  setDefNameProperty(slot, s.str() );
198 
199  // apply the PM rules to the slot and transfoms the result in a symbolic box
200  Tree result = boxSymbolic(slot, a2sb(applyList(exp, cons(slot,nil))));
201 
202  // propagate definition name property when needed
203  if (getDefNameProperty(exp, name)) setDefNameProperty(result, name);
204  return result;
205 
206  } else if (isBoxWaveform(exp)) {
207  // A waveform is always in Normal Form, nothing to evaluate
208  return exp;
209 
210  } else {
211  // it is a constructor : transform each branches
212  unsigned int ar = exp->arity();
213  tvec B(ar);
214  bool modified = false;
215  for (unsigned int i = 0; i < ar; i++) {
216  Tree b = exp->branch(i);
217  Tree m = a2sb(b);
218  B[i] = m;
219  if (b != m) modified=true;
220  }
221  Tree r = (modified) ? CTree::make(exp->node(), B) : exp;
222  return r;
223  }
224 }
225 
226 static bool autoName(Tree exp , Tree& id)
227 {
228  stringstream s; s << boxpp(exp);
229  id = tree(s.str().c_str());
230  return true;
231 }
232 
233 bool getArgName(Tree t, Tree& id)
234 {
235  //return getDefNameProperty(t, id) || autoName(t, id) ;
236  return autoName(t, id) ;
237 }
238 
239 
240 
250 static loopDetector LD(1024, 512);
251 
252 
253 static Node EVALPROPERTY(symbol("EvalProperty"));
254 
261 void setEvalProperty(Tree box, Tree env, Tree value)
262 {
263  setProperty(box, tree(EVALPROPERTY,env), value);
264 }
265 
266 
274 bool getEvalProperty(Tree box, Tree env, Tree& value)
275 {
276  return getProperty(box, tree(EVALPROPERTY,env), value);
277 }
278 
279 
280 static Tree eval (Tree exp, Tree visited, Tree localValEnv)
281 {
282  Tree id;
283  Tree result;
284 
285  if (!getEvalProperty(exp, localValEnv, result)) {
286  LD.detect(cons(exp,localValEnv));
287  //cerr << "ENTER eval("<< *exp << ") with env " << *localValEnv << endl;
288  result = realeval(exp, visited, localValEnv);
289  setEvalProperty(exp, localValEnv, result);
290  //cerr << "EXIT eval(" << *exp << ") IS " << *result << " with env " << *localValEnv << endl;
291  if (getDefNameProperty(exp, id)) {
292  setDefNameProperty(result, id); // propagate definition name property
293  }
294  }
295  return result;
296 }
297 
308 static Tree realeval (Tree exp, Tree visited, Tree localValEnv)
309 {
310  //Tree def;
311  Tree fun;
312  Tree arg;
313  Tree var, num, body, ldef;
314  Tree label;
315  Tree cur, lo, hi, step;
316  Tree e1, e2, exp2, notused, visited2, lenv2;
317  Tree rules;
318  Tree id;
319 
320  //cerr << "EVAL " << *exp << " (visited : " << *visited << ")" << endl;
321  //cerr << "REALEVAL of " << *exp << endl;
322 
323  xtended* xt = (xtended*) getUserData(exp);
324 
325 
326  // constants
327  //-----------
328 
329  if ( xt ||
330  isBoxInt(exp) || isBoxReal(exp) ||
331  isBoxWire(exp) || isBoxCut(exp) ||
332  isBoxPrim0(exp) || isBoxPrim1(exp) ||
333  isBoxPrim2(exp) || isBoxPrim3(exp) ||
334  isBoxPrim4(exp) || isBoxPrim5(exp) ||
335  isBoxFFun(exp) || isBoxFConst(exp) || isBoxFVar(exp) ||
336  isBoxWaveform(exp)) {
337  return exp;
338 
339  // block-diagram constructors
340  //---------------------------
341 
342  } else if ( isBoxSeq(exp, e1, e2) ) {
343  return boxSeq(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));
344 
345  } else if ( isBoxPar(exp, e1, e2) ) {
346  return boxPar(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));
347 
348  } else if ( isBoxRec(exp, e1, e2) ) {
349  return boxRec(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));
350 
351  } else if ( isBoxSplit(exp, e1, e2) ) {
352  return boxSplit(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));
353 
354  } else if ( isBoxMerge(exp, e1, e2) ) {
355  return boxMerge(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));
356 
357  // Modules
358  //--------
359 
360  } else if (isBoxAccess(exp, body, var)) {
361  Tree val = eval(body, visited, localValEnv);
362  if (isClosure(val, exp2, notused, visited2, lenv2)) {
363  // it is a closure, we have an environment to access
364  return eval(closure(var,notused,visited2,lenv2), visited, localValEnv);
365  } else {
366  evalerror(getDefFileProp(exp), getDefLineProp(exp), "No environment to access ", exp);
367  exit(1);
368  }
369 
371 
372  } else if (isBoxModifLocalDef(exp, body, ldef)) {
373  Tree val = eval(body, visited, localValEnv);
374  if (isClosure(val, exp2, notused, visited2, lenv2)) {
375  // we rebuild the closure using a copy of the original environment
376  // modified with some new definitions
377  Tree lenv3 = copyEnvReplaceDefs(lenv2, ldef, visited2, localValEnv);
378  return eval(closure(exp2,notused,visited2,lenv3), visited, localValEnv);
379  } else {
380 
381  evalerror(getDefFileProp(exp), getDefLineProp(exp), "not a closure ", val);
382  evalerror(getDefFileProp(exp), getDefLineProp(exp), "No environment to access ", exp);
383  exit(1);
384  }
385 
387 
388  } else if (isBoxComponent(exp, label)) {
389  string fname = tree2str(label);
390  Tree eqlst = gReader.expandlist(gReader.getlist(fname));
391  Tree res = closure(boxIdent("process"), nil, nil, pushMultiClosureDefs(eqlst, nil, nil));
392  setDefNameProperty(res, label);
393  //cerr << "component is " << boxpp(res) << endl;
394  return res;
395 
396  } else if (isBoxLibrary(exp, label)) {
397  string fname = tree2str(label);
398  Tree eqlst = gReader.expandlist(gReader.getlist(fname));
400  setDefNameProperty(res, label);
401  //cerr << "component is " << boxpp(res) << endl;
402  return res;
403 
404 
405  // user interface elements
406  //------------------------
407 
408  } else if (isBoxButton(exp, label)) {
409  const char* l1 = tree2str(label);
410  const char* l2= evalLabel(l1, visited, localValEnv);
411  //cout << "button label : " << l1 << " become " << l2 << endl;
412  return ((l1 == l2) ? exp : boxButton(tree(l2)));
413 
414  } else if (isBoxCheckbox(exp, label)) {
415  const char* l1 = tree2str(label);
416  const char* l2= evalLabel(l1, visited, localValEnv);
417  //cout << "check box label : " << l1 << " become " << l2 << endl;
418  return ((l1 == l2) ? exp : boxCheckbox(tree(l2)));
419 
420  } else if (isBoxVSlider(exp, label, cur, lo, hi, step)) {
421  const char* l1 = tree2str(label);
422  const char* l2= evalLabel(l1, visited, localValEnv);
423  return ( boxVSlider(tree(l2),
424  tree(eval2double(cur, visited, localValEnv)),
425  tree(eval2double(lo, visited, localValEnv)),
426  tree(eval2double(hi, visited, localValEnv)),
427  tree(eval2double(step, visited, localValEnv))));
428 
429  } else if (isBoxHSlider(exp, label, cur, lo, hi, step)) {
430  const char* l1 = tree2str(label);
431  const char* l2= evalLabel(l1, visited, localValEnv);
432  return ( boxHSlider(tree(l2),
433  tree(eval2double(cur, visited, localValEnv)),
434  tree(eval2double(lo, visited, localValEnv)),
435  tree(eval2double(hi, visited, localValEnv)),
436  tree(eval2double(step, visited, localValEnv))));
437 
438  } else if (isBoxNumEntry(exp, label, cur, lo, hi, step)) {
439  const char* l1 = tree2str(label);
440  const char* l2= evalLabel(l1, visited, localValEnv);
441  return (boxNumEntry(tree(l2),
442  tree(eval2double(cur, visited, localValEnv)),
443  tree(eval2double(lo, visited, localValEnv)),
444  tree(eval2double(hi, visited, localValEnv)),
445  tree(eval2double(step, visited, localValEnv))));
446 
447  } else if (isBoxVGroup(exp, label, arg)) {
448  const char* l1 = tree2str(label);
449  const char* l2= evalLabel(l1, visited, localValEnv);
450  return boxVGroup(tree(l2), eval(arg, visited, localValEnv) );
451 
452  } else if (isBoxHGroup(exp, label, arg)) {
453  const char* l1 = tree2str(label);
454  const char* l2= evalLabel(l1, visited, localValEnv);
455  return boxHGroup(tree(l2), eval(arg, visited, localValEnv) );
456 
457  } else if (isBoxTGroup(exp, label, arg)) {
458  const char* l1 = tree2str(label);
459  const char* l2= evalLabel(l1, visited, localValEnv);
460  return boxTGroup(tree(l2), eval(arg, visited, localValEnv) );
461 
462  } else if (isBoxHBargraph(exp, label, lo, hi)) {
463  const char* l1 = tree2str(label);
464  const char* l2= evalLabel(l1, visited, localValEnv);
465  return boxHBargraph(tree(l2),
466  tree(eval2double(lo, visited, localValEnv)),
467  tree(eval2double(hi, visited, localValEnv)));
468 
469  } else if (isBoxVBargraph(exp, label, lo, hi)) {
470  const char* l1 = tree2str(label);
471  const char* l2= evalLabel(l1, visited, localValEnv);
472  return boxVBargraph(tree(l2),
473  tree(eval2double(lo, visited, localValEnv)),
474  tree(eval2double(hi, visited, localValEnv)));
475 
476  // lambda calculus
477  //----------------
478 
479  } else if (isBoxIdent(exp)) {
480  return evalIdDef(exp, visited, localValEnv);
481 
482  } else if (isBoxWithLocalDef(exp, body, ldef)) {
483  return eval(body, visited, pushMultiClosureDefs(ldef, visited, localValEnv));
484 
485  } else if (isBoxAppl(exp, fun, arg)) {
486  return applyList( eval(fun, visited, localValEnv),
487  revEvalList(arg, visited, localValEnv) );
488 
489  } else if (isBoxAbstr(exp)) {
490  // it is an abstraction : return a closure
491  return closure(exp, nil, visited, localValEnv);
492 
493  } else if (isBoxEnvironment(exp)) {
494  // environment : return also a closure
495  return closure(exp, nil, visited, localValEnv);
496 
497  } else if (isClosure(exp, exp2, notused, visited2, lenv2)) {
498 
499  if (isBoxAbstr(exp2)) {
500  // a 'real' closure
501  return closure(exp2, nil, setUnion(visited,visited2), lenv2);
502  } else if (isBoxEnvironment(exp2)) {
503  // a 'real' closure
504  return closure(exp2, nil, setUnion(visited,visited2), lenv2);
505  } else {
506  // it was a suspended evaluation
507  return eval(exp2, setUnion(visited,visited2), lenv2);
508  }
509 
510  // Algorithmic constructions
511  //--------------------------
512 
513  } else if (isBoxIPar(exp, var, num, body)) {
514  int n = eval2int(num, visited, localValEnv);
515  return iteratePar(var, n, body, visited, localValEnv);
516 
517  } else if (isBoxISeq(exp, var, num, body)) {
518  int n = eval2int(num, visited, localValEnv);
519  return iterateSeq(var, n, body, visited, localValEnv);
520 
521  } else if (isBoxISum(exp, var, num, body)) {
522  int n = eval2int(num, visited, localValEnv);
523  return iterateSum(var, n, body, visited, localValEnv);
524 
525  } else if (isBoxIProd(exp, var, num, body)) {
526  int n = eval2int(num, visited, localValEnv);
527  return iterateProd(var, n, body, visited, localValEnv);
528 
529  // static
530  } else if (isBoxInputs(exp, body)) {
531  int ins, outs;
532  Tree b = a2sb(eval(body, visited, localValEnv));
533  if (getBoxType (b, &ins, &outs)) {
534  return boxInt(ins);
535  } else {
536  cerr << "ERROR : can't evaluate ' : " << *exp << endl;
537  assert(false);
538  }
539 
540  } else if (isBoxOutputs(exp, body)) {
541  int ins, outs;
542  Tree b = a2sb(eval(body, visited, localValEnv));
543  if (getBoxType (b, &ins, &outs)) {
544  return boxInt(outs);
545  } else {
546  cerr << "ERROR : can't evaluate ' : " << *exp << endl;
547  assert(false);
548  }
549 
550 
551  } else if (isBoxSlot(exp)) {
552  return exp;
553 
554  } else if (isBoxSymbolic(exp)) {
555 
556  return exp;
557 
558 
559  // Pattern matching extension
560  //---------------------------
561 
562  } else if (isBoxCase(exp, rules)) {
563  return evalCase(rules, localValEnv);
564 
565  } else if (isBoxPatternVar(exp, id)) {
566  return exp;
567  //return evalIdDef(id, visited, localValEnv);
568 
569  } else if (isBoxPatternMatcher(exp)) {
570  return exp;
571 
572  } else {
573  cerr << "ERROR : EVAL don't intercept : " << *exp << endl;
574  assert(false);
575  }
576  return NULL;
577 }
578 
579 /* Deconstruct a (BDA) op pattern (YO). */
580 
581 static inline bool isBoxPatternOp(Tree box, Node& n, Tree& t1, Tree& t2)
582 {
583  if ( isBoxPar(box, t1, t2) ||
584  isBoxSeq(box, t1, t2) ||
585  isBoxSplit(box, t1, t2) ||
586  isBoxMerge(box, t1, t2) ||
587  isBoxRec(box, t1, t2) )
588  {
589  n = box->node();
590  return true;
591  } else {
592  return false;
593  }
594 }
595 
596 
597 Tree NUMERICPROPERTY = tree(symbol("NUMERICPROPERTY"));
598 
600 {
601  setProperty(t, NUMERICPROPERTY, num);
602 }
603 
605 {
606  return getProperty(t, NUMERICPROPERTY, num);
607 }
608 
615 /* uncomment for debugging output */
616 //#define DEBUG
618 {
619  Tree num;
620  if (!getNumericProperty(value,num)) {
621  if (!isBoxNumeric(value,num)) {
622  num = value;
623  }
624  setNumericProperty(value,num);
625  }
626  return num;
627 }
628 
629 
630 static bool isBoxNumeric (Tree in, Tree& out)
631 {
632  int numInputs, numOutputs;
633  double x;
634  int i;
635  Tree v;
636 
637  if (isBoxInt(in, &i) || isBoxReal(in, &x)) {
638  out = in;
639  return true;
640  } else {
641  v = a2sb(in);
642  if ( getBoxType(v, &numInputs, &numOutputs) && (numInputs == 0) && (numOutputs == 1) ) {
643  // potential numerical expression
644  Tree lsignals = boxPropagateSig(nil, v , makeSigInputList(numInputs) );
645  Tree res = simplify(hd(lsignals));
646  if (isSigReal(res, &x)) {
647  out = boxReal(x);
648  return true;
649  }
650  if (isSigInt(res, &i)) {
651  out = boxInt(i);
652  return true;
653  }
654  }
655  return false;
656  }
657 }
658 
660 {
661 
662  Node n(0);
663  Tree v, t1, t2;
664 
665  if (isBoxNumeric(pattern, v)) {
666  return v;
667  } else if (isBoxPatternOp(pattern, n, t1, t2)) {
669  } else {
670  return pattern;
671  }
672 }
673 
674 
675 
689 static double eval2double (Tree exp, Tree visited, Tree localValEnv)
690 {
691  Tree diagram = a2sb(eval(exp, visited, localValEnv)); // pour getBoxType
692  int numInputs, numOutputs;
693  getBoxType(diagram, &numInputs, &numOutputs);
694  if ( (numInputs > 0) || (numOutputs != 1) ) {
695  evalerror (yyfilename, yylineno, "not a constant expression of type : (0->1)", exp);
696  return 1;
697  } else {
698  Tree lsignals = boxPropagateSig(nil, diagram , makeSigInputList(numInputs) );
699  Tree val = simplify(hd(lsignals));
700  return tree2float(val);
701  }
702 }
703 
704 
718 static int eval2int (Tree exp, Tree visited, Tree localValEnv)
719 {
720  Tree diagram = a2sb(eval(exp, visited, localValEnv)); // pour getBoxType()
721  int numInputs, numOutputs;
722  getBoxType(diagram, &numInputs, &numOutputs);
723  if ( (numInputs > 0) || (numOutputs != 1) ) {
724  evalerror (yyfilename, yylineno, "not a constant expression of type : (0->1)", exp);
725  return 1;
726  } else {
727  Tree lsignals = boxPropagateSig(nil, diagram , makeSigInputList(numInputs) );
728  Tree val = simplify(hd(lsignals));
729  return tree2int(val);
730  }
731 }
732 
733 static bool isDigitChar(char c)
734 {
735  return (c >= '0') & (c <= '9');
736 }
737 
738 static bool isIdentChar(char c)
739 {
740  return ((c >= 'a') & (c <= 'z')) || ((c >= 'A') & (c <= 'Z')) || ((c >= '0') & (c <= '9')) || (c == '_');
741 }
742 
743 const char* Formats [] = {"%d", "%1d", "%2d", "%3d", "%4d"};
744 
745 static void writeIdentValue(std::string& dst, const std::string& format, const std::string& ident, Tree visited, Tree localValEnv)
746 {
747  int f = atoi(format.c_str());
748  int n = eval2int(boxIdent(ident.c_str()), visited, localValEnv);
749  int i = min(4,max(f,0));
750  char val[256];
751 
752  snprintf(val, 250, Formats[i], n);
753  dst += val;
754 }
755 
756 
760 static const char * evalLabel (const char* src, Tree visited, Tree localValEnv)
761 {
762  //std::cerr << "Eval Label : " << src;
763 
764  int state = 0; // current state
765  std::string dst; // label once evaluated
766  std::string ident; // current identifier
767  std::string format; // current format
768 
769  while (state != -1) {
770 
771  char c = *src++;
772 
773  if (state == 0) {
774 
775  if (c == 0) {
776  state = -1;
777  } else if (c == '%') {
778  ident = "";
779  format = "";
780  state = 1;
781  } else {
782  dst+=c;
783  state = 0;
784  }
785 
786  } else if (state == 1) {
787 
788  if (c == 0) {
789  // fin et pas d'indentifiant, abandon
790  dst += '%';
791  dst += format;
792  state = -1;
793  } else if (isDigitChar(c)) {
794  format += c;
795  state = 1;
796  } else if (isIdentChar(c)) {
797  ident += c;
798  state = 2;
799  } else {
800  // caractere de ponctuation et pas d'indentifiant, abandon
801  dst += '%';
802  dst += format;
803  src--;
804  state = 0;
805  }
806 
807  } else if (state == 2) {
808 
809  if (isIdentChar(c)) {
810  ident += c;
811  state = 2;
812  } else {
813  writeIdentValue(dst, format, ident, visited, localValEnv);
814  src--;
815  state = 0;
816  }
817 
818  } else {
819 
820  std::cerr << "internal error in evallabel : undefined state " << state << std::endl;
821  exit(1);
822  }
823  }
824 
825  const char* val = strdup(dst.c_str());
826  //std::cerr << " ===> " << val << std::endl;
827  return val;
828 }
829 
830 
831 
845 static Tree iteratePar (Tree id, int num, Tree body, Tree visited, Tree localValEnv)
846 {
847  assert (num>0);
848 
849  Tree res = eval(body, visited, pushValueDef(id, tree(num-1), localValEnv));
850  for (int i = num-2; i >= 0; i--) {
851  res = boxPar(eval(body, visited, pushValueDef(id, tree(i), localValEnv)), res);
852  }
853 
854  return res;
855 }
856 
857 
858 
871 static Tree iterateSeq (Tree id, int num, Tree body, Tree visited, Tree localValEnv)
872 {
873  assert (num>0);
874 
875  Tree res = eval(body, visited, pushValueDef(id, tree(num-1), localValEnv));
876  for (int i = num-2; i >= 0; i--) {
877  res = boxSeq(eval(body, visited, pushValueDef(id, tree(i), localValEnv)), res);
878  }
879 
880  return res;
881 }
882 
883 
884 
898 static Tree iterateSum (Tree id, int num, Tree body, Tree visited, Tree localValEnv)
899 {
900  assert (num>0);
901 
902  Tree res = eval(body, visited, pushValueDef(id, tree(0), localValEnv));
903 
904  for (int i = 1; i < num; i++) {
905  res = boxSeq(boxPar(res, eval(body, visited, pushValueDef(id, tree(i), localValEnv))),boxPrim2(sigAdd)) ;
906  }
907 
908  return res;
909 }
910 
911 
912 
926 static Tree iterateProd (Tree id, int num, Tree body, Tree visited, Tree localValEnv)
927 {
928  assert (num>0);
929 
930  Tree res = eval(body, visited, pushValueDef(id, tree(0), localValEnv));
931 
932  for (int i = 1; i < num; i++) {
933  res = boxSeq(boxPar(res, eval(body, visited, pushValueDef(id, tree(i), localValEnv))),boxPrim2(sigMul)) ;
934  }
935 
936  return res;
937 }
938 
947  #if 1
948 static bool boxlistOutputs(Tree boxlist, int* outputs)
949 {
950  int ins, outs;
951 
952  *outputs = 0;
953  while (!isNil(boxlist))
954  {
955  Tree b = a2sb(hd(boxlist)); // for getBoxType, suppose list of evaluated boxes
956  if (getBoxType(b, &ins, &outs)) {
957  *outputs += outs;
958  } else {
959  // arbitrary output arity set to 1
960  // when can't be determined
961  *outputs += 1;
962  }
963  boxlist = tl(boxlist);
964  }
965  return isNil(boxlist);
966 }
967 #else
968 static bool boxlistOutputs(Tree boxlist, int* outputs)
969 {
970  int ins, outs;
971 
972  *outputs = 0;
973  while (!isNil(boxlist) && getBoxType(hd(boxlist), &ins, &outs)) {
974  *outputs += outs;
975  boxlist = tl(boxlist);
976  }
977  return isNil(boxlist);
978 }
979 #endif
980 
984 static Tree nwires(int n)
985 {
986  Tree l = nil;
987  while (n--) { l = cons(boxWire(), l); }
988  return l;
989 }
990 
991 
1003 static Tree applyList (Tree fun, Tree larg)
1004 {
1005  Tree abstr;
1006  Tree globalDefEnv;
1007  Tree visited;
1008  Tree localValEnv;
1009  Tree envList;
1010  Tree originalRules;
1011  Tree revParamList;
1012 
1013  Tree id;
1014  Tree body;
1015 
1016  Automaton* automat;
1017  int state;
1018 
1019  prim2 p2;
1020 
1021  //cerr << "applyList (" << *fun << ", " << *larg << ")" << endl;
1022 
1023  if (isNil(larg)) return fun;
1024 
1025  if (isBoxError(fun) || isBoxError(larg)) {
1026  return boxError();
1027  }
1028 
1029  if (isBoxPatternMatcher(fun, automat, state, envList, originalRules, revParamList)) {
1030  Tree result;
1031  int state2;
1032  vector<Tree> envVect;
1033 
1034  list2vec(envList, envVect);
1035  //cerr << "applyList/apply_pattern_matcher(" << automat << "," << state << "," << *hd(larg) << ")" << endl;
1036  state2 = apply_pattern_matcher(automat, state, hd(larg), result, envVect);
1037  //cerr << "state2 = " << state2 << "; result = " << *result << endl;
1038  if (state2 >= 0 && isNil(result)) {
1039  // we need to continue the pattern matching
1040  return applyList(
1041  boxPatternMatcher(automat, state2, vec2list(envVect), originalRules, cons(hd(larg),revParamList)),
1042  tl(larg) );
1043  } else if (state2 < 0) {
1044  cerr << "ERROR : pattern matching failed, no rule of " << boxpp(boxCase(originalRules))
1045  << " matches argument list " << boxpp(reverse(cons(hd(larg), revParamList))) << endl;
1046  exit(1);
1047  } else {
1048  // Pattern Matching was succesful
1049  // the result is a closure that we need to evaluate.
1050  if (isClosure(result, body, globalDefEnv, visited, localValEnv)) {
1051  // why ??? return simplifyPattern(eval(body, nil, localValEnv));
1052  //return eval(body, nil, localValEnv);
1053  return applyList(eval(body, nil, localValEnv), tl(larg));
1054  } else {
1055  cerr << "wrong result from pattern matching (not a closure) : " << boxpp(result) << endl;
1056  return boxError();
1057  }
1058  }
1059  }
1060  if (!isClosure(fun, abstr, globalDefEnv, visited, localValEnv)) {
1061  // principle : f(a,b,c,...) ==> (a,b,c,...):f
1062  int ins, outs;
1063 
1064  // check arity of function
1065  Tree efun = a2sb(fun);
1066  //cerr << "TRACEPOINT 1 : " << boxpp(efun) << endl;
1067  if (!getBoxType(efun, &ins, &outs)) { // on laisse comme ca pour le moment
1068  // we can't determine the input arity of the expression
1069  // hope for the best
1070  return boxSeq(larg2par(larg), fun);
1071  }
1072 
1073  // check arity of arg list
1074  if (!boxlistOutputs(larg,&outs)) {
1075  // we don't know yet the output arity of larg. Therefore we can't
1076  // do any arity checking nor add _ to reach the required number of arguments
1077  // cerr << "warning : can't infere the type of : " << boxpp(larg) << endl;
1078  return boxSeq(larg2par(larg), fun);
1079  }
1080 
1081  if (outs > ins) {
1082  cerr << "too much arguments : " << outs << ", instead of : " << ins << endl;
1083  cerr << "when applying : " << boxpp(fun) << endl
1084  << " to : " << boxpp(larg) << endl;
1085  assert(false);
1086  }
1087 
1088  if ( (outs == 1)
1089  &&
1090  ( ( isBoxPrim2(fun, &p2) && (p2 != sigPrefix) )
1091  || ( getUserData(fun) && ((xtended*)getUserData(fun))->isSpecialInfix() ) ) ) {
1092  // special case : /(3) ==> _,3 : /
1093  Tree larg2 = concat(nwires(ins-outs), larg);
1094  return boxSeq(larg2par(larg2), fun);
1095 
1096  } else {
1097 
1098  Tree larg2 = concat(larg, nwires(ins-outs));
1099  return boxSeq(larg2par(larg2), fun);
1100  }
1101  }
1102 
1103  if (isBoxEnvironment(abstr)) {
1104  evalerrorbox(yyfilename, -1, "an environment can't be used as a function", fun);
1105  exit(1);
1106  }
1107 
1108  if (!isBoxAbstr(abstr, id, body)) {
1109  evalerror(yyfilename, -1, "(internal) not an abstraction inside closure", fun);
1110  exit(1);
1111  }
1112 
1113  // try to synthetise a name from the function name and the argument name
1114  {
1115  Tree arg = eval(hd(larg), visited, localValEnv);
1116  Tree narg; if ( isBoxNumeric(arg,narg) ) { arg = narg; }
1117  Tree f = eval(body, visited, pushValueDef(id, arg, localValEnv));
1118 
1119  Tree fname;
1120  if (getDefNameProperty(fun, fname)) {
1121  stringstream s; s << tree2str(fname); if (!gSimpleNames) s << "(" << boxpp(arg) << ")";
1122  setDefNameProperty(f, s.str());
1123  }
1124  return applyList(f, tl(larg));
1125  }
1126 }
1127 
1128 
1129 
1141 static Tree revEvalList (Tree lexp, Tree visited, Tree localValEnv)
1142 {
1143  Tree result = nil;
1144  //Tree lexp_orig = lexp;
1145  //cerr << "ENTER revEvalList(" << *lexp_orig << ", env:" << *localValEnv << ")" << endl;
1146  while (!isNil(lexp)) {
1147  result = cons(eval(hd(lexp), visited, localValEnv), result);
1148  lexp = tl(lexp);
1149  }
1150 
1151  //cerr << "EXIT revEvalList(" << *lexp_orig << ", env:" << *localValEnv << ") -> " << *result << endl;
1152  return result;
1153 }
1154 
1155 
1156 
1163 static Tree larg2par (Tree larg)
1164 {
1165  if (isNil(larg)) {
1166  evalerror(yyfilename, -1, "empty list of arguments", larg);
1167  exit(1);
1168  }
1169  if (isNil(tl(larg))) {
1170  return hd(larg);
1171  }
1172  return boxPar(hd(larg), larg2par(tl(larg)));
1173 }
1174 
1175 
1176 
1177 
1188 static Tree evalIdDef(Tree id, Tree visited, Tree lenv)
1189 {
1190  Tree def, name;
1191 
1192  // search the environment env for a definition of symbol id
1193  while (!isNil(lenv) && !getProperty(lenv, id, def)) {
1194  lenv = lenv->branch(0);
1195  }
1196 
1197  // check that the definition exists
1198  if (isNil(lenv)) {
1199  cerr << "undefined symbol " << *id << endl;
1200  evalerror(getDefFileProp(id), getDefLineProp(id), "undefined symbol ", id);
1201  exit(1);
1202  }
1203 
1204  //cerr << "Id definition is " << *def << endl;
1205  // check that it is not a recursive definition
1206  Tree p = cons(id,lenv);
1207  // set the definition name property
1208  if (!getDefNameProperty(def, name)) {
1209  // if the definition has no name use the identifier
1210  stringstream s; s << boxpp(id);
1211  //XXXXXX setDefNameProperty(def, s.str());
1212  }
1213 
1214  // return the evaluated definition
1215  return eval(def, addElement(p,visited), nil);
1216 }
1217 
1218 
1226 static Tree listn (int n, Tree e)
1227 {
1228  return (n<= 0) ? nil : cons(e, listn(n-1,e));
1229 }
1230 
1236 static Node PMPROPERTYNODE(symbol("PMPROPERTY"));
1237 
1238 static void setPMProperty(Tree t, Tree env, Tree pm)
1239 {
1240  setProperty(t, tree(PMPROPERTYNODE, env), pm);
1241 }
1242 
1243 static bool getPMProperty(Tree t, Tree env, Tree& pm)
1244 {
1245  return getProperty(t, tree(PMPROPERTYNODE, env), pm);
1246 }
1247 
1257 static Tree evalCase(Tree rules, Tree env)
1258 {
1259  Tree pm;
1260  if (!getPMProperty(rules, env, pm)) {
1261  Automaton* a = make_pattern_matcher(evalRuleList(rules, env));
1262  pm = boxPatternMatcher(a, 0, listn(len(rules), pushEnvBarrier(env)), rules, nil);
1263  setPMProperty(rules, env, pm);
1264  }
1265  return pm;
1266 }
1267 
1268 
1272 static Tree evalRuleList(Tree rules, Tree env)
1273 {
1274  //cerr << "evalRuleList "<< *rules << " in " << *env << endl;
1275  if (isNil(rules)) return nil;
1276  else return cons(evalRule(hd(rules), env), evalRuleList(tl(rules), env));
1277 }
1278 
1279 
1283 static Tree evalRule(Tree rule, Tree env)
1284 {
1285  //cerr << "evalRule "<< *rule << " in " << *env << endl;
1286  return cons(evalPatternList(left(rule), env), right(rule));
1287 }
1288 
1289 
1293 static Tree evalPatternList(Tree patterns, Tree env)
1294 {
1295  if (isNil(patterns)) {
1296  return nil;
1297  } else {
1298  return cons( evalPattern(hd(patterns), env),
1299  evalPatternList(tl(patterns), env) );
1300  }
1301 }
1302 
1303 
1308 static Tree evalPattern(Tree pattern, Tree env)
1309 {
1310  Tree p = eval(pattern, nil, env);
1311  return patternSimplification(p);
1312 }
1313 
1314 
1315 static void list2vec(Tree l, vector<Tree>& v)
1316 {
1317  while (!isNil(l)) {
1318  v.push_back(hd(l));
1319  l = tl(l);
1320  }
1321 }
1322 
1323 
1324 static Tree vec2list(const vector<Tree>& v)
1325 {
1326  Tree l = nil;
1327  int n = (int)v.size();
1328  while (n--) { l = cons(v[n],l); }
1329  return l;
1330 }
1331 
1332 
1333 
1334 
1336 // further simplification : replace bloc-diagrams that denote constant number by this number
1338 
1340 static Tree numericBoxSimplification(Tree box);
1341 static Tree insideBoxSimplification (Tree box);
1342 
1348 {
1349  Tree simplified;
1350 
1351  if (SimplifiedBoxProperty.get(box,simplified)) {
1352 
1353  return simplified;
1354 
1355  } else {
1356 
1357  simplified = numericBoxSimplification(box);
1358 
1359  // transferts name property if any
1360  Tree name; if (getDefNameProperty(box, name)) setDefNameProperty(simplified, name);
1361 
1362  // attach simplified expression as a property of original box
1363  SimplifiedBoxProperty.set(box,simplified);
1364 
1365  return simplified;
1366  }
1367 }
1368 
1373 {
1374  int ins, outs;
1375  Tree result;
1376  int i;
1377  double x;
1378 
1379  if ( ! getBoxType(box, &ins, &outs)) {
1380  cout << "ERROR in file " << __FILE__ << ':' << __LINE__ << ", Can't compute the box type of : " << *box << endl;
1381  exit(1);
1382  }
1383 
1384  if (ins==0 && outs==1) {
1385  // this box can potentially denote a number
1386  if (isBoxInt(box, &i) || isBoxReal(box, &x)) {
1387  result = box;
1388  } else {
1389  // propagate signals to discover if it simplifies to a number
1390  int i;
1391  double x;
1392  Tree lsignals = boxPropagateSig(nil, box , makeSigInputList(0));
1393  Tree s = simplify(hd(lsignals));
1394 
1395  if (isSigReal(s, &x)) {
1396  result = boxReal(x);
1397  } else if (isSigInt(s, &i)) {
1398  result = boxInt(i);
1399  } else {
1400  result = insideBoxSimplification(box);
1401  }
1402  }
1403  } else {
1404  // this box can't denote a number
1405  result = insideBoxSimplification(box);
1406  }
1407  return result;
1408 }
1409 
1414 {
1415  int i;
1416  double r;
1417  prim0 p0;
1418  prim1 p1;
1419  prim2 p2;
1420  prim3 p3;
1421  prim4 p4;
1422  prim5 p5;
1423 
1424  Tree t1, t2, ff, label, cur, min, max, step, type, name, file, slot, body;
1425 
1426 
1427  xtended* xt = (xtended*)getUserData(box);
1428 
1429  // Extended Primitives
1430 
1431  if (xt) {
1432  return box;
1433  }
1434 
1435  // Numbers and Constants
1436 
1437  else if (isBoxInt(box, &i)) {
1438  return box;
1439  }
1440  else if (isBoxReal(box, &r)) {
1441  return box;
1442  }
1443 
1444  else if (isBoxFConst(box, type, name, file)) {
1445  return box;
1446  }
1447 
1448  else if (isBoxFVar(box, type, name, file)) {
1449  return box;
1450  }
1451 
1452  // Wire and Cut
1453 
1454  else if (isBoxCut(box)) {
1455  return box;
1456  }
1457 
1458  else if (isBoxWire(box)) {
1459  return box;
1460  }
1461 
1462  // Primitives
1463 
1464  else if (isBoxPrim0(box, &p0)) {
1465  return box;
1466  }
1467 
1468  else if (isBoxPrim1(box, &p1)) {
1469  return box;
1470  }
1471 
1472  else if (isBoxPrim2(box, &p2)) {
1473  return box;
1474  }
1475 
1476  else if (isBoxPrim3(box, &p3)) {
1477  return box;
1478  }
1479 
1480  else if (isBoxPrim4(box, &p4)) {
1481  return box;
1482  }
1483 
1484  else if (isBoxPrim5(box, &p5)) {
1485  return box;
1486  }
1487 
1488  else if (isBoxFFun(box, ff)) {
1489  return box;
1490  }
1491 
1492  // User Interface Widgets
1493 
1494  else if (isBoxButton(box, label)) {
1495  return box;
1496  }
1497 
1498  else if (isBoxCheckbox(box, label)) {
1499  return box;
1500  }
1501 
1502  else if (isBoxVSlider(box, label, cur, min, max, step)) {
1503  return box;
1504  }
1505 
1506  else if (isBoxHSlider(box, label, cur, min, max, step)) {
1507  return box;
1508  }
1509 
1510  else if (isBoxNumEntry(box, label, cur, min, max, step)) {
1511  return box;
1512  }
1513 
1514  else if (isBoxVBargraph(box, label, min, max)) {
1515  return box;
1516  }
1517 
1518  else if (isBoxHBargraph(box, label, min, max)) {
1519  return box;
1520  }
1521 
1522  // User Interface Groups
1523 
1524  else if (isBoxVGroup(box, label, t1)) {
1525  return boxVGroup(label, boxSimplification(t1));
1526  }
1527 
1528  else if (isBoxHGroup(box, label, t1)) {
1529  return boxHGroup(label, boxSimplification(t1));
1530  }
1531 
1532  else if (isBoxTGroup(box, label, t1)) {
1533  return boxTGroup(label, boxSimplification(t1));
1534  }
1535 
1536  // Slots and Symbolic Boxes
1537 
1538  else if (isBoxSlot(box)) {
1539  return box;;
1540  }
1541 
1542  else if (isBoxSymbolic(box, slot, body)){
1543 
1544  Tree b = boxSimplification(body);
1545  return boxSymbolic(slot,b);
1546  }
1547 
1548  // Block Diagram Composition Algebra
1549 
1550  else if (isBoxSeq(box, t1, t2)) {
1551  Tree s1 = boxSimplification(t1);
1552  Tree s2 = boxSimplification(t2);
1553  return boxSeq(s1,s2);
1554  }
1555 
1556  else if (isBoxPar(box, t1, t2)) {
1557  Tree s1 = boxSimplification(t1);
1558  Tree s2 = boxSimplification(t2);
1559  return boxPar(s1,s2);
1560  }
1561 
1562  else if (isBoxSplit(box, t1, t2)) {
1563  Tree s1 = boxSimplification(t1);
1564  Tree s2 = boxSimplification(t2);
1565  return boxSplit(s1,s2);
1566  }
1567 
1568  else if (isBoxMerge(box, t1, t2)) {
1569  Tree s1 = boxSimplification(t1);
1570  Tree s2 = boxSimplification(t2);
1571  return boxMerge(s1,s2);
1572  }
1573  else if (isBoxRec(box, t1, t2)) {
1574  Tree s1 = boxSimplification(t1);
1575  Tree s2 = boxSimplification(t2);
1576  return boxRec(s1,s2);
1577  }
1578 
1579  cout << "ERROR in file " << __FILE__ << ':' << __LINE__ << ", unrecognised box expression : " << *box << endl;
1580  exit(1);
1581  return 0;
1582 }
static Tree evalRule(Tree rule, Tree env)
Evaluates the list of patterns and closure the rhs.
Definition: eval.cpp:1283
bool isBoxPrim1(Tree s)
Definition: boxes.cpp:315
bool isBoxPrim5(Tree s)
Definition: boxes.cpp:335
bool getDefNameProperty(Tree t, Tree &id)
Indicates the identifier (if any) the expression was a definition of.
Definition: names.cpp:85
Tree(* prim2)(Tree x, Tree y)
Definition: boxes.hh:210
bool isBoxIPar(Tree t, Tree &x, Tree &y, Tree &z)
Definition: boxes.cpp:169
bool isBoxWire(Tree t)
Definition: boxes.cpp:109
static bool isBoxNumeric(Tree in, Tree &out)
Definition: eval.cpp:630
Tree boxSymbolic(Tree slot, Tree body)
Definition: boxes.cpp:125
Tree addElement(Tree e, Tree l)
Definition: list.cpp:272
Definition: num.hh:58
bool isBoxSeq(Tree t, Tree &x, Tree &y)
Definition: boxes.cpp:136
Tree reverse(Tree l)
Definition: list.cpp:240
bool isBoxWithLocalDef(Tree t, Tree &body, Tree &ldef)
Definition: boxes.cpp:265
bool isBoxInt(Tree t)
Definition: boxes.cpp:78
Class Node = (type x (int + double + Sym + void*))
Definition: node.hh:75
static Tree evalPattern(Tree pattern, Tree env)
Evaluates a pattern and simplify it to numerical value if possible.
Definition: eval.cpp:1308
static Tree boxSimplification(Tree box)
boxSimplification(box) : simplify a block-diagram by replacing expressions denoting a constant number...
Definition: eval.cpp:1347
void evalerrorbox(const char *filename, int linenum, const char *msg, Tree exp)
Definition: errormsg.cpp:47
bool isBoxIdent(Tree t)
Definition: boxes.cpp:58
Tree boxCheckbox(Tree lbl)
Definition: boxes.cpp:371
static Tree eval(Tree exp, Tree visited, Tree localValEnv)
Definition: eval.cpp:280
Tree boxHBargraph(Tree lbl, Tree min, Tree max)
Definition: boxes.cpp:454
Tree boxSlot(int id)
Definition: boxes.cpp:118
bool isBoxOutputs(Tree t, Tree &x)
Definition: boxes.cpp:186
Tree cons(Tree a, Tree b)
Definition: list.hh:124
Tree left(Tree t)
Definition: list.hh:170
bool isBoxIProd(Tree t, Tree &x, Tree &y, Tree &z)
Definition: boxes.cpp:172
Tree pushValueDef(Tree id, Tree def, Tree lenv)
Push a new layer and add a single definition.
Definition: environment.cpp:94
bool isBoxPatternMatcher(Tree s)
Definition: boxes.cpp:630
int tree2int(Tree t)
if t has a node of type int, return it otherwise error
Definition: tree.cpp:230
Tree boxRec(Tree x, Tree y)
Definition: boxes.cpp:143
Tree copyEnvReplaceDefs(Tree anEnv, Tree ldefs, Tree visited, Tree curEnv)
Create a new environment by copying an existing one and replacing some definitions.
static Tree vec2list(const vector< Tree > &v)
Definition: eval.cpp:1324
static Tree nwires(int n)
repeat n times a wire
Definition: eval.cpp:984
bool getArgName(Tree t, Tree &id)
Definition: eval.cpp:233
Tree evaldocexpr(Tree docexpr, Tree eqlist)
Definition: eval.cpp:114
bool isBoxSplit(Tree t, Tree &x, Tree &y)
Definition: boxes.cpp:148
static Tree iterateSeq(Tree id, int num, Tree body, Tree visited, Tree localValEnv)
Iterate a sequential construction.
Definition: eval.cpp:871
Tree boxNumEntry(Tree lbl, Tree cur, Tree min, Tree max, Tree step)
Definition: boxes.cpp:416
void setNumericProperty(Tree t, Tree num)
Definition: eval.cpp:599
Tree boxEnvironment()
Definition: boxes.cpp:284
bool isBoxComponent(Tree s, Tree &filename)
Definition: boxes.cpp:290
Tree(* prim4)(Tree w, Tree x, Tree y, Tree z)
Definition: boxes.hh:212
vector< Tree > tvec
Definition: tree.hh:90
static Node PMPROPERTYNODE(symbol("PMPROPERTY"))
A property to store the pattern matcher corresponding to a set of rules in a specific environement...
int gMaxNameSize
Definition: main.cpp:127
bool isBoxFFun(Tree s)
Definition: boxes.cpp:344
A CTree = (Node x [CTree]) is a Node associated with a list of subtrees called branches.
Definition: tree.hh:109
bool isBoxCut(Tree t)
Definition: boxes.cpp:105
static loopDetector LD(1024, 512)
Eval a block diagram expression.
Detect evaluation loops.
static void list2vec(Tree l, vector< Tree > &v)
Definition: eval.cpp:1315
bool isBoxAppl(Tree t)
Definition: boxes.cpp:203
Tree simplify(Tree sig)
Definition: simplify.cpp:76
Tree boxVSlider(Tree lbl, Tree cur, Tree min, Tree max, Tree step)
Definition: boxes.cpp:397
Tree boxIdent(const char *name)
Definition: boxes.cpp:57
Tree sigPrefix(Tree t0, Tree t1)
Definition: signals.cpp:65
Tree hd(Tree l)
Definition: list.hh:133
bool isBoxAccess(Tree t, Tree &exp, Tree &id)
Definition: boxes.cpp:256
bool isBoxPrim0(Tree s)
Definition: boxes.cpp:310
bool isBoxPrim4(Tree s)
Definition: boxes.cpp:330
const Node & node() const
return the content of the tree
Definition: tree.hh:143
bool isBoxHGroup(Tree s)
Definition: boxes.cpp:437
bool isBoxHBargraph(Tree s)
Definition: boxes.cpp:455
Tree boxHSlider(Tree lbl, Tree cur, Tree min, Tree max, Tree step)
Definition: boxes.cpp:377
static bool isIdentChar(char c)
Definition: eval.cpp:738
bool gSimpleNames
Definition: main.cpp:128
static Tree make(const Node &n, int ar, Tree br[])
return a new tree or an existing equivalent one
static Tree listn(int n, Tree e)
Creates a list of n elements.
Definition: eval.cpp:1226
Tree right(Tree t)
Definition: list.hh:171
static void writeIdentValue(std::string &dst, const std::string &format, const std::string &ident, Tree visited, Tree localValEnv)
Definition: eval.cpp:745
void setDefNameProperty(Tree t, Tree id)
Definition: names.cpp:54
bool getEvalProperty(Tree box, Tree env, Tree &value)
retrieve the value of box in the environment env
Definition: eval.cpp:274
Tree pushEnvBarrier(Tree lenv)
Definition: environment.cpp:43
bool isBoxRec(Tree t, Tree &x, Tree &y)
Definition: boxes.cpp:144
static void setPMProperty(Tree t, Tree env, Tree pm)
Definition: eval.cpp:1238
Interface of the block diagram evaluator.
static Tree real_a2sb(Tree exp)
Definition: eval.cpp:154
Tree boxInt(int n)
Definition: boxes.cpp:75
double max(double x, double y)
Definition: interval.hh:60
static Node EVALPROPERTY(symbol("EvalProperty"))
static Tree a2sb(Tree exp)
Definition: eval.cpp:135
bool isBoxAbstr(Tree t)
Definition: boxes.cpp:202
Tree(* prim3)(Tree x, Tree y, Tree z)
Definition: boxes.hh:211
static Tree evalPatternList(Tree patterns, Tree env)
Evaluates each pattern of the list.
Definition: eval.cpp:1293
static Tree evalCase(Tree rules, Tree env)
Eval a case expression containing a list of pattern matching rules.
Definition: eval.cpp:1257
Tree boxWire()
Definition: boxes.cpp:108
bool get(Tree t, Tree &data)
Definition: property.hh:67
bool isNil(Tree l)
Definition: list.hh:137
Tree(* prim5)(Tree v, Tree w, Tree x, Tree y, Tree z)
Definition: boxes.hh:213
Tree boxVBargraph(Tree lbl, Tree min, Tree max)
Definition: boxes.cpp:460
bool isSigReal(Tree t, double *r)
Definition: signals.cpp:44
Tree simplifyPattern(Tree value)
Simplify a block-diagram pattern by computing its numerical sub-expressions.
Definition: eval.cpp:617
static const char * evalLabel(const char *l, Tree visited, Tree localValEnv)
evallabel replace "...%2i..." occurences in label with value of i
Definition: eval.cpp:760
Tree boxPatternMatcher(Automaton *a, int state, Tree env, Tree origRules, Tree revParamList)
Definition: boxes.cpp:625
static Tree revEvalList(Tree lexp, Tree visited, Tree localValEnv)
Eval a list of expression in reverse order.
Definition: eval.cpp:1141
bool isBoxModifLocalDef(Tree t, Tree &body, Tree &ldef)
Definition: boxes.cpp:275
static double eval2double(Tree exp, Tree visited, Tree localValEnv)
Eval a block diagram to a double.
Definition: eval.cpp:689
bool isBoxSymbolic(Tree t)
Definition: boxes.cpp:126
bool isBoxTGroup(Tree s)
Definition: boxes.cpp:449
Tree boxButton(Tree lbl)
Definition: boxes.cpp:365
bool isBoxISum(Tree t, Tree &x, Tree &y, Tree &z)
Definition: boxes.cpp:171
bool isBoxEnvironment(Tree s)
Definition: boxes.cpp:285
Tree boxPropagateSig(Tree path, Tree box, const siglist &lsig)
Top level propagate a list of signals into a block diagram.
Definition: propagate.cpp:501
Tree pushMultiClosureDefs(Tree ldefs, Tree visited, Tree lenv)
Push a new layer with multiple definitions creating the appropriate closures.
Tree evalprocess(Tree eqlist)
Eval "process" from a list of definitions.
Definition: eval.cpp:100
bool isBoxButton(Tree s)
Definition: boxes.cpp:366
bool isBoxReal(Tree t)
Definition: boxes.cpp:79
static property< Tree > SimplifiedBoxProperty
Definition: eval.cpp:1339
bool isBoxCase(Tree s)
Definition: boxes.cpp:617
Tree(* prim1)(Tree x)
Definition: boxes.hh:209
bool getNumericProperty(Tree t, Tree &num)
Definition: eval.cpp:604
Tree setUnion(Tree A, Tree B)
Definition: list.cpp:317
int getDefLineProp(Tree sym)
Definition: errormsg.cpp:82
bool isBoxPar(Tree t, Tree &x, Tree &y)
Definition: boxes.cpp:140
bool isBoxHSlider(Tree s)
Definition: boxes.cpp:379
static int gBoxSlotNumber
counter for unique slot number
Definition: eval.cpp:152
Tree boxMerge(Tree x, Tree y)
Definition: boxes.cpp:151
bool isBoxVBargraph(Tree s)
Definition: boxes.cpp:461
bool isBoxWaveform(Tree s)
Definition: boxes.cpp:97
static Tree numericBoxSimplification(Tree box)
Try to do a numeric simplification of a block-diagram.
Definition: eval.cpp:1372
bool isClosure(Tree t, Tree &abstr, Tree &genv, Tree &vis, Tree &lenv)
Definition: boxes.cpp:239
static bool boxlistOutputs(Tree boxlist, int *outputs)
Compute the sum of outputs of a list of boxes.
Definition: eval.cpp:948
Tree expandlist(Tree ldef)
Return the list of definitions where all imports have been expanded.
Tree sigAdd(Tree x, Tree y)
Definition: signals.hh:152
Tree boxError()
Definition: boxes.cpp:244
bool isBoxCheckbox(Tree s)
Definition: boxes.cpp:372
static bool autoName(Tree exp, Tree &id)
Definition: eval.cpp:226
Tree boxReal(double n)
Definition: boxes.cpp:76
Tree concat(Tree l, Tree q)
Definition: list.cpp:216
bool gSimplifyDiagrams
Definition: main.cpp:129
Tree boxPrim2(prim2 foo)
Definition: boxes.cpp:319
static bool getPMProperty(Tree t, Tree env, Tree &pm)
Definition: eval.cpp:1243
static Tree patternSimplification(Tree pattern)
Definition: eval.cpp:659
static bool isDigitChar(char c)
Definition: eval.cpp:733
static Tree applyList(Tree fun, Tree larg)
Apply a function to a list of arguments.
Definition: eval.cpp:1003
bool isBoxVGroup(Tree s)
Definition: boxes.cpp:443
int arity() const
return the number of branches (subtrees) of a tree
Definition: tree.hh:144
void set(Tree t, Tree data)
Definition: property.hh:62
siglist makeSigInputList(int n)
Fabrique une liste de n entrées.
Definition: propagate.cpp:96
Tree boxSeq(Tree x, Tree y)
Definition: boxes.cpp:135
void evalerror(const char *filename, int linenum, const char *msg, Tree exp)
Definition: errormsg.cpp:40
bool isBoxFVar(Tree s)
Definition: boxes.cpp:356
const char * name(Symbol *sym)
Returns the name of a symbol.
Definition: symbol.hh:98
Tree closure(Tree abstr, Tree genv, Tree vis, Tree lenv)
Definition: boxes.cpp:234
bool isSigInt(Tree t, int *i)
Definition: signals.cpp:41
Tree tree(const Node &n)
Definition: tree.hh:186
const char * yyfilename
Definition: errormsg.cpp:30
const char * Formats[]
Definition: eval.cpp:743
bool isBoxVSlider(Tree s)
Definition: boxes.cpp:399
Tree boxHGroup(Tree lbl, Tree x)
Definition: boxes.cpp:436
static Tree evalRuleList(Tree rules, Tree env)
Evaluates each rule of the list.
Definition: eval.cpp:1272
SourceReader gReader
Definition: main.cpp:89
static bool isBoxPatternOp(Tree box, Node &n, Tree &t1, Tree &t2)
Definition: eval.cpp:581
Definition: ppbox.hh:58
bool isBoxNumEntry(Tree s)
Definition: boxes.cpp:418
Tree boxTGroup(Tree lbl, Tree x)
Definition: boxes.cpp:448
void setProperty(Tree t, Tree key, Tree val)
Definition: list.cpp:418
bool isBoxSlot(Tree t)
Definition: boxes.cpp:119
static int eval2int(Tree exp, Tree visited, Tree localValEnv)
Eval a block diagram to an int.
Definition: eval.cpp:718
Tree boxPar(Tree x, Tree y)
Definition: boxes.cpp:139
static Tree iteratePar(Tree var, int num, Tree body, Tree visited, Tree localValEnv)
Iterate a parallel construction.
Definition: eval.cpp:845
bool isBoxInputs(Tree t, Tree &x)
Definition: boxes.cpp:185
void * getUserData(Symbol *sym)
Returns user data.
Definition: symbol.hh:100
bool isBoxPrim3(Tree s)
Definition: boxes.cpp:325
bool isBoxISeq(Tree t, Tree &x, Tree &y, Tree &z)
Definition: boxes.cpp:170
Tree nil
Definition: list.cpp:116
bool isBoxPatternVar(Tree s, Tree &id)
Definition: boxes.cpp:622
Tree sigMul(Tree x, Tree y)
Definition: signals.hh:154
Tree getlist(string fname)
Return the list of definitions file contains.
Symbol * symbol(const char *str)
Returns (and creates if new) the symbol of name str.
Definition: symbol.hh:95
bool isBoxLibrary(Tree s, Tree &filename)
Definition: boxes.cpp:295
static Tree iterateSum(Tree id, int num, Tree body, Tree visited, Tree localValEnv)
Iterate an addition construction.
Definition: eval.cpp:898
static Tree insideBoxSimplification(Tree box)
Simplify inside a block-diagram : S[A*B] => S[A]*S[B].
Definition: eval.cpp:1413
Interface for names management.
static Tree larg2par(Tree larg)
Transform a list of expressions in a parallel construction.
Definition: eval.cpp:1163
bool isBoxError(Tree t)
Definition: boxes.cpp:249
bool isBoxMerge(Tree t, Tree &x, Tree &y)
Definition: boxes.cpp:152
Tree NUMERICPROPERTY
Definition: eval.cpp:597
bool isBoxFConst(Tree s)
Definition: boxes.cpp:350
double min(double x, double y)
Definition: interval.hh:59
bool isBoxPrim2(Tree s)
Definition: boxes.cpp:320
bool detect(Tree t)
Definition: loopDetector.cpp:4
int apply_pattern_matcher(Automaton *A, int s, Tree X, Tree &C, vector< Tree > &E)
double tree2float(Tree t)
if t has a node of type float, return it otherwise error
Definition: tree.cpp:246
Tree boxSplit(Tree x, Tree y)
Definition: boxes.cpp:147
Tree boxCase(Tree rules)
Definition: boxes.cpp:615
int len(Tree l)
Definition: list.cpp:198
Automaton * make_pattern_matcher(Tree R)
Tree tl(Tree l)
Definition: list.hh:134
void setEvalProperty(Tree box, Tree env, Tree value)
set the value of box in the environment env
Definition: eval.cpp:261
property< Tree > gSymbolicBoxProperty
Transform unused (unapplied) closures into symbolic boxes.
Definition: eval.cpp:131
static Tree evalIdDef(Tree id, Tree visited, Tree env)
Search the environment for the definition of a symbol ID and evaluate it.
Definition: eval.cpp:1188
const char * tree2str(Tree t)
if t has a node of type symbol, return its name otherwise error
Definition: tree.cpp:278
Tree boxVGroup(Tree lbl, Tree x)
Definition: boxes.cpp:442
Tree branch(int i) const
return the ith branch (subtree) of a tree
Definition: tree.hh:145
int yylineno
Definition: faustlexer.cpp:357
const char * getDefFileProp(Tree sym)
Definition: errormsg.cpp:72
Tree(* prim0)()
Definition: boxes.hh:208
bool getProperty(Tree t, Tree key, Tree &val)
Definition: list.cpp:423
static Tree iterateProd(Tree id, int num, Tree body, Tree visited, Tree localValEnv)
Iterate a product construction.
Definition: eval.cpp:926
bool getBoxType(Tree box, int *inum, int *onum)
Return the type (number of inputs and outputs) of a box or false if undefined.
Definition: boxtype.cpp:63
static Tree realeval(Tree exp, Tree visited, Tree localValEnv)
Eval a block diagram expression.
Definition: eval.cpp:308