Example #1
0
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);
}
Example #2
0
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();
}
Example #3
0
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, ")");
            }
        }
    }
}
Example #4
0
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;
}