Пример #1
0
static Tree realeval (Tree exp, Tree visited, Tree localValEnv)
{
	//Tree 	def;
	Tree 	fun;
	Tree 	arg;
	Tree	var, num, body, ldef;
	Tree 	label;
	Tree	cur, lo, hi, step;
	Tree	e1, e2, exp2, notused, visited2, lenv2;
	Tree	rules;
	Tree	id;

	//cerr << "EVAL " << *exp << " (visited : " << *visited << ")" << endl;
    //cerr << "REALEVAL of " << *exp << endl;
	
	xtended* xt = (xtended*) getUserData(exp);

	// constants
	//-----------
	
	if ( 	xt || 
			isBoxInt(exp) || isBoxReal(exp) || 
			isBoxWire(exp) || isBoxCut(exp) ||
			isBoxPrim0(exp) || isBoxPrim1(exp) || 
			isBoxPrim2(exp) || isBoxPrim3(exp) || 
			isBoxPrim4(exp) || isBoxPrim5(exp) ||
            isBoxFFun(exp) || isBoxFConst(exp) || isBoxFVar(exp) ||
            isBoxWaveform(exp)) {
		return exp;

	// block-diagram constructors
	//---------------------------
	
	} else if (isBoxSeq(exp, e1, e2)) {
		return boxSeq(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));

	} else if (isBoxPar(exp, e1, e2)) {
		return boxPar(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));

	} else if (isBoxRec(exp, e1, e2)) {
		return boxRec(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));

	} else if (isBoxSplit(exp, e1, e2)) {
		return boxSplit(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));

	} else if (isBoxMerge(exp, e1, e2)) {
		return boxMerge(eval(e1, visited, localValEnv), eval(e2, visited, localValEnv));
		
	// Modules
	//--------

    } else if (isBoxAccess(exp, body, var)) {
        Tree val = eval(body, visited, localValEnv);
        if (isClosure(val, exp2, notused, visited2, lenv2)) {
            // it is a closure, we have an environment to access
            return eval(closure(var,notused,visited2,lenv2), visited, localValEnv);
        } else {
            evalerror(getDefFileProp(exp), getDefLineProp(exp), "no environment to access", exp);
        }

//////////////////////en chantier////////////////////////////

    } else if (isBoxModifLocalDef(exp, body, ldef)) {
        Tree val = eval(body, visited, localValEnv);
        if (isClosure(val, exp2, notused, visited2, lenv2)) {
            // we rebuild the closure using a copy of the original environment
            // modified with some new definitions
            Tree lenv3 = copyEnvReplaceDefs(lenv2, ldef, visited2, localValEnv);
            return eval(closure(exp2,notused,visited2,lenv3), visited, localValEnv);
        } else {
            evalerror(getDefFileProp(exp), getDefLineProp(exp), "not a closure", val);
            evalerror(getDefFileProp(exp), getDefLineProp(exp), "no environment to access", exp);
        }

///////////////////////////////////////////////////////////////////

    } else if (isBoxComponent(exp, label)) {
        string  fname   = tree2str(label);
        Tree    eqlst   = gGlobal->gReader.expandlist(gGlobal->gReader.getlist(fname));
        Tree    res     = closure(boxIdent("process"), gGlobal->nil, gGlobal->nil, pushMultiClosureDefs(eqlst, gGlobal->nil, gGlobal->nil));
        setDefNameProperty(res, label);
        //cerr << "component is " << boxpp(res) << endl;
        return res;

    } else if (isBoxLibrary(exp, label)) {
        string  fname   = tree2str(label);
        Tree    eqlst   = gGlobal->gReader.expandlist(gGlobal->gReader.getlist(fname));
        Tree    res     = closure(boxEnvironment(), gGlobal->nil, gGlobal->nil, pushMultiClosureDefs(eqlst, gGlobal->nil, gGlobal->nil));
        setDefNameProperty(res, label);
        //cerr << "component is " << boxpp(res) << endl;
        return res;

	// user interface elements
	//------------------------
	
	} else if (isBoxButton(exp, label)) {
		const char* l1 = tree2str(label);
     	const char* l2 = evalLabel(l1, visited, localValEnv);
		//cout << "button label : " << l1 << " become " << l2 << endl;
		return ((l1 == l2) ? exp : boxButton(tree(l2)));

	} else if (isBoxCheckbox(exp, label)) {
		const char* l1 = tree2str(label);
    	const char* l2 = evalLabel(l1, visited, localValEnv);
		//cout << "check box label : " << l1 << " become " << l2 << endl;
		return ((l1 == l2) ? exp : boxCheckbox(tree(l2)));

	} else if (isBoxVSlider(exp, label, cur, lo, hi, step)) {
		const char* l1 = tree2str(label);
        const char* l2 = evalLabel(l1, visited, localValEnv);
		return ( boxVSlider(tree(l2),
					tree(eval2double(cur, visited, localValEnv)),
					tree(eval2double(lo, visited, localValEnv)),
					tree(eval2double(hi, visited, localValEnv)),
					tree(eval2double(step, visited, localValEnv))));

	} else if (isBoxHSlider(exp, label, cur, lo, hi, step)) {
		const char* l1 = tree2str(label);
     	const char* l2 = evalLabel(l1, visited, localValEnv);
		return ( boxHSlider(tree(l2),
					tree(eval2double(cur, visited, localValEnv)),
					tree(eval2double(lo, visited, localValEnv)),
					tree(eval2double(hi, visited, localValEnv)),
					tree(eval2double(step, visited, localValEnv))));

	} else if (isBoxNumEntry(exp, label, cur, lo, hi, step)) {
		const char* l1 = tree2str(label);
      	const char* l2 = evalLabel(l1, visited, localValEnv);
		return (boxNumEntry(tree(l2),
					tree(eval2double(cur, visited, localValEnv)),
					tree(eval2double(lo, visited, localValEnv)),
					tree(eval2double(hi, visited, localValEnv)),
					tree(eval2double(step, visited, localValEnv))));

	} else if (isBoxVGroup(exp, label, arg)) {
		const char* l1 = tree2str(label);
        const char* l2 = evalLabel(l1, visited, localValEnv);
		return boxVGroup(tree(l2),	eval(arg, visited, localValEnv) );

	} else if (isBoxHGroup(exp, label, arg)) {
		const char* l1 = tree2str(label);
 		const char* l2 = evalLabel(l1, visited, localValEnv);
		return boxHGroup(tree(l2),	eval(arg, visited, localValEnv) );

	} else if (isBoxTGroup(exp, label, arg)) {
		const char* l1 = tree2str(label);
    	const char* l2 = evalLabel(l1, visited, localValEnv);
		return boxTGroup(tree(l2),	eval(arg, visited, localValEnv) );

	} else if (isBoxHBargraph(exp, label, lo, hi)) {
		const char* l1 = tree2str(label);
    	const char* l2 = evalLabel(l1, visited, localValEnv);
		return boxHBargraph(tree(l2),
					tree(eval2double(lo, visited, localValEnv)),
					tree(eval2double(hi, visited, localValEnv)));

	} else if (isBoxVBargraph(exp, label, lo, hi)) {
		const char* l1 = tree2str(label);
  		const char* l2 = evalLabel(l1, visited, localValEnv);
		return boxVBargraph(tree(l2),
					tree(eval2double(lo, visited, localValEnv)),
					tree(eval2double(hi, visited, localValEnv)));

	// lambda calculus
	//----------------
		
	} else if (isBoxIdent(exp)) {
		return evalIdDef(exp, visited, localValEnv);

	} else if (isBoxWithLocalDef(exp, body, ldef)) {
		return eval(body, visited, pushMultiClosureDefs(ldef, visited, localValEnv));
	
	} else if (isBoxAppl(exp, fun, arg)) {
        return applyList( eval(fun, visited, localValEnv),
						  revEvalList(arg, visited, localValEnv) );

    } else if (isBoxAbstr(exp)) {
        // it is an abstraction : return a closure
        return closure(exp, gGlobal->nil, visited, localValEnv);

    } else if (isBoxEnvironment(exp)) {
        // environment : return also a closure
        return closure(exp, gGlobal->nil, visited, localValEnv);

	} else if (isClosure(exp, exp2, notused, visited2, lenv2)) {

        if (isBoxAbstr(exp2)) {
            // a 'real' closure
            return closure(exp2, gGlobal->nil, setUnion(visited,visited2), lenv2);
        } else if (isBoxEnvironment(exp2)) {
            // a 'real' closure
            return closure(exp2, gGlobal->nil, setUnion(visited,visited2), lenv2);
        } else {
			// it was a suspended evaluation
			return eval(exp2, setUnion(visited,visited2), lenv2);
		}

	// Algorithmic constructions
	//--------------------------
	
	} else if (isBoxIPar(exp, var, num, body)) {
		int n = eval2int(num, visited, localValEnv);
		return iteratePar(var, n, body, visited, localValEnv);

	} else if (isBoxISeq(exp, var, num, body)) {
		int n = eval2int(num, visited, localValEnv);
		return iterateSeq(var, n, body, visited, localValEnv);

	} else if (isBoxISum(exp, var, num, body)) {
		int n = eval2int(num, visited, localValEnv);
		return iterateSum(var, n, body, visited, localValEnv);

    } else if (isBoxIProd(exp, var, num, body)) {
        int n = eval2int(num, visited, localValEnv);
        return iterateProd(var, n, body, visited, localValEnv);

    // static
    } else if (isBoxInputs(exp, body)) {
        int ins, outs;
        Tree b = a2sb(eval(body, visited, localValEnv));
        if (getBoxType (b, &ins, &outs)) {
            return boxInt(ins);
        } else {
            stringstream error;
            error << "ERROR : can't evaluate ' : " << *exp << endl;
            throw faustexception(error.str());
        }
  
    } else if (isBoxOutputs(exp, body)) {
        int ins, outs;
        Tree b = a2sb(eval(body, visited, localValEnv));
        if (getBoxType (b, &ins, &outs)) {
            return boxInt(outs);
        } else {
            stringstream error;
            error << "ERROR : can't evaluate ' : " << *exp << endl;
            throw faustexception(error.str());
        }

	} else if (isBoxSlot(exp)) 		{ 
		return exp; 
	
	} else if (isBoxSymbolic(exp)) 	{
	 	return exp;

	// Pattern matching extension
	//---------------------------
	
	} else if (isBoxCase(exp, rules)) {
        return evalCase(rules, localValEnv);

	} else if (isBoxPatternVar(exp, id)) {
		return exp;
		//return evalIdDef(id, visited, localValEnv);

	} else if (isBoxPatternMatcher(exp)) {
		return exp;

    } else {
        stringstream error;
        error << "ERROR : EVAL doesn't intercept : " << *exp << endl;
        throw faustexception(error.str());
    }
	return NULL;
}
Пример #2
0
/**
 * Prepare a "pattern" by replacing variables x by special
 * pattern variables ?x.
 *
 * P[x]     -> ?x
 * P[x(e)]  -> x(P[e])
 * P[e(f)]  -> P[e](P[f])
 * P[e:f]   -> P[e]:P[f]
 * etc.
 */
