示例#1
0
/**
 * Try to open the file '<dir>/<path>/<filename>'. If it succeed, it stores the full pathname
 * of the file into <fullpath>
 */
static FILE* fopenat(string& fullpath, const string& dir, const char* path, const char* filename)
{
    int	err;
    char olddirbuffer[FAUST_PATH_MAX];
    char newdirbuffer[FAUST_PATH_MAX];
    
    char* olddir = getcwd(olddirbuffer, FAUST_PATH_MAX);
    
    if (chdir(dir.c_str()) == 0) {
        if (chdir(path) == 0) {            
            FILE* f = fopen(filename, "r");
            char* newdir = getcwd(newdirbuffer, FAUST_PATH_MAX);
            if (!newdir) {
                stringstream error;
                error << "ERROR : getcwd '" << strerror(errno) << endl;
                throw faustexception(error.str());
            }
            fullpath = newdir;
			fullpath += '/';
			fullpath += filename;
            err = chdir(olddir);
            return f;
        }
    }
    err = chdir(olddir);
    if (err != 0) {
        stringstream error;
        error << "ERROR : cannot change back directory to '" << olddir << "' : " <<  strerror(errno) << endl;
        throw faustexception(error.str());
    }
    return 0;
}
示例#2
0
/**
 * codeAudioType(Type) -> Tree
 * Code an audio type as a tree in order to benefit of memoization
 * The type field (of the coded type) is used to store the audio
 * type
 */
Tree codeAudioType(AudioType* t)
{
    SimpleType 	*st;
    TableType   *tt;
    TupletType	*nt;

    Tree        r;

    if ((r=t->getCode())) return r;

    if ((st = isSimpleType(t))) {
        r = codeSimpleType(st);
    } else if ((tt = isTableType(t))) {
        r = codeTableType(tt);
    } else if ((nt = isTupletType(t))) {
        r = codeTupletType(nt);
    } else {
        stringstream error;
        error << "ERROR in codeAudioType() : invalide pointer " << t << endl;
        throw faustexception(error.str());
    }

    r->setType(t);
    return r;
}
示例#3
0
Type operator| ( const Type& t1, const Type& t2)
{
	SimpleType 	*st1, *st2;
	TableType	*tt1, *tt2;
	TupletType	*nt1, *nt2;

	if ( (st1 = isSimpleType(t1)) && (st2 = isSimpleType(t2)) ) {

        return makeSimpleType(	st1->nature()|st2->nature(),
					st1->variability()|st2->variability(),
					st1->computability()|st2->computability(),
					st1->vectorability()|st2->vectorability(),
					st1->boolean()|st2->boolean(),
                    reunion(st1->getInterval(), st2->getInterval())
					);

	} else if ( (tt1 = isTableType(t1)) && (tt2 = isTableType(t2)) ) {

        return makeTableType( tt1->content() | tt2->content() );

	} else if ( (nt1 = isTupletType(t1)) && (nt2 = isTupletType(t2)) ) {

		vector<Type> v;
		int n = min(nt1->arity(), nt2->arity());
		for (int i=0; i<n; i++) { v.push_back( (*nt1)[i] | (*nt2)[i]); }
		return new TupletType( v );

	} else {

	    stringstream error;
        error << "Error : trying to combine incompatible types, " << t1 << " and " << t2 << endl;
        throw faustexception(error.str());
        
	}
}
示例#4
0
文件: boxes.cpp 项目: EBone/Faust
Tree buildBoxAppl 	(Tree fun, Tree revarglist)
{
	if (isNil (revarglist)) {
        // a revoir !!!!!!
        throw faustexception("ERROR : buildBoxAppl called with null revarglist\n");
    }
	return  boxAppl(fun, revarglist);
}
示例#5
0
/**
 * Generate a "iota" time function, n-cyclical.
 */
string DocCompiler::generateIota (Tree sig, Tree n)
{
	int size;
	if (!isSigInt(n, &size)) { 
        throw faustexception("ERROR in generateIota\n");
    }
	//cout << "iota !" << endl;
	return subst(" t \\bmod{$0} ", docT(size));
}
示例#6
0
Type checkInit(Type t)
{
	// verifie que t est connu a l'initialisation
	if (t->computability() > kInit) {
        stringstream error;
        error << "Error : checkInit failed for type " << t << endl;
        throw faustexception(error.str());
	}
	return t;
}
示例#7
0
Type checkKonst(Type t)
{
	// verifie que t est constant
	if (t->variability() > kKonst) {
        stringstream error;
        error << "Error : checkKonst failed for type " << t << endl;
        throw faustexception(error.str());
	}
	return t;
}
示例#8
0
/**
 * Switch back to the previously stored current directory
 */
