Logo Search packages:      
Sourcecode: yacas version File versions  Download package

void BranchingUserFunction::Evaluate ( LispPtr aResult,
LispEnvironment aEnvironment,
LispPtr aArguments 
) [virtual]

Evaluate the function on given arguments.

Parameters:
aResult (on output) the result of the evaluation
aEnvironment the underlying Lisp environment
aArguments the arguments to the function
First, all arguments are evaluated by the evaluator associated to aEnvironment, unless the iHold flag of the corresponding parameter is true. Then a new LispLocalFrame is constructed, in which the actual arguments are assigned to the names of the formal arguments, as stored in iParameter. Then all rules in iRules are tried one by one. The body of the first rule that matches is evaluated, and the result is put in aResult. If no rule matches, aResult will recieve a new expression with evaluated arguments.

Implements LispUserFunction.

Definition at line 77 of file mathuserfunc.cpp.

References Arity(), BranchingUserFunction::BranchRuleBase::Body(), LispObject::Copy(), LispPtr::Get(), LispIterator::GoNext(), LispEnvironment::iEvaluator, iParameters, iRules, BranchingUserFunction::BranchRuleBase::Matches(), LispEnvironment::NewLocal(), LispObject::Next(), BranchingUserFunction::BranchRuleBase::Precedence(), LispIterator::Ptr(), LispPtr::Set(), and LispEvaluatorBase::StackInformation().

{
    LispInt arity = Arity();
    LispInt i;

    //hier
    if (Traced())
    {
        LispPtr tr;
        tr.Set(LispSubList::New(aArguments.Get()));
        TraceShowEnter(aEnvironment,tr);
        tr.Set(NULL);
    }

    LispIterator iter(aArguments);
    iter.GoNext();

    // unrollable arguments 
    LispPtr* arguments;
    if (arity==0)
        arguments = NULL;
    else
    {
        LISPASSERT(arity>0);
        arguments = NEW LispPtr[arity];
    }
    LocalArgs args(arguments);

    // Walk over all arguments, evaluating them as necessary
    for (i=0;i<arity;i++)
    {
        Check(iter() != NULL, KLispErrWrongNumberOfArgs);
        if (iParameters[i].iHold)
        {
            arguments[i].Set(iter()->Copy(LispFalse));
        }
        else
        {
            Check(iter.Ptr() != NULL, KLispErrWrongNumberOfArgs);
            InternalEval(aEnvironment, arguments[i], *iter.Ptr());
        }
        iter.GoNext();
    }

    if (Traced())
    {
        LispIterator iter(aArguments);
        iter.GoNext();
        for (i=0;i<arity;i++)
        {
            TraceShowArg(aEnvironment,*iter.Ptr(),
                  arguments[i]);

            iter.GoNext();
        }
    }
    
    // declare a new local stack.
    LispLocalFrame frame(aEnvironment,Fenced());

    // define the local variables.
    for (i=0;i<arity;i++)
    {
        LispStringPtr variable = iParameters[i].iParameter;
        // set the variable to the new value
        aEnvironment.NewLocal(variable,arguments[i].Get());
    }

    // walk the rules database, returning the evaluated result if the
    // predicate is LispTrue.
    LispInt nrRules = iRules.NrItems();
    UserStackInformation &st = aEnvironment.iEvaluator->StackInformation();
    for (i=0;i<nrRules;i++)
    {
        BranchRuleBase* thisRule = iRules[i];
        CHECKPTR(thisRule);
        LISPASSERT(thisRule != NULL);

        st.iRulePrecedence = thisRule->Precedence();
        LispBoolean matches = thisRule->Matches(aEnvironment, arguments);
        if (matches)
        {
            st.iSide = 1;
            InternalEval(aEnvironment, aResult, thisRule->Body());
            goto FINISH;
        }

        // If rules got inserted, walk back
        while (thisRule != iRules[i] && i>0) i--;
    }
    
    // No predicate was LispTrue: return a new expression with the evaluated
    // arguments.

    {
        LispPtr full;
        full.Set(aArguments.Get()->Copy(LispFalse));
        if (arity == 0)
        {
            full.Get()->Next().Set(NULL);
        }
        else
        {
            full.Get()->Next().Set(arguments[0].Get());
            for (i=0;i<arity-1;i++)
            {
                arguments[i].Get()->Next().Set(arguments[i+1].Get());
            }
        }
        aResult.Set(LispSubList::New(full.Get()));
    }

FINISH:
    if (Traced())
    {
        LispPtr tr;
        tr.Set(LispSubList::New(aArguments.Get()));
        TraceShowLeave(aEnvironment, aResult,tr);
        tr.Set(NULL);
    }
}


Generated by  Doxygen 1.6.0   Back to index