Esempio n. 1
0
// (internal use only) turning argument expressions into values
// given that application itself is proper list, randExps is always
// either nil or pair
const SExp *evalArgs(const SExp *randExps, Environment *env) {
    if (sexpNil == randExps->tag)
        return newNil();

    const SExp *firstVal = evalDispatch(sexpCar(randExps), env);
    const SExp *restVals = evalArgs(sexpCdr(randExps), env);

    // if the evaluation for sub-exprs have failed,
    // stop this immediately
    if (firstVal == NULL || restVals == NULL)
        return NULL;

    const SExp *retVal = newPair(firstVal,restVals);
    // here we cannot recursively de-allocate the resource,
    // because eval-handlers might return an existing pointer as results
    // which means the value returned might be allocated somewhere else.
    pointerManagerRegister(retVal);
    return retVal;
}
Esempio n. 2
0
// apply arguments to a function object
const SExp *funcObjApp(const FuncObj *rator, const SExp *rands, Environment *env) {
    assert(rator && "operator cannot be NULL");
    switch (rator->tag) {
    case funcPrim: {
        FuncPrimHandler handler = rator->fields.primHdlr;
        const SExp *randVals = evalArgs(rands,env);
        return handler(randVals);
    }
    case funcCompound: {
        FuncCompound fc = rator->fields.compObj;
        const SExp *ps = fc.parameters;
        const SExp *bd = fc.body;
        Environment *fenv = fc.env;

        Environment *appEnv = calloc(1,sizeof(Environment));
        envInit(appEnv);
        pointerManagerRegisterCustom(appEnv, (PFreeCallback)releaseTempEnv);
        envSetParent(appEnv, fenv);

        while (sexpNil != rands->tag && sexpNil != ps->tag ) {
            if (sexpSymbol != sexpCar( ps )->tag)
                return NULL;
            char *varName = sexpCar( ps )->fields.symbolName;
            const SExp *rand = sexpCar( rands );
            const SExp *randVal = evalDispatch(rand, env);
            if (!randVal) return NULL;
            envInsert(appEnv, varName, randVal);
            rands = sexpCdr(rands);
            ps = sexpCdr(ps);
        }
        if (! (sexpNil == rands->tag && sexpNil == ps->tag) )
            return NULL;
        // execute body under new environment
        return evSequence(bd, appEnv);
    }
    }
    assert(0 && "invalid function object");
}
Esempio n. 3
0
void
SeExprFuncNode::eval(SeVec3d& result) const
{
    if (!_func) { result = 0.0; return; }

    // funcx is a catchall that does all its own processing
    if (_func->type() == SeExprFunc::FUNCX) {
	_func->funcx()->eval(this, result);
	return;
    }

    // handle the case of a scalar func applied to a vector
    bool applyScalarToVec = _isVec && !_func->isVec();
    int niter = applyScalarToVec ? 3 : 1;

    // eval args and call the function
    SeVec3d* a = evalArgs();
    for (int i = 0; i < niter; i++) {
	switch (_func->type()) {
	default: 
	    result[i] = result[1] = result[2] = 0;
	    break;
	case SeExprFunc::FUNC0:
	    result[i] = _func->func0()(); 
	    break;
	case SeExprFunc::FUNC1:
	    result[i] = _func->func1()(a[0][i]);
	    break;
	case SeExprFunc::FUNC2:
	    result[i] = _func->func2()(a[0][i], a[1][i]);
	    break;
	case SeExprFunc::FUNC3:
	    result[i] = _func->func3()(a[0][i], a[1][i], a[2][i]);
	    break;
	case SeExprFunc::FUNC4:
	    result[i] = _func->func4()(a[0][i], a[1][i], a[2][i], a[3][i]);
	    break;
	case SeExprFunc::FUNC5:
	    result[i] = _func->func5()(a[0][i], a[1][i], a[2][i], a[3][i],
				       a[4][i]);
	    break;
	case SeExprFunc::FUNC6:
	    result[i] = _func->func6()(a[0][i], a[1][i], a[2][i], a[3][i],
				       a[4][i], a[5][i]);
	    break;
	case SeExprFunc::FUNCN: 
	    {
		double* d = scalarArgs();
		for (int n = 0; n < _nargs; n++) d[n] = a[n][i];
		result[i] = _func->funcn()(_nargs, d);
		break;
	    }
	case SeExprFunc::FUNC1V:
	    result[i] = _func->func1v()(a[0]);
	    break;
	case SeExprFunc::FUNC2V:
	    result[i] = _func->func2v()(a[0], a[1]);
	    break;
	case SeExprFunc::FUNCNV: 
	    result[i] = _func->funcnv()(_nargs, a);
	    break;
	case SeExprFunc::FUNC1VV:
	    result = _func->func1vv()(a[0]);
	    break;
	case SeExprFunc::FUNC2VV:
	    result = _func->func2vv()(a[0], a[1]);
	    break;
	case SeExprFunc::FUNCNVV: 
	    result = _func->funcnvv()(_nargs, a);
	    break;
	}
    }

}