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

YacasParamMatcherBase * YacasPatternPredicateBase::MakeParamMatcher ( LispEnvironment aEnvironment,
LispObject aPattern 
) [protected]

Construct a pattern matcher out of a Lisp expression. The result of this function depends on the value of aPattern:

  • If aPattern is a number, the corresponding MatchNumber is constructed and returned.
  • If aPattern is an atom, the corresponding MatchAtom is constructed and returned.
  • If aPattern is a list of the form ( _ var ), where var is an atom, LookUp() is called on var. Then the correspoding MatchVariable is constructed and returned.
  • If aPattern is a list of the form ( _ var expr ), where var is an atom, LookUp() is called on var. Then, expr is appended to iPredicates. Finally, the correspoding MatchVariable is constructed and returned.
  • If aPattern is a list of another form, this function calls itself on any of the entries in this list. The resulting YacasParamMatcherBase objects are collected in a MatchSubList, which is returned.
  • Otherwise, this function returns NULL.

Definition at line 166 of file patterns.cpp.

References CArrayGrower< T >::Append(), LispObject::Copy(), LispPtr::Get(), LispIterator::GoNext(), LispEnvironment::HashTable(), iPredicates, LookUp(), LispHashTable::LookUp(), LispObject::Next(), LispObject::Number(), LispEnvironment::Precision(), LispPtr::Set(), LispObject::String(), and LispObject::SubList().

Referenced by YacasPatternPredicateBase().

{
    if (aPattern == NULL)
        return NULL;
#ifdef MATCH_NUMBERS
    if (aPattern->Number(aEnvironment.Precision()))
    {
        return NEW MatchNumber(aPattern->Number(aEnvironment.Precision()));
    }
#endif
    // 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();
        LISPASSERT(sublist != NULL);

        LispInt num = InternalListLength(*sublist);

        // variable matcher here...
        if (num>1)
        {
            LispObject* head = sublist->Get();
            if (head->String() == aEnvironment.HashTable().LookUp("_"))
            {
                LispObject* second = head->Next().Get();
                if (second->String() != NULL)
                {
                    LispInt index = LookUp(second->String());

                    // Make a predicate for the type, if needed
                    if (num>2)
                    {
                        LispPtr third;

                        LispObject* predicate = second->Next().Get();
                        if (predicate->SubList() != NULL)
                        {
                            InternalFlatCopy(third, *predicate->SubList());
                        }
                        else
                        {
                            third.Set(second->Next().Get()->Copy(LispFalse));
                        }

                        LispCharPtr str = second->String()->String();
                        LispObject* last = third.Get();
                        while (last->Next().Get() != NULL)
                            last = last->Next().Get();
                        
                        last->Next().Set(LispAtom::New(aEnvironment,str));

//                        third.Get()->Next().Set(LispAtom::New(aEnvironment,aEnvironment.HashTable().LookUp(str)));
                        LispPtr *pred = NEW LispPtr;
                        pred->Set(LispSubList::New(third.Get()));
#ifdef YACAS_DEBUG
                        third.Get()->Next().Get()->SetFileAndLine(second->iFileName,second->iLine);
                        pred->Get()->SetFileAndLine(head->iFileName,head->iLine);
#endif
//LispPtr hold;
//hold.Set(pred->Get());
//aEnvironment.CurrentPrinter().Print(*pred,
//                                    *aEnvironment.CurrentOutput());

                        iPredicates.Append(pred);
                    }
                    return NEW MatchVariable(index);
                }
            }
        }
        
        YacasParamMatcherBase** matchers = (YacasParamMatcherBase**)PlatAlloc(num*sizeof(YacasParamMatcherBase*));

        LispInt i;
        LispIterator iter(*sublist);
        for (i=0;i<num;i++)
        {
            matchers[i] = MakeParamMatcher(aEnvironment,iter());
            LISPASSERT(matchers[i] != NULL);
            iter.GoNext();
        }
        return NEW MatchSubList(matchers, num);
    }
    
    return NULL;
}


Generated by  Doxygen 1.6.0   Back to index