static Tree preparePattern(Tree box)
{
// cerr << "preparePattern(" << boxpp(box) << ")" << endl;

  int id;
  double r;
  prim0 p0;
  prim1 p1;
  prim2 p2;
  prim3 p3;
  prim4 p4;
  prim5 p5;

  Tree t1, t2, t3, ff, label, cur, min, max, step, type, name, file, arg,
       body, fun, args, ldef, slot,
       ident, rules;

  xtended* xt = (xtended*)getUserData(box);

  // primitive elements
  if(xt)
    return box;
  else if(isBoxIdent(box))
    return boxPatternVar(box);
  else if(isBoxAppl(box, fun, args))
  {
    if(isBoxIdent(fun))
      return boxAppl(fun, lmap(preparePattern, args));
    else
      return boxAppl(preparePattern(fun), lmap(preparePattern, args));
  }
  else if(isBoxAbstr(box, arg, body))
    return box;
  else if(isBoxInt(box))
    return box;
  else if(isBoxReal(box, &r))
    return box;
  else if(isBoxWaveform(box))
    return box;
  else if(isBoxCut(box))
    return box;
  else if(isBoxWire(box))
    return box;
  else if(isBoxPrim0(box, &p0))
    return box;
  else if(isBoxPrim1(box, &p1))
    return box;
  else if(isBoxPrim2(box, &p2))
    return box;
  else if(isBoxPrim3(box, &p3))
    return box;
  else if(isBoxPrim4(box, &p4))
    return box;
  else if(isBoxPrim5(box, &p5))
    return box;

  else if(isBoxWithLocalDef(box, body, ldef))
    return boxWithLocalDef(preparePattern(body), ldef);

  // foreign elements
  else if(isBoxFFun(box, ff))
    return box;
  else if(isBoxFConst(box, type, name, file))
    return box;
  else if(isBoxFVar(box, type, name, file))
    return box;

  // block diagram binary operator
  else if(isBoxSeq(box, t1, t2))
    return boxSeq(preparePattern(t1), preparePattern(t2));
  else if(isBoxSplit(box, t1, t2))
    return boxSplit(preparePattern(t1), preparePattern(t2));
  else if(isBoxMerge(box, t1, t2))
    return boxMerge(preparePattern(t1), preparePattern(t2));
  else if(isBoxPar(box, t1, t2))
    return boxPar(preparePattern(t1), preparePattern(t2));
  else if(isBoxRec(box, t1, t2))
    return boxRec(preparePattern(t1), preparePattern(t2));

  // iterative block diagram construction
  else if(isBoxIPar(box, t1, t2, t3))
    return boxIPar(t1, t2, preparePattern(t3));
  else if(isBoxISeq(box, t1, t2, t3))
    return boxISeq(t1, t2, preparePattern(t3));
  else if(isBoxISum(box, t1, t2, t3))
    return boxISum(t1, t2, preparePattern(t3));
  else if(isBoxIProd(box, t1, t2, t3))
    return boxIProd(t1, t2, preparePattern(t3));

  // static information
  else if(isBoxInputs(box, t1))
    return boxInputs(preparePattern(t1));
  else if(isBoxOutputs(box, t1))
    return boxOutputs(preparePattern(t1));

  // user interface
  else if(isBoxButton(box, label))
    return box;
  else if(isBoxCheckbox(box, label))
    return box;

  else if(isBoxVSlider(box, label, cur, min, max, step))
    return box;
  else if(isBoxHSlider(box, label, cur, min, max, step))
    return box;

  else if(isBoxVGroup(box, label, t1))
    return boxVGroup(label, preparePattern(t1));
  else if(isBoxHGroup(box, label, t1))
    return boxHGroup(label, preparePattern(t1));
  else if(isBoxTGroup(box, label, t1))
    return boxTGroup(label, preparePattern(t1));

  else if(isBoxHBargraph(box, label, min, max))
    return box;
  else if(isBoxVBargraph(box, label, min, max))
    return box;
  else if(isBoxNumEntry(box, label, cur, min, max, step))
    return box;

  else if(isNil(box))
    return box;
  else if(isList(box))
    return lmap(preparePattern, box);
  else if(isBoxEnvironment(box))
    return box;
  /* not expected
     else if (isClosure(box, abstr, genv, vis, lenv)) {
      fout << "closure[" << boxpp(abstr)
          << ", genv = " << envpp(genv)
          << ", lenv = " << envpp(lenv)
          << "]";
     }
   */
  else if(isBoxComponent(box, label))
    return box;
  else if(isBoxAccess(box, t1, t2))
    return box;

  /* not expected
     else if (isImportFile(box, label)) {
      fout << "import("
          << tree2str(label) << ')';
     }
   */

  else if(isBoxSlot(box, &id))
    return box;
  else if(isBoxSymbolic(box, slot, body))
    return box;

  // Pattern Matching Extensions
  else if(isBoxCase(box, rules))
    return box;
  else if(isBoxPatternVar(box, ident))
    return box;

  // None of the previous tests succeded, then it is not a valid box
  else
  {
    cerr << "Error in preparePattern() : " << *box << " is not a valid box" << endl;
    exit(1);
  }

  return box;
}
Пример #3
0
/**
 *  Simplify inside a block-diagram : S[A*B] => S[A]*S[B]
 */
