Exemplo n.º 1
0
ostream& boxpp::print (ostream& fout) const
{
    int		i, 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, abstr, genv, vis, lenv, ldef, slot,
            ident, rules;

    const char* str;

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

    // primitive elements
    if (xt) 						fout << xt->name();
    else if (isBoxInt(box, &i))			fout << i;
    else if (isBoxReal(box, &r))		fout << T(r);
    else if (isBoxCut(box))				fout << '!';
    else if (isBoxWire(box))			fout << '_';
    else if (isBoxIdent(box, &str))		fout << str;
    else if (isBoxPrim0(box, &p0))		fout << prim0name(p0);
    else if (isBoxPrim1(box, &p1))		fout << prim1name(p1);
    else if (isBoxPrim2(box, &p2))		fout << prim2name(p2);
    else if (isBoxPrim3(box, &p3))		fout << prim3name(p3);
    else if (isBoxPrim4(box, &p4))		fout << prim4name(p4);
    else if (isBoxPrim5(box, &p5))		fout << prim5name(p5);

    else if (isBoxAbstr(box,arg,body))	fout << "\\" << boxpp(arg) << ".(" << boxpp(body) << ")";
    else if (isBoxAppl(box, fun, args))	fout << boxpp(fun) << boxpp(args) ;

    else if (isBoxWithLocalDef(box, body, ldef))	fout << boxpp(body) << " with { " << envpp(ldef) << " }";

    // foreign elements
    else if (isBoxFFun(box, ff)) {
        fout << "ffunction(" << type2str(ffrestype(ff));
        Tree namelist = nth(ffsignature(ff),1);
        char sep = ' ';
        for (int i = 0; i < gFloatSize; i++) {
            fout << sep << tree2str(nth(namelist,i));
            sep = '|';
        }
        sep = '(';
        for (int i = 0; i < ffarity(ff); i++) {
            fout << sep << type2str(ffargtype(ff, i));
            sep = ',';
        }
        fout << ')';
        fout << ',' << ffincfile(ff) << ',' << fflibfile(ff) << ')';
    } else if (isBoxFConst(box, type, name, file))
        fout << "fconstant(" << type2str(tree2int(type)) << ' ' << tree2str(name) << ", " << tree2str(file) << ')';
    else if (isBoxFVar(box, type, name, file))
        fout << "fvariable(" << type2str(tree2int(type)) << ' ' << tree2str(name) << ", " << tree2str(file) << ')';

    // block diagram binary operator
    else if (isBoxSeq(box, t1, t2))		streambinop(fout, t1, " : ", t2, 1, priority);
    else if (isBoxSplit(box, t1, t2))	streambinop(fout, t1, "<:", t2, 1, priority);
    else if (isBoxMerge(box, t1, t2)) 	streambinop(fout, t1, ":>", t2, 1, priority);
    else if (isBoxPar(box, t1, t2)) 	streambinop(fout, t1,",",t2, 2, priority);
    else if (isBoxRec(box, t1, t2)) 	streambinop(fout, t1,"~",t2, 4, priority);

    // iterative block diagram construction
    else if (isBoxIPar(box, t1, t2, t3)) 	fout << "par(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";
    else if (isBoxISeq(box, t1, t2, t3)) 	fout << "seq(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";
    else if (isBoxISum(box, t1, t2, t3)) 	fout << "sum(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";
    else if (isBoxIProd(box, t1, t2, t3)) 	fout << "prod(" << boxpp(t1) << ", " << boxpp(t2) << ") {" << boxpp(t3) << "}";

    else if (isBoxInputs(box, t1))          fout << "inputs(" << boxpp(t1) << ")";
    else if (isBoxOutputs(box, t1))         fout << "outputs(" << boxpp(t1) << ")";

    // user interface
    else if (isBoxButton(box, label))	fout << "button(" << tree2quotedstr(label) << ')';
    else if (isBoxCheckbox(box, label))	fout << "checkbox(" << tree2quotedstr(label) << ')';
    else if (isBoxVSlider(box, label, cur, min, max, step)) 	{
        fout << "vslider("
             << tree2quotedstr(label) << ", "
             << boxpp(cur) << ", "
             << boxpp(min) << ", "
             << boxpp(max) << ", "
             << boxpp(step)<< ')';
    }
    else if (isBoxHSlider(box, label, cur, min, max, step)) 	{
        fout << "hslider("
             << tree2quotedstr(label) << ", "
             << boxpp(cur) << ", "
             << boxpp(min) << ", "
             << boxpp(max) << ", "
             << boxpp(step)<< ')';
    }
    else if (isBoxVGroup(box, label, t1)) {
        fout << "vgroup(" << tree2quotedstr(label) << ", " << boxpp(t1, 0) << ')';
    }
    else if (isBoxHGroup(box, label, t1)) {
        fout << "hgroup(" << tree2quotedstr(label) << ", " << boxpp(t1, 0) << ')';
    }
    else if (isBoxTGroup(box, label, t1)) {
        fout << "tgroup(" << tree2quotedstr(label) << ", " << boxpp(t1, 0) << ')';
    }
    else if (isBoxHBargraph(box, label, min, max)) 	{
        fout << "hbargraph("
             << tree2quotedstr(label) << ", "
             << boxpp(min) << ", "
             << boxpp(max) << ')';
    }
    else if (isBoxVBargraph(box, label, min, max)) 	{
        fout << "vbargraph("
             << tree2quotedstr(label) << ", "
             << boxpp(min) << ", "
             << boxpp(max) << ')';
    }
    else if (isBoxNumEntry(box, label, cur, min, max, step)) 	{
        fout << "nentry("
             << tree2quotedstr(label) << ", "
             << boxpp(cur) << ", "
             << boxpp(min) << ", "
             << boxpp(max) << ", "
             << boxpp(step)<< ')';
    }
    else if (isNil(box)) {
        fout << "()" ;
    }
    else if (isList(box)) {

        Tree l = box;
        char sep = '(';

        do {
            fout << sep << boxpp(hd(l));
            sep = ',';
            l = tl(l);
        } while (isList(l));

        fout << ')';

    } else if (isBoxWaveform(box)) {
    
        fout << "waveform";
        char sep = '{';
        for (int i=0; i<box->arity(); i++) {
            fout << sep << boxpp(box->branch(i));
            sep = ',';
        }
        fout << '}';

        /*
        size_t n = box->arity();

        if (n < 6) {
            // small waveform, print all data
            fout << "waveform";
            char sep = '{';
            for (size_t i=0; i<n; i++) {
                fout << sep << boxpp(box->branch(i));
                sep = ',';
            }
            fout << '}';
        } else {
            // large waveform print only first and last values
            fout << "waveform{" << box->branch(0) << ", ..<" << n-2 << ">..," << box->branch(n-1) << "}";
        }
        */

    } else if (isBoxEnvironment(box)) {
        fout << "environment";

    } else if (isClosure(box, abstr, genv, vis, lenv)) {
        fout << "closure[" << boxpp(abstr)
             << ", genv = " << envpp(genv)
             << ", lenv = " << envpp(lenv)
             << "]";
    }
    else if (isBoxComponent(box, label)) {
        fout << "component("
             << tree2quotedstr(label) << ')';
    }
    else if (isBoxAccess(box, t1, t2)) {
        fout << boxpp(t1) << '.' << boxpp(t2);
    }
    else if (isImportFile(box, label)) {
        fout << "import("
             << tree2quotedstr(label) << ')';
    }
    else if (isBoxSlot(box, &id)) {
        //fout << "#" << id;
        fout << "x" << id;
    }
    else if (isBoxSymbolic(box, slot, body)) {
        fout << "\\(" << boxpp(slot) << ").(" << boxpp(body) << ")";
    }

    // Pattern Matching Extensions
    else if (isBoxCase(box, rules)) {
        fout << "case {";
        while (!isNil(rules)) {
            printRule(fout, hd(rules));
            rules = tl(rules);
        }
        fout << "}";
    }
#if 1
    // more useful for debugging output
    else if (isBoxPatternVar(box, ident)) {
        fout << "<" << boxpp(ident) << ">";
    }
#else
    // beautify messages involving lhs patterns
    else if (isBoxPatternVar(box, ident)) {
        fout << boxpp(ident);
    }
#endif

    else if (isBoxPatternMatcher(box)) {
        fout << "PM[" << box << "]";
    }

    else if (isBoxError(box)) {
        fout << "ERROR";
    }
   
    //else if (isImportFile(box, filename)) {
    //    printf("filename %s\n", tree2str(filename));
    //    fout << tree2quotedstr(filename);
    //}
   
    // None of the previous tests succeded, then it is not a valid box
    else {
        cerr << "Error in box::print() : " << *box << " is not a valid box" << endl;
        exit(1);
    }

    return fout;
}
Exemplo n.º 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;
}
Exemplo n.º 3
0
/**
 * 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
 *
 * @param fun the function to apply
 * @param larg the list of arguments
 * @return the resulting expression in normal form
 */
