void LispLocalSymbols(LispEnvironment& aEnvironment, LispInt aStackTop) { LispInt nrArguments = InternalListLength(ARGUMENT(0)); LispInt nrSymbols = nrArguments-2; std::vector<const LispString*> names(nrSymbols); std::vector<const LispString*> localnames(nrSymbols); LispInt uniquenumber = aEnvironment.GetUniqueId(); LispInt i; for (i=0;i<nrSymbols;i++) { const LispString* atomname = Argument(ARGUMENT(0), i+1)->String(); CheckArg(atomname, i + 1, aEnvironment, aStackTop); names[i] = atomname; std::string newname = "$"; newname.append(*atomname); newname.append(std::to_string(uniquenumber)); localnames[i] = aEnvironment.HashTable().LookUp(newname); } LocalSymbolBehaviour behaviour(aEnvironment, std::move(names), std::move(localnames)); LispPtr result; InternalSubstitute(result, Argument(ARGUMENT(0), nrArguments-1), behaviour); InternalEval(aEnvironment, RESULT, result); }
void CheckNrArgs(int n, LispPtr& aArguments, LispEnvironment& aEnvironment) { const int nrArguments = InternalListLength(aArguments); if (nrArguments == n) return; const int needed = n-1; const int passed = nrArguments-1; ShowStack(aEnvironment); ShowFunctionError(aArguments, aEnvironment); aEnvironment.iErrorOutput << "expected " << needed << " arguments, got " << passed << "\n"; throw LispErrWrongNumberOfArgs(); }
void InfixPrinter::Print( const LispPtr& aExpression, std::ostream& aOutput, LispInt iPrecedence) { assert(aExpression); const LispString* string = aExpression->String(); if (string) { LispInt bracket = 0; if (iPrecedence < KMaxPrecedence && (*string)[0] == '-' && (std::isdigit((*string)[1]) || (*string)[1] == '.') ) { bracket = 1; } if (bracket) WriteToken(aOutput, "("); WriteToken(aOutput, *string); if (bracket) WriteToken(aOutput, ")"); return; } if (const GenericClass* g = aExpression->Generic()) { if (const AssociationClass* a = dynamic_cast<const AssociationClass*>(g)) { WriteToken(aOutput, "Association"); WriteToken(aOutput, "("); Print(a->ToList(), aOutput, KMaxPrecedence); WriteToken(aOutput, ")"); } else if (const ArrayClass* a = dynamic_cast<const ArrayClass*>(g)) { WriteToken(aOutput, "Array"); WriteToken(aOutput, "("); WriteToken(aOutput, "{"); const std::size_t n = a->Size(); for (std::size_t i = 1; i <= n; ++i) { Print(LispPtr(a->GetElement(i)), aOutput, KMaxPrecedence); if (i != n) WriteToken(aOutput, ","); } WriteToken(aOutput, "}"); WriteToken(aOutput, ")"); } else { WriteToken(aOutput, g->TypeName()); } return; } LispPtr* subList = aExpression->SubList(); if (!subList) { throw LispErrUnprintableToken(); } else { LispInt length = InternalListLength(*subList); string = (*subList)->String(); const LispOperators::const_iterator prefix = length != 2 ? iPrefixOperators.end() : iPrefixOperators.find(string); const LispOperators::const_iterator infix = length != 3 ? iInfixOperators.end() : iInfixOperators.find(string); const LispOperators::const_iterator postfix = length != 2 ? iPostfixOperators.end() : iPostfixOperators.find(string); const LispOperators::const_iterator bodied = iBodiedOperators.find(string); const LispInFixOperator* op = nullptr; if (prefix != iPrefixOperators.end()) op = &prefix->second; if (postfix != iPostfixOperators.end()) op = &postfix->second; if (infix != iInfixOperators.end()) op = &infix->second; if (op) { LispPtr* left = nullptr; LispPtr* right = nullptr; if (prefix != iPrefixOperators.end()) { right = &(*subList)->Nixed(); } else if (infix != iInfixOperators.end()) { left = &(*subList)->Nixed(); right = &(*subList)->Nixed()->Nixed(); } else if (postfix != iPostfixOperators.end()) { left = &(*subList)->Nixed(); } if (iPrecedence < op->iPrecedence) { WriteToken(aOutput, "("); } else { //Vladimir? aOutput.Write(" "); } if (left) Print(*left, aOutput, op->iLeftPrecedence); WriteToken(aOutput, *string); if (right) Print(*right, aOutput, op->iRightPrecedence); if (iPrecedence < op->iPrecedence) WriteToken(aOutput, ")"); } else { LispIterator iter((*subList)->Nixed()); if (string == iCurrentEnvironment->iList->String()) { WriteToken(aOutput, "{"); for (int ii = 0; iter.getObj(); ii++, ++iter) { if (ii) WriteToken(aOutput, ","); Print(*iter, aOutput, KMaxPrecedence); } WriteToken(aOutput, "}"); } else if (string == iCurrentEnvironment->iProg->String()) { WriteToken(aOutput, "["); while (iter.getObj()) { Print(*iter, aOutput, KMaxPrecedence); ++iter; WriteToken(aOutput, ";"); } WriteToken(aOutput, "]"); } else if (string == iCurrentEnvironment->iNth->String()) { Print(*iter, aOutput, 0); ++iter; WriteToken(aOutput, "["); Print(*iter, aOutput, KMaxPrecedence); WriteToken(aOutput, "]"); } else { LispInt bracket = false; if (bodied != iBodiedOperators.end()) { //printf("%d > %d\n",iPrecedence, bodied->iPrecedence); if (iPrecedence < bodied->second.iPrecedence) bracket = true; } if (bracket) WriteToken(aOutput, "("); if (string) { WriteToken(aOutput, *string); } else { Print(*subList, aOutput, 0); } WriteToken(aOutput, "("); LispIterator counter(*iter); LispInt nr = 0; while (counter.getObj()) { ++counter; nr++; } if (bodied != iBodiedOperators.end()) nr--; while (nr--) { Print(*iter, aOutput, KMaxPrecedence); ++iter; if (nr) WriteToken(aOutput, ","); } WriteToken(aOutput, ")"); if (iter.getObj()) { assert(bodied != iBodiedOperators.end()); Print(*iter, aOutput, bodied->second.iPrecedence); } if (bracket) WriteToken(aOutput, ")"); } } } }
const YacasParamMatcherBase* YacasPatternPredicateBase::MakeParamMatcher(LispEnvironment& aEnvironment, LispObject* aPattern) { if (!aPattern) return nullptr; if (aPattern->Number(aEnvironment.Precision())) return new MatchNumber(aPattern->Number(aEnvironment.Precision())); // Deal with atoms if (aPattern->String()) return new MatchAtom(aPattern->String()); // Else it must be a sublist if (aPattern->SubList()) { // See if it is a variable template: LispPtr* sublist = aPattern->SubList(); assert(sublist); LispInt num = InternalListLength(*sublist); // variable matcher here... if (num>1) { LispObject* head = (*sublist); if (head->String() == aEnvironment.HashTable().LookUp("_")) { LispObject* second = head->Nixed(); if (second->String()) { LispInt index = LookUp(second->String()); // Make a predicate for the type, if needed if (num>2) { LispPtr third; LispObject* predicate = second->Nixed(); if (predicate->SubList()) { InternalFlatCopy(third, *predicate->SubList()); } else { third = (second->Nixed()->Copy()); } LispObject* last = third; while (!!last->Nixed()) last = last->Nixed(); last->Nixed() = LispAtom::New(aEnvironment, *second->String()); iPredicates.push_back(LispPtr(LispSubList::New(third))); } return new MatchVariable(index); } } } std::vector<const YacasParamMatcherBase*> matchers; matchers.reserve(num); LispIterator iter(*sublist); for (LispInt i = 0; i < num; ++i, ++iter) { matchers.push_back(MakeParamMatcher(aEnvironment,iter.getObj())); assert(matchers[i]); } return new MatchSubList(std::move(matchers)); } return nullptr; }