static int cholddir ()
{
	if (chdir(gGlobal->gCurrentDir.c_str()) == 0) {
		return 0;
	} else {
        stringstream error;
        error << "ERROR in cholddir " << strerror(errno) << endl;
        throw faustexception(error.str());
	}
}
示例#9
0
Type checkWRTbl(Type tbl, Type wr)
{
	// verifie que wr est compatible avec le contenu de tbl
	if (wr->nature() > tbl->nature()) {
        stringstream error;
        error << "Error : checkWRTbl failed, the content of  " << tbl << " is incompatible with " << wr << endl;
        throw faustexception(error.str());
	}
	return tbl;
}
示例#10
0
/**
 * @brief Main code generator dispatch.
 *
 * According to the type of the input signal, generateCode calls
 * the appropriate generator with appropriate arguments.
 *
 * @param	sig			The signal expression to compile.
 * @param	priority	The environment priority of the expression.
 * @return	<string>	The LaTeX code translation of the signal.
 */
string DocCompiler::generateCode (Tree sig, int priority)
{
	int 	i;
	double	r;
    Tree 	c, sel, x, y, z, u, label, ff, largs, type, name, file;
	
	if ( getUserData(sig) )							{ printGCCall(sig,"generateXtended");	return generateXtended	(sig, priority);		}
	else if ( isSigInt(sig, &i) ) 					{ printGCCall(sig,"generateNumber");	return generateNumber	(sig, docT(i));			}
	else if ( isSigReal(sig, &r) ) 					{ printGCCall(sig,"generateNumber");	return generateNumber	(sig, docT(r));			}
	else if ( isSigInput(sig, &i) ) 				{ printGCCall(sig,"generateInput");		return generateInput	(sig, docT(i+1)); 		}
	else if ( isSigOutput(sig, &i, x) ) 			{ printGCCall(sig,"generateOutput");	return generateOutput	(sig, docT(i+1), CS(x, priority));	}
	
	else if ( isSigFixDelay(sig, x, y) ) 			{ printGCCall(sig,"generateFixDelay");	return generateFixDelay	(sig, x, y, priority); 	}
	else if ( isSigPrefix(sig, x, y) ) 				{ printGCCall(sig,"generatePrefix");	return generatePrefix	(sig, x, y, priority); 	}
	else if ( isSigIota(sig, x) ) 					{ printGCCall(sig,"generateIota");		return generateIota 	(sig, x); 				}
	
	else if ( isSigBinOp(sig, &i, x, y) )			{ printGCCall(sig,"generateBinOp");		return generateBinOp	(sig, i, x, y, priority); 		}
	else if ( isSigFFun(sig, ff, largs) )			{ printGCCall(sig,"generateFFun");		return generateFFun 	(sig, ff, largs, priority); 	}
    else if ( isSigFConst(sig, type, name, file) )  { printGCCall(sig,"generateFConst");	return generateFConst	(sig, tree2str(file), tree2str(name)); }
    else if ( isSigFVar(sig, type, name, file) )    { printGCCall(sig,"generateFVar");		return generateFVar		(sig, tree2str(file), tree2str(name)); }
	
    // new special tables for documentation purposes

    else if ( isSigDocConstantTbl(sig, x, y) )      { printGCCall(sig,"generateDocConstantTbl");    return generateDocConstantTbl (sig, x, y);	}
    else if ( isSigDocWriteTbl(sig,x,y,z,u) )       { printGCCall(sig,"generateDocWriteTbl");       return generateDocWriteTbl (sig, x, y, z, u); }
    else if ( isSigDocAccessTbl(sig, x, y) )        { printGCCall(sig, "generateDocAccessTbl");     return generateDocAccessTbl(sig, x, y); }


	else if ( isSigSelect2(sig, sel, x, y) ) 		{ printGCCall(sig,"generateSelect2");	return generateSelect2 	(sig, sel, x, y, priority); 	}
	else if ( isSigSelect3(sig, sel, x, y, z) ) 	{ printGCCall(sig,"generateSelect3");	return generateSelect3 	(sig, sel, x, y, z, priority); 	}
	
    else if ( isProj(sig, &i, x) )                  { printGCCall(sig,"generateRecProj");	return generateRecProj	(sig, x, i, priority);	}
	
	else if ( isSigIntCast(sig, x) ) 				{ printGCCall(sig,"generateIntCast");	return generateIntCast	(sig, x, priority); 	}
	else if ( isSigFloatCast(sig, x) ) 				{ printGCCall(sig,"generateFloatCast");	return generateFloatCast(sig, x, priority); 	}
	
	else if ( isSigButton(sig, label) ) 			{ printGCCall(sig,"generateButton");	return generateButton   (sig, label); 			}
	else if ( isSigCheckbox(sig, label) ) 			{ printGCCall(sig,"generateCheckbox");	return generateCheckbox (sig, label); 			}
	else if ( isSigVSlider(sig, label,c,x,y,z) )	{ printGCCall(sig,"generateVSlider");	return generateVSlider 	(sig, label, c,x,y,z);	}
	else if ( isSigHSlider(sig, label,c,x,y,z) )	{ printGCCall(sig,"generateHSlider");	return generateHSlider 	(sig, label, c,x,y,z);	}
	else if ( isSigNumEntry(sig, label,c,x,y,z) )	{ printGCCall(sig,"generateNumEntry");	return generateNumEntry (sig, label, c,x,y,z);	}
	
	else if ( isSigVBargraph(sig, label,x,y,z) )	{ printGCCall(sig,"generateVBargraph");	return CS(z, priority);}//generateVBargraph 	(sig, label, x, y, CS(z, priority)); }
	else if ( isSigHBargraph(sig, label,x,y,z) )	{ printGCCall(sig,"generateHBargraph");	return CS(z, priority);}//generateHBargraph 	(sig, label, x, y, CS(z, priority)); }
    else if ( isSigAttach(sig, x, y) )				{ printGCCall(sig,"generateAttach");	return generateAttach	(sig, x, y, priority); }
    else if ( isSigEnable(sig, x, y) )				{ printGCCall(sig,"generateEnable");      return generateEnable	(sig, x, y, priority); }

	else {
        stringstream error;
        error << "ERROR in d signal, unrecognized signal : " << *sig << endl;
        throw faustexception(error.str());
	}
    faustassert(0);
	return "error in generate code";
}
示例#11
0
Type checkInt(Type t)
{
	// verifie que t est entier
	SimpleType* st = isSimpleType(t);
	if (st == 0 || st->nature() > kInt) {
        stringstream error;
        error << "Error : checkInt failed for type " << t << endl;
        throw faustexception(error.str());
	}
	return t;
}
示例#12
0
bool check_url(const char* filename)
{
    char* fileBuf = 0;
    
    // Tries to open as an URL for a local file
    if (strstr(filename, "file://") != 0) {
        // Tries to open as a regular file after removing 'file://'
        FILE* f = fopen(&filename[7], "r");
        if (f) {
            fclose(f);
            return true;
        } else {
            stringstream error;
            error << "ERROR : cannot open file '" << filename << "' : " << http_strerror() << "; for help type \"faust --help\"" << endl;
            throw faustexception(error.str());
        }
        // Tries to open as a http URL
    } else if (strstr(filename, "http://") != 0) {
        if (http_fetch(filename, &fileBuf) != -1) {
            return true;
        } else {
            stringstream error;
            error << "ERROR : unable to access URL '" << filename << "' : " << http_strerror() << "; for help type \"faust --help\"" << endl;
            throw faustexception(error.str());
        }
    } else {
        // Otherwise tries to open as a regular file
        FILE* f = fopen(filename, "r");
        if (f) {
            fclose(f);
            return true;
        } else {
            stringstream error;
            error << "ERROR : cannot open file '" << filename << "' : " <<  strerror(errno) << "; for help type \"faust --help\"" << endl;
            throw faustexception(error.str());
        }
    }
}
示例#13
0
/**
 * Open architecture file.
 */