static Tree applyList (Tree fun, Tree larg)
{
	Tree abstr;
	Tree globalDefEnv;
	Tree visited;
	Tree localValEnv;
	Tree envList;
	Tree originalRules;
	Tree revParamList;

	Tree id;
	Tree body;
	
	Automaton*	automat;
	int			state;

	prim2	p2;

    //cerr << "applyList (" << *fun << ", " << *larg << ")" << endl;

	if (isNil(larg)) return fun;

	if (isBoxError(fun) || isBoxError(larg)) {
		return boxError();
	}

	if (isBoxPatternMatcher(fun, automat, state, envList, originalRules, revParamList)) {
		Tree 			result;
		int 			state2;
		vector<Tree>	envVect;
		
		list2vec(envList, envVect);
        //cerr << "applyList/apply_pattern_matcher(" << automat << "," << state << "," << *hd(larg) << ")" << endl;
		state2 = apply_pattern_matcher(automat, state, hd(larg), result, envVect);
        //cerr << "state2 = " << state2 << "; result = " << *result << endl;
		if (state2 >= 0 && isNil(result)) {
			// we need to continue the pattern matching
			return applyList(
						boxPatternMatcher(automat, state2, vec2list(envVect), originalRules, cons(hd(larg),revParamList)),
						tl(larg) );
		} else if (state2 < 0) {
		    stringstream error;
            error << "ERROR : pattern matching failed, no rule of " << boxpp(boxCase(originalRules)) 
				 << " matches argument list " << boxpp(reverse(cons(hd(larg), revParamList))) << endl;
            throw faustexception(error.str());
		} else {
			// Pattern Matching was succesful
			// the result is a closure that we need to evaluate.
			if (isClosure(result, body, globalDefEnv, visited, localValEnv)) {
				// why ??? return simplifyPattern(eval(body, nil, localValEnv));
				//return eval(body, nil, localValEnv);
				return applyList(eval(body, gGlobal->nil, localValEnv), tl(larg));
			} else {
				cerr << "wrong result from pattern matching (not a closure) : " << boxpp(result) << endl;
				return boxError();
			}
		}			
	}
	if (!isClosure(fun, abstr, globalDefEnv, visited, localValEnv)) {
		// principle : f(a,b,c,...) ==> (a,b,c,...):f
         int ins, outs;
         
         // check arity of function
         Tree efun = a2sb(fun);
         //cerr << "TRACEPOINT 1 : " << boxpp(efun) << endl;
         if (!getBoxType(efun, &ins, &outs)) { // on laisse comme ca pour le moment
         	// we can't determine the input arity of the expression
         	// hope for the best
         	return boxSeq(larg2par(larg), fun);
         }
 
         // check arity of arg list
         if (!boxlistOutputs(larg, &outs)) {
         	// we don't know yet the output arity of larg. Therefore we can't
         	// do any arity checking nor add _ to reach the required number of arguments
            // cerr << "warning : can't infere the type of : " << boxpp(larg) << endl;
         	return boxSeq(larg2par(larg), fun);
         }
		
		if (outs > ins) {
            stringstream error;
			error << "too much arguments : " << outs << ", instead of : " << ins << endl;
            error << "when applying : " << boxpp(fun) << endl
            << "to : " << boxpp(larg) << endl;
            throw faustexception(error.str());
		}
		
        if ((outs == 1)
            && (( isBoxPrim2(fun, &p2) && (p2 != sigPrefix))
            || (getUserData(fun) && ((xtended*)getUserData(fun))->isSpecialInfix()))) {
            // special case : /(3) ==> _,3 : /
            Tree larg2 = concat(nwires(ins-outs), larg);
            return boxSeq(larg2par(larg2), fun);

        } else {

			Tree larg2 = concat(larg, nwires(ins-outs));
            return boxSeq(larg2par(larg2), fun);
        }
	}

    if (isBoxEnvironment(abstr)) {
        evalerrorbox(yyfilename, -1, "an environment can't be used as a function", fun);
    }

    if (!isBoxAbstr(abstr, id, body)) {
        evalerror(yyfilename, -1, "(internal) not an abstraction inside closure", fun);
    }

	// try to synthetise a  name from the function name and the argument name
	{
		Tree arg = eval(hd(larg), visited, localValEnv);
		Tree narg; if ( isBoxNumeric(arg,narg) ) { arg =  narg; } 
		Tree f = eval(body, visited, pushValueDef(id, arg, localValEnv));

		Tree fname;
		if (getDefNameProperty(fun, fname)) {
			stringstream s; s << tree2str(fname); if (!gGlobal->gSimpleNames) s << "(" << boxpp(arg) << ")";
			setDefNameProperty(f, s.str());
		}
		return applyList(f, tl(larg));
	}
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
0
siglist realPropagate (Tree slotenv, Tree path, Tree box, const siglist&  lsig)
{
	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, chan;
    tvec    wf;
	
	
	xtended* xt = (xtended*)getUserData(box);
	
	// Extended Primitives
	
	if (xt)	{
		faustassert(lsig.size() == xt->arity());
		return makeList(xt->computeSigOutput(lsig));
	}
		
	// Numbers and Constants
	
	else if (isBoxInt(box, &i)) 	{ 
		faustassert(lsig.size()==0); 
		return makeList(sigInt(i)); 
	}
	else if (isBoxReal(box, &r)) 	{ 
		faustassert(lsig.size()==0); 
		return makeList(sigReal(r)); 
	}

    // A Waveform has two outputs it size and a period signal representing its content

    else if (isBoxWaveform(box)) 	{
        faustassert(lsig.size()==0);
        const tvec br = box->branches();
        return listConcat(makeList(sigInt(int(br.size()))), makeList(sigWaveform(br)));
    }

    else if (isBoxFConst(box, type, name, file))    { 
        faustassert(lsig.size()==0); 
        return makeList(sigFConst(type, name, file)); 
    }
    
    else if (isBoxFVar(box, type, name, file))    { 
        faustassert(lsig.size()==0); 
        return makeList(sigFVar(type, name, file)); 
    }
	
	// Wire and Cut
	
	else if (isBoxCut(box)) 				{ 
		faustassert(lsig.size()==1); 
		return siglist(); 
	}
	
	else if (isBoxWire(box)) 				{ 
		faustassert(lsig.size()==1); 
		return lsig;  
	}
	
	// Slots and Symbolic Boxes
	
	else if (isBoxSlot(box)) 				{ 
		Tree sig;
		faustassert(lsig.size()==0); 
		if (!searchEnv(box,sig,slotenv)) {
			// test YO simplification des diagrames
			//fprintf(stderr, "propagate : internal error (slot undefined)\n");
			sig = sigInput(++gGlobal->gDummyInput);
		}
		return makeList(sig);
	}
	
	else if (isBoxSymbolic(box, slot, body)) 				{ 
		faustassert(lsig.size()>0); 
		return propagate(pushEnv(slot,lsig[0],slotenv), path, body, listRange(lsig, 1, (int)lsig.size()));
	}
	
	// Primitives
	
	else if (isBoxPrim0(box, &p0)) 			{ 
		faustassert(lsig.size()==0); 
		return makeList(p0());
	}
	
	else if (isBoxPrim1(box, &p1)) 				{ 
		faustassert(lsig.size()==1); 
		return makeList(p1(lsig[0]));
	}
	
	else if (isBoxPrim2(box, &p2)) 				{ 
//		printf("prim2 recoit : "); print(lsig); printf("\n");
		faustassert(lsig.size()==2);
        if (p2 == &sigEnable) {
            if (gGlobal->gEnableFlag) {
                // special case for sigEnable that requires a transformation
                // enable(X,Y) -> sigEnable(X*Y, Y>0)
                return makeList(sigEnable( sigMul(lsig[0],lsig[1]), sigGT(lsig[1],sigReal(0.0))));
            } else {
                // We gEnableFlag is false we replace enable by a simple multiplication
                return makeList(sigMul(lsig[0],lsig[1]));
            }
        } else if (p2 == &sigControl) {
            if (gGlobal->gEnableFlag) {
                // special case for sigEnable that requires a transformation
                // enable(X,Y) -> sigEnable(X*Y, Y>0)
                return makeList(sigEnable( lsig[0], lsig[1]));
            } else {
                // We gEnableFlag is false we replace control by identity function
                return makeList(lsig[0]);
            }
        }
        return makeList( p2(lsig[0],lsig[1]) );
	}
	
	else if (isBoxPrim3(box, &p3)) 				{ 
		faustassert(lsig.size()==3); 
		return makeList(p3(lsig[0],lsig[1],lsig[2]));
	}
	
	else if (isBoxPrim4(box, &p4)) 				{ 
		faustassert(lsig.size()==4); 
		return makeList(p4(lsig[0],lsig[1],lsig[2],lsig[3]));
	}
	
	else if (isBoxPrim5(box, &p5)) 				{ 
		faustassert(lsig.size()==5); 
		return makeList(p5(lsig[0],lsig[1],lsig[2],lsig[3],lsig[4]));
	}
	
	else if (isBoxFFun(box, ff)) 				{ 
		//cerr << "propagate en boxFFun of arity " << ffarity(ff) << endl;
		faustassert(int(lsig.size())==ffarity(ff)); 
		return makeList(sigFFun(ff, listConvert(lsig)));  
	}
	
	// User Interface Widgets
	
	else if (isBoxButton(box, label)) 	{ 
		faustassert(lsig.size()==0); 
		return makeList(sigButton(normalizePath(cons(label, path)))); 
	}
	
	else if (isBoxCheckbox(box, label)) 	{ 
		faustassert(lsig.size()==0); 
		return makeList(sigCheckbox(normalizePath(cons(label, path)))); 
	}
	
	else if (isBoxVSlider(box, label, cur, min, max, step)) 	{ 
		faustassert(lsig.size()==0); 
		return makeList(sigVSlider(normalizePath(cons(label, path)), cur, min, max, step)); 
	}
	
	else if (isBoxHSlider(box, label, cur, min, max, step)) 	{ 
		faustassert(lsig.size()==0); 
		return makeList(sigHSlider(normalizePath(cons(label, path)), cur, min, max, step)); 
	}

	else if (isBoxNumEntry(box, label, cur, min, max, step)) 	{ 
		faustassert(lsig.size()==0); 
		return makeList(sigNumEntry(normalizePath(cons(label, path)), cur, min, max, step)); 
	}
	
	else if (isBoxVBargraph(box, label, min, max)) 	{ 
		faustassert(lsig.size()==1); 
		return makeList(sigVBargraph(normalizePath(cons(label, path)), min, max, lsig[0])); 
	}
	
	else if (isBoxHBargraph(box, label, min, max)) 	{ 
		faustassert(lsig.size()==1); 
		return makeList(sigHBargraph(normalizePath(cons(label, path)), min, max, lsig[0])); 
	}
	
	else if (isBoxSoundfile(box, label, chan)) 	{ 
		faustassert(lsig.size()==1);
        Tree fullpath = normalizePath(cons(label, path));
        Tree soundfile = sigSoundfile(fullpath);
        int c = tree2int(chan);
        siglist lsig2(c+3);
        lsig2[0] = sigSoundfileLength(soundfile);
        lsig2[1] = sigSoundfileRate(soundfile);
        lsig2[2] = sigSoundfileChannels(soundfile);

		// compute bound limited read index : int(max(0, min(ridx,length-1)))
		Tree ridx = sigIntCast(tree(gGlobal->gMaxPrim->symbol(), sigInt(0), tree(gGlobal->gMinPrim->symbol(), lsig[0], sigAdd(lsig2[0],sigInt(-1)))));
		for (int i = 0; i<c; i++) {
			lsig2[i+3] = sigSoundfileBuffer(soundfile, sigInt(i), ridx);
		}
		return lsig2; 
	}
	
	// User Interface Groups
	
	else if (isBoxVGroup(box, label, t1)) 	{ 
		return propagate(slotenv,cons(cons(tree(0),label), path), t1, lsig); 
	}
	
	else if (isBoxHGroup(box, label, t1)) 	{ 
		return propagate(slotenv, cons(cons(tree(1),label), path), t1, lsig); 
	}
	
	else if (isBoxTGroup(box, label, t1)) 	{ 
		return propagate(slotenv, cons(cons(tree(2),label), path), t1, lsig); 
	}
	
	// Block Diagram Composition Algebra
	
	else if (isBoxSeq(box, t1, t2)) 	{ 
		int in1, out1, in2, out2;
		getBoxType(t1, &in1, &out1);
		getBoxType(t2, &in2, &out2);

        faustassert(out1==in2);

		if (out1 == in2) {
			return propagate(slotenv, path, t2, propagate(slotenv, path,t1,lsig));
		} else if (out1 > in2) {
			siglist lr = propagate(slotenv, path, t1,lsig);
			return listConcat(propagate(slotenv, path, t2, listRange(lr, 0, in2)), listRange(lr, in2, out1));
		} else {
			return propagate(slotenv, path, t2, listConcat( propagate(slotenv, path, t1, listRange(lsig,0,in1)), listRange(lsig,in1,in1+in2-out1)));
		}
	}
	
	else if (isBoxPar(box, t1, t2)) 	{ 
		int in1, out1, in2, out2;
		getBoxType(t1, &in1, &out1);
		getBoxType(t2, &in2, &out2);
			
		return listConcat(propagate(slotenv, path, t1, listRange(lsig, 0,  in1)),
                          propagate(slotenv, path, t2, listRange(lsig, in1, in1+in2)));
	}
	
	else if (isBoxSplit(box, t1, t2)) 	{ 
		int in1, out1, in2, out2;
		getBoxType(t1, &in1, &out1);
		getBoxType(t2, &in2, &out2);
		
		siglist l1 = propagate(slotenv, path, t1, lsig);
		siglist l2 = split(l1, in2);
		return propagate(slotenv, path, t2, l2);
	}
	
	else if (isBoxMerge(box, t1, t2)) 	{ 
		int in1, out1, in2, out2;
		getBoxType(t1, &in1, &out1);
		getBoxType(t2, &in2, &out2);
		
		siglist l1 = propagate(slotenv, path, t1, lsig);
		siglist l2 = mix(l1, in2);
		return propagate(slotenv, path, t2, l2);
	}

    else if (isBoxRec(box, t1, t2)) 	{
        // Bug Corrected
        int in1, out1, in2, out2;
        getBoxType(t1, &in1, &out1);
        getBoxType(t2, &in2, &out2);

        Tree slotenv2 = lift(slotenv); // the environment must also be lifted

        siglist l0 = makeMemSigProjList(ref(1), in2);
        siglist l1 = propagate(slotenv2, path, t2, l0);
        siglist l2 = propagate(slotenv2, path, t1, listConcat(l1,listLift(lsig)));
		siglist l3 = (gGlobal->gFTZMode > 0) ? wrapWithFTZ(l2) : l2;
        Tree g = rec(listConvert(l3));
        return makeSigProjList(g, out1);
    }

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

	return siglist();
}