File indexing completed on 2024-04-28 03:40:38

0001 /*************************************************************************************
0002  *  Copyright (C) 2010 by Aleix Pol <aleixpol@kde.org>                               *
0003  *                                                                                   *
0004  *  This program is free software; you can redistribute it and/or                    *
0005  *  modify it under the terms of the GNU General Public License                      *
0006  *  as published by the Free Software Foundation; either version 2                   *
0007  *  of the License, or (at your option) any later version.                           *
0008  *                                                                                   *
0009  *  This program is distributed in the hope that it will be useful,                  *
0010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of                   *
0011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                    *
0012  *  GNU General Public License for more details.                                     *
0013  *                                                                                   *
0014  *  You should have received a copy of the GNU General Public License                *
0015  *  along with this program; if not, write to the Free Software                      *
0016  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA   *
0017  *************************************************************************************/
0018 
0019 
0020 #include "abstractexpressiontransformer.h"
0021 #include "list.h"
0022 #include "container.h"
0023 #include "vector.h"
0024 #include "apply.h"
0025 #include "variable.h"
0026 #include "matrix.h"
0027 
0028 using namespace Analitza;
0029 
0030 AbstractExpressionTransformer::~AbstractExpressionTransformer()
0031 {}
0032 
0033 #define ITERATION_WALKER(T, ...)\
0034 Object* AbstractExpressionTransformer::walk##T(const T* pattern)\
0035 {\
0036     T* ret = new T(__VA_ARGS__);\
0037     T ::const_iterator it=pattern->constBegin(), itEnd=pattern->constEnd();\
0038     for(; it!=itEnd; ++it) {\
0039         ret->appendBranch(walk(*it));\
0040     }\
0041     return ret;\
0042 }
0043 
0044 ITERATION_WALKER(List, {})
0045 ITERATION_WALKER(MatrixRow, pattern->size())
0046 ITERATION_WALKER(Vector, pattern->size())
0047 ITERATION_WALKER(Container, pattern->containerType())
0048 
0049 Object* AbstractExpressionTransformer::walk(const Object* pattern)
0050 {
0051     if(!pattern)
0052         return nullptr;
0053     
0054     switch(pattern->type()) {
0055         case Object::apply:
0056             return walkApply(static_cast<const Apply*>(pattern));
0057         case Object::variable:
0058             return walkVariable(static_cast<const Ci*>(pattern));
0059         case Object::container:
0060             return walkContainer(static_cast<const Container*>(pattern));
0061         case Object::list:
0062             return walkList(static_cast<const List*>(pattern));
0063         case Object::vector:
0064             return walkVector(static_cast<const Vector*>(pattern));
0065         case Object::matrix:
0066             return walkMatrix(static_cast<const Matrix*>(pattern));
0067         case Object::matrixrow:
0068             return walkMatrixRow(static_cast<const MatrixRow*>(pattern));
0069         case Object::oper:
0070         case Object::value:
0071         case Object::custom:
0072             return pattern->copy();
0073         case Object::none:
0074             break;
0075     }
0076     
0077     Q_ASSERT(false);
0078     return nullptr;
0079 }
0080 
0081 Object* AbstractExpressionTransformer::walkApply(const Analitza::Apply* pattern)
0082 {
0083     Apply* ret = new Apply;
0084     ret->ulimit()=walk(pattern->ulimit());
0085     ret->dlimit()=walk(pattern->dlimit());
0086     ret->domain()=walk(pattern->domain());
0087     
0088     if(pattern->firstOperator().isCorrect()) {
0089         Operator op = pattern->firstOperator();
0090         ret->appendBranch(walk(&op));
0091     }
0092     
0093     Apply::const_iterator it=pattern->firstValue(), itEnd=pattern->constEnd();
0094     for(; it!=itEnd; ++it)
0095         ret->appendBranch(walk(*it));
0096     
0097     return ret;
0098 }
0099 
0100 Object* AbstractExpressionTransformer::walkVariable(const Analitza::Ci* pattern)
0101 {
0102     return pattern->copy();
0103 }
0104 
0105 Object* AbstractExpressionTransformer::walkMatrix(const Matrix* pattern)
0106 {
0107     Matrix* ret = new Matrix;
0108     Matrix::const_iterator it=pattern->constBegin(), itEnd=pattern->constEnd();
0109     for(; it!=itEnd; ++it) {
0110         ret->appendBranch(static_cast<MatrixRow*>(walk(*it)));
0111     }
0112     return ret;
0113 }