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

void BasicEvaluator::Eval ( LispEnvironment aEnvironment,
LispPtr aResult,
LispPtr aExpression 
) [virtual]

Evaluate a Lisp expression

Parameters:
aEnvironment the Lisp environment, in which the evaluation should take place.
aResult the result of the evaluation.
aExpression the expression to evaluate.
First, the evaluation depth is checked. An error is raised if the maximum evaluation depth is exceeded.

The next step is the actual evaluation. aExpression is a LispObject, so we can distinguish three cases.

  • If aExpression is a string starting with " , it is simply copied in aResult. If it starts with another character (this includes the case where it represents a number), the environment is checked to see whether a variable with this name exists. If it does, its value is copied in aResult, otherwise aExpression is copied.
  • If aExpression is a list, the head of the list is examined. If the head is not a string. InternalApplyPure() is called. If the head is a string, it is checked against the core commands; if there is a check, the corresponding evaluator is called. Then it is checked agaist the list of user function with GetUserFunction() . Again, the corresponding evaluator is called if there is a check. If all fails, ReturnUnEvaluated() is called.
  • Otherwise (ie. if aExpression is a generic object), it is copied in aResult.

Note:
The result of this operation must be a unique (copied) element! Eg. its Next might be set...

Implements LispEvaluatorBase.

Definition at line 107 of file lispeval.cpp.

References LispObject::Copy(), LispEnvironment::CoreCommands(), LispUserFunction::Evaluate(), LispPtr::Get(), LispEnvironment::GetVariable(), LispEnvironment::iEvalDepth, LispEnvironment::iMaxEvalDepth, LispAssociatedHash< T >::LookUp(), LispObject::Next(), LispPtr::Set(), LispObject::String(), and LispObject::SubList().

{
    LISPASSERT(aExpression.Get() != NULL);

    aEnvironment.iEvalDepth++;
    if (aEnvironment.iEvalDepth>=aEnvironment.iMaxEvalDepth)
    {
        if (aEnvironment.iEvalDepth>aEnvironment.iMaxEvalDepth+20)
        {
            CHK2(aEnvironment.iEvalDepth<aEnvironment.iMaxEvalDepth,
                 KLispErrUserInterrupt);
        }
        else
        {
            CHK2(aEnvironment.iEvalDepth<aEnvironment.iMaxEvalDepth,
                 KLispErrMaxRecurseDepthReached);
        }
    }

    LispStringPtr str = aExpression.Get()->String();
    CHECKPTR(str);

    // Evaluate an atom: find the bound value (treat it as a variable)
    if (str)
    {
        if (str->String()[0] == '\"')
        {
            aResult.Set(aExpression.Get()->Copy(LispFalse));
            goto FINISH;
        }

        LispPtr val;
        aEnvironment.GetVariable(str,val);
        if (val.Get())
        {
            aResult.Set(val.Get()->Copy(LispFalse));
            goto FINISH;
        }
        aResult.Set(aExpression.Get()->Copy(LispFalse));
        goto FINISH;
    }

    {
//        EvalFuncBase* func = NULL;
        LispPtr* subList = aExpression.Get()->SubList();

//        if (func)
//        {
//            func->Evaluate(aResult, aEnvironment, *subList);
//            goto FINISH;
//        }
        if (subList)
        {
            LispObject* head = subList->Get();
            if (head)
            {
                if (head->String())
                {
                  {
                    YacasEvaluator* evaluator = aEnvironment.CoreCommands().LookUp(head->String());
                    // Try to find a built-in command
                    if (evaluator)
                    {
                        evaluator->Evaluate(aResult, aEnvironment, *subList);
                        goto FINISH;
                    }
                  }

//                    else // Else try to find a user-defined function
                    {
                        LispUserFunction* userFunc;
                        userFunc = GetUserFunction(aEnvironment, subList);
                        CHECKPTR(userFunc);
                        if (userFunc != NULL)
                        {
                            userFunc->Evaluate(aResult,aEnvironment,*subList);
                            goto FINISH;
                        }
                    }
                }
                else
                {
                    //printf("ApplyPure!\n");
                    LispPtr oper;
                    LispPtr args2;
                    oper.Set(subList->Get());
                    args2.Set(subList->Get()->Next().Get());
                    InternalApplyPure(oper,args2,aResult,aEnvironment);
                    goto FINISH;
                }
                //printf("**** Undef: %s\n",head->String()->String());
                ReturnUnEvaluated(aResult,*subList,aEnvironment);
                goto FINISH;
            }
        }
        aResult.Set(aExpression.Get()->Copy(LispFalse));
    }
FINISH:

    aEnvironment.iEvalDepth--;
}


Generated by  Doxygen 1.6.0   Back to index