Пример #1
0
void InternalApplyPure(LispPtr& oper,LispPtr& args2,LispPtr& aResult,LispEnvironment& aEnvironment)
{
    LispPtr * chk1 = oper->SubList();

    if (!chk1)
        throw LispErrInvalidArg();

    LispPtr oper2((*chk1)->Nixed());

    if (!oper2)
        throw LispErrInvalidArg();

    LispPtr body(oper2->Nixed());

    if (!body)
        throw LispErrInvalidArg();

    LispPtr * chk2 = oper2->SubList();

    if (!chk2 || !*chk2)
        throw LispErrInvalidArg();

    oper2 = ((*chk2)->Nixed());

    LispLocalFrame frame(aEnvironment,false);

    while (!!oper2)  {
        if (!args2)
            throw LispErrInvalidArg();

        const LispString* var = oper2->String();

        if (!var)
            throw LispErrInvalidArg();

        LispPtr newly(args2->Copy());

        aEnvironment.NewLocal(var,newly);

        oper2 = (oper2->Nixed());

        args2 = (args2->Nixed());
    }

    if (args2)
        throw LispErrInvalidArg();

    aEnvironment.iEvaluator->Eval(aEnvironment, aResult, body);
}
Пример #2
0
void ReturnUnEvaluated(LispPtr& aResult,LispPtr& aArguments,
                       LispEnvironment& aEnvironment)
{
    LispPtr full(aArguments->Copy());
    aResult = (LispSubList::New(full));

    LispIterator iter(aArguments);
    ++iter;

    while (iter.getObj())
    {
        LispPtr next;
        aEnvironment.iEvaluator->Eval(aEnvironment, next, *iter);
        full->Nixed() = (next);
        full = (next);
        ++iter;
    }
    full->Nixed() = (nullptr);
}
Пример #3
0
void BranchingUserFunction::Evaluate(LispPtr& aResult,LispEnvironment& aEnvironment,
                                     LispPtr& aArguments)
{
    const LispInt arity = Arity();
    LispInt i;

    if (Traced()) {
        LispPtr tr(LispSubList::New(aArguments));
        TraceShowEnter(aEnvironment, tr);
        tr = nullptr;
    }

    LispIterator iter(aArguments);
    ++iter;

    // unrollable arguments
    std::unique_ptr<LispPtr[]> arguments(arity == 0 ? nullptr : new LispPtr[arity]);

    // Walk over all arguments, evaluating them as necessary
    for (i = 0; i < arity; i++, ++iter) {
        if (!iter.getObj())
            throw LispErrWrongNumberOfArgs();

        if (iParameters[i].iHold) {
            arguments[i] = iter.getObj()->Copy();
        } else {
            //Check(iter.getObj(), KLispErrWrongNumberOfArgs);  // checked above
            InternalEval(aEnvironment, arguments[i], *iter);
        }
    }

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

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

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

    // walk the rules database, returning the evaluated result if the
    // predicate is true.
    const std::size_t nrRules = iRules.size();
    UserStackInformation &st = aEnvironment.iEvaluator->StackInformation();
    for (std::size_t i = 0; i < nrRules; i++) {
        BranchRuleBase* thisRule = iRules[i];
        assert(thisRule);

        st.iRulePrecedence = thisRule->Precedence();
        bool matches = thisRule->Matches(aEnvironment, arguments.get());
        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 true: return a new expression with the evaluated
    // arguments.

    {
        LispPtr full(aArguments->Copy());
        if (arity == 0) {
            full->Nixed() = nullptr;
        } else {
            full->Nixed() = arguments[0];
            for (i = 0; i < arity - 1; i++)
                arguments[i]->Nixed() = arguments[i + 1];
        }
        aResult = LispSubList::New(full);
    }

FINISH:
    if (Traced()) {
        LispPtr tr(LispSubList::New(aArguments));
        TraceShowLeave(aEnvironment, aResult, tr);
        tr = nullptr;
    }
}