void YacasPatternPredicateBase::SetPatternVariables(LispEnvironment& aEnvironment, LispPtr* arguments) { const std::size_t n = iVariables.size(); for (std::size_t i = 0; i < n; ++i) aEnvironment.NewLocal(iVariables[i],arguments[i]); }
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); }
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; } }