Tree insideBoxSimplification (Tree box)
{
    int		i;
    double	r;
    prim0	p0;
    prim1	p1;
    prim2	p2;
    prim3	p3;
    prim4	p4;
    prim5	p5;

    Tree	t1, t2, ff, label, cur, min, max, step, type, name, file, slot, body;

    xtended* xt = (xtended*)getUserData(box);

    // Extended Primitives

    if (xt)	{
        return box;
    }

    // Numbers and Constants

    else if (isBoxInt(box, &i)) 	{
        return box;
    }
    else if (isBoxReal(box, &r)) 	{
        return box;
    }

    else if (isBoxFConst(box, type, name, file))    {
        return box;
    }

    else if (isBoxFVar(box, type, name, file))    {
        return box;
    }

    // Wire and Cut

    else if (isBoxCut(box)) 				{
        return box;
    }

    else if (isBoxWire(box)) 				{
        return box;
    }

    // Primitives

    else if (isBoxPrim0(box, &p0)) 			{
        return box;
    }

    else if (isBoxPrim1(box, &p1)) 			{
        return box;
    }

    else if (isBoxPrim2(box, &p2)) 				{
        return box;
    }

    else if (isBoxPrim3(box, &p3)) 				{
        return box;
    }

    else if (isBoxPrim4(box, &p4)) 				{
        return box;
    }

    else if (isBoxPrim5(box, &p5)) 				{
        return box;
    }

    else if (isBoxFFun(box, ff)) 				{
        return box;
    }

    // User Interface Widgets

    else if (isBoxButton(box, label)) 	{
        return box;
    }

    else if (isBoxCheckbox(box, label)) 	{
        return box;
    }

    else if (isBoxVSlider(box, label, cur, min, max, step)) 	{
        return box;
    }

    else if (isBoxHSlider(box, label, cur, min, max, step)) 	{
        return box;
    }

    else if (isBoxNumEntry(box, label, cur, min, max, step)) 	{
        return box;
    }

    else if (isBoxVBargraph(box, label, min, max)) 	{
        return box;
    }

    else if (isBoxHBargraph(box, label, min, max)) 	{
        return box;
    }

    // User Interface Groups

    else if (isBoxVGroup(box, label, t1)) 	{
        return boxVGroup(label, boxSimplification(t1));
    }

    else if (isBoxHGroup(box, label, t1)) 	{
        return boxHGroup(label, boxSimplification(t1));
    }

    else if (isBoxTGroup(box, label, t1)) 	{
        return boxTGroup(label, boxSimplification(t1));
    }

    // Slots and Symbolic Boxes

    else if (isBoxSlot(box)) 				{
        return box;;
    }

    else if (isBoxSymbolic(box, slot, body)){

        Tree b = boxSimplification(body);
        return boxSymbolic(slot,b);
    }

    // Block Diagram Composition Algebra

    else if (isBoxSeq(box, t1, t2)) 	{
        Tree s1 = boxSimplification(t1);
        Tree s2 = boxSimplification(t2);
        return boxSeq(s1,s2);
    }

    else if (isBoxPar(box, t1, t2)) 	{
        Tree s1 = boxSimplification(t1);
        Tree s2 = boxSimplification(t2);
        return boxPar(s1,s2);
    }

    else if (isBoxSplit(box, t1, t2)) 	{
        Tree s1 = boxSimplification(t1);
        Tree s2 = boxSimplification(t2);
        return boxSplit(s1,s2);
    }

    else if (isBoxMerge(box, t1, t2)) 	{
        Tree s1 = boxSimplification(t1);
        Tree s2 = boxSimplification(t2);
        return boxMerge(s1,s2);
    }
    else if (isBoxRec(box, t1, t2)) 	{
        Tree s1 = boxSimplification(t1);
        Tree s2 = boxSimplification(t2);
        return boxRec(s1,s2);
    }

    stringstream error;
    error << "ERROR in file " << __FILE__ << ':' << __LINE__ << ", unrecognised box expression : " << *box << endl;
    throw faustexception(error.str());
    return 0;
}