static istream* openArchFile (const string& filename)
{
	istream* file;
	getCurrentDir();	// Save the current directory.
	if ( (file = open_arch_stream(filename.c_str())) ) {
		//cerr << "Documentator : openArchFile : Opening '" << filename << "'" << endl;
	} else {
        stringstream error;
        error << "ERROR : can't open architecture file " << filename << endl;
        throw faustexception(error.str());
	}
	cholddir();			// Return to current directory.
	return file;
}
示例#14
0
string DocCompiler::generateCacheCode(Tree sig, const string& exp)
{
	//cerr << "!! entering generateCacheCode with sig=\"" << ppsig(sig) << "\"" << endl;	
	
	string vname, ctype, code, vectorname;
	
	int sharing = getSharingCount(sig);
    Occurences* o = fOccMarkup.retrieve(sig);
	
	// check reentrance
    if (getCompiledExpression(sig, code)) {
		//cerr << "!! generateCacheCode called a true getCompiledExpression" << endl;
        return code;
    }
	
	// check for expression occuring in delays
	if (o->getMaxDelay()>0) {
        if (getVectorNameProperty(sig, vectorname)) {
			return exp;
		}
        getTypedNames(getCertifiedSigType(sig), "r", ctype, vname);
		gGlobal->gDocNoticeFlagMap["recursigs"] = true;
		//cerr << "- r : generateCacheCode : vame=\"" << vname << "\", for sig=\"" << ppsig(sig) << "\"" << endl;
        if (sharing>1) {
			//cerr << "      generateCacheCode calls generateDelayVec(generateVariableStore) on vame=\"" << vname << "\"" << endl;            
            return generateDelayVec(sig, generateVariableStore(sig,exp), ctype, vname, o->getMaxDelay());
        } else {
			//cerr << "      generateCacheCode calls generateDelayVec(exp) on vame=\"" << vname << "\"" << endl;            
		    return generateDelayVec(sig, exp, ctype, vname, o->getMaxDelay());
        }
	} 
	else if (sharing == 1 || getVectorNameProperty(sig, vectorname) || isVerySimpleFormula(sig)) {
		//cerr << "! generateCacheCode : sharing == 1 : return \"" << exp << "\"" << endl;
        return exp;
	} 
	else if (sharing > 1) {
		//cerr << "! generateCacheCode : sharing > 1 : return \"" << exp << "\"" << endl;
        return generateVariableStore(sig, exp);
	} 
	else {
        stringstream error;
        error << "ERROR in sharing count (" << sharing << ") for " << *sig << endl;
        throw faustexception(error.str());
	}
	
	return "Error in generateCacheCode";
}
示例#15
0
/**
 * Build a full pathname of <filename>.
 * <fullpath> = <currentdir>/<filename>
 */
static void buildFullPathname(string& fullpath, const char* filename)
{
	char old[FAUST_PATH_MAX];

	if (isAbsolutePathname(filename)) {
		fullpath = filename;
	} else {
        char* newdir = getcwd(old, FAUST_PATH_MAX);
        if (!newdir) {
            stringstream error;
            error << "ERROR : getcwd '" << strerror(errno) << endl;
            throw faustexception(error.str());
        }
        fullpath = newdir;
    	fullpath += '/';
		fullpath += filename;
	}
}
示例#16
0
/**
 * Try to do a numeric simplification of a block-diagram
 */
Tree numericBoxSimplification(Tree box)
{
    int     ins, outs;
    Tree    result;
    int     i;
    double  x;

    if (!getBoxType(box, &ins, &outs)) {
        stringstream error;
        error << "ERROR in file " << __FILE__ << ':' << __LINE__ << ", Can't compute the box type of : " << *box << endl;
        throw faustexception(error.str());
    }

    if (ins==0 && outs==1) {
        // this box can potentially denote a number
        if (isBoxInt(box, &i) || isBoxReal(box, &x)) {
           result = box;
        } else {
            // propagate signals to discover if it simplifies to a number
            int     i;
            double  x;
            Tree    lsignals = boxPropagateSig(gGlobal->nil, box , makeSigInputList(0));
            Tree    s = simplify(hd(lsignals));

            if (isSigReal(s, &x)) 	{
                result = boxReal(x);
            } else if (isSigInt(s, &i))  	{
                result = boxInt(i);
            } else {
                result = insideBoxSimplification(box);
            }
        }
    } else {
        // this box can't denote a number
        result = insideBoxSimplification(box);
    }
    return result;
}
示例#17
0
文件: propagate.cpp 项目: EBone/Faust
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();
}
示例#18
0
文件: boxes.cpp 项目: EBone/Faust
/**
 * 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 {
            stringstream error;
            error << "ERROR in preparePattern() : " << *box << " is not a valid box" << endl;
            throw faustexception(error.str());
        }

   return box;
}
示例#19
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));
	}
}
示例#20
0
/**
 * evallabel replace "...%2i..." occurences in label with value of i
 */
static const char * evalLabel (const char* src, Tree visited, Tree localValEnv)
{
    //std::cerr << "Eval Label : " << src;

    int             state = 0;  // current state
    std::string     dst;        // label once evaluated
    std::string     ident;      // current identifier
    std::string     format;     // current format

    while (state != -1) {

        char c = *src++;

        if (state == 0) {

            if (c == 0) {
                state = -1;
            } else if (c == '%') {
                ident = "";
                format = "";
                state = 1;
            } else {
                dst+=c;
                state = 0;
            }

        } else if (state == 1) {

            if (c == 0) {
                // fin et pas d'indentifiant, abandon
                dst += '%';
                dst += format;
                state = -1;
            } else if (isDigitChar(c)) {
                format += c;
                state = 1;
            } else if (isIdentChar(c)) {
                ident += c;
                state = 2;
            } else {
                // caractere de ponctuation et pas d'indentifiant, abandon
                dst += '%';
                dst += format;
                src--;
                state = 0;
            }

        } else if (state == 2) {

            if (isIdentChar(c)) {
                ident += c;
                state = 2;
            } else {
                writeIdentValue(dst, format, ident, visited, localValEnv);
                src--;
                state = 0;
            }

        } else {
            stringstream error;
            error << "internal error in evallabel : undefined state " << state << std::endl;
            throw faustexception(error.str());
        }
    }

    const char* val = strdup(dst.c_str());
    //std::cerr << "  ===> " << val << std::endl;
    return val;
}
示例#21
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;
}
示例#22
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;
}