~ubuntu-branches/ubuntu/trusty/kalgebra/trusty-updates

« back to all changes in this revision

Viewing changes to analitza/stringexpressionwriter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Philip Muškovac
  • Date: 2011-07-08 20:10:34 UTC
  • Revision ID: james.westby@ubuntu.com-20110708201034-0cqpagx7uz4pu82n
Tags: upstream-4.6.90+repack1
Import upstream version 4.6.90+repack1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*************************************************************************************
 
2
 *  Copyright (C) 2008 by Aleix Pol <aleixpol@kde.org>                               *
 
3
 *                                                                                   *
 
4
 *  This program is free software; you can redistribute it and/or                    *
 
5
 *  modify it under the terms of the GNU General Public License                      *
 
6
 *  as published by the Free Software Foundation; either version 2                   *
 
7
 *  of the License, or (at your option) any later version.                           *
 
8
 *                                                                                   *
 
9
 *  This program is distributed in the hope that it will be useful,                  *
 
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of                   *
 
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                    *
 
12
 *  GNU General Public License for more details.                                     *
 
13
 *                                                                                   *
 
14
 *  You should have received a copy of the GNU General Public License                *
 
15
 *  along with this program; if not, write to the Free Software                      *
 
16
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA   *
 
17
 *************************************************************************************/
 
18
 
 
19
#include "stringexpressionwriter.h"
 
20
#include "value.h"
 
21
#include "vector.h"
 
22
#include "operator.h"
 
23
#include "container.h"
 
24
#include <QStringList>
 
25
#include "list.h"
 
26
#include "variable.h"
 
27
#include "apply.h"
 
28
#include "analitzautils.h"
 
29
 
 
30
using namespace Analitza;
 
31
 
 
32
template <class T>
 
33
QStringList StringExpressionWriter::allValues(T it, const T& itEnd, ExpressionWriter* writer)
 
34
{
 
35
        QStringList elements;
 
36
        for(; it!=itEnd; ++it)
 
37
                elements += (*it)->visit(writer);
 
38
        
 
39
        return elements;
 
40
}
 
41
 
 
42
 
 
43
QMap<Operator::OperatorType, QString> initOperators()
 
44
{
 
45
        QMap<Operator::OperatorType, QString> ret;
 
46
        ret.insert(Operator::plus, "+");
 
47
        ret.insert(Operator::times, "*");
 
48
        ret.insert(Operator::divide, "/");
 
49
        ret.insert(Operator::eq, "=");
 
50
        ret.insert(Operator::neq, "!=");
 
51
        ret.insert(Operator::lt, "<");
 
52
        ret.insert(Operator::leq, "<=");
 
53
        ret.insert(Operator::gt, ">");
 
54
        ret.insert(Operator::geq, ">=");
 
55
        ret.insert(Operator::power, "^");
 
56
        ret.insert(Operator::minus, "-");
 
57
        return ret;
 
58
}
 
59
 
 
60
const QMap<Operator::OperatorType, QString> StringExpressionWriter::s_operators=initOperators();
 
61
 
 
62
StringExpressionWriter::StringExpressionWriter(const Object* o)
 
63
{
 
64
        m_result=o->visit(this);
 
65
}
 
66
 
 
67
QString StringExpressionWriter::accept(const Ci* var)
 
68
{
 
69
        return var->name();
 
70
}
 
71
 
 
72
QString StringExpressionWriter::accept(const Operator* op)
 
73
{
 
74
        return op->name();
 
75
}
 
76
 
 
77
QString StringExpressionWriter::accept(const Vector* vec)
 
78
{
 
79
        return QString("vector { %1 }").arg(allValues<Vector::const_iterator>(vec->constBegin(), vec->constEnd(), this).join(QString(", ")));
 
80
}
 
81
 
 
82
QString StringExpressionWriter::accept(const List* vec)
 
83
{
 
84
        if(!vec->isEmpty() && vec->at(0)->type()==Object::value && static_cast<Cn*>(vec->at(0))->format()==Cn::Char)
 
85
                return "\""+AnalitzaUtils::listToString(vec)+"\"";
 
86
        else
 
87
                return QString("list { %1 }").arg(allValues<List::const_iterator>(vec->constBegin(), vec->constEnd(), this).join(QString(", ")));
 
88
}
 
89
 
 
90
QString StringExpressionWriter::accept(const Cn* var)
 
91
{
 
92
        if(var->isBoolean())
 
93
                return var->isTrue() ? "true" : "false";
 
94
        else
 
95
                return QString::number(var->value(), 'g', 12);
 
96
}
 
97
 
 
98
int StringExpressionWriter::weight(const Operator* op, int size)
 
99
{
 
100
        switch(op->operatorType()) {
 
101
                case Operator::lt:
 
102
                case Operator::gt:
 
103
                case Operator::eq:
 
104
                case Operator::neq:
 
105
                case Operator::leq:
 
106
                case Operator::geq:
 
107
                        return 1;
 
108
                case Operator::plus:
 
109
                        return 2;
 
110
                case Operator::minus:
 
111
                        return size==1 ? 8 : 3;
 
112
                case Operator::times:
 
113
                        return 4;
 
114
                case Operator::divide:
 
115
                        return 5;
 
116
                case Operator::_and:
 
117
                case Operator::_or:
 
118
                case Operator::_xor:
 
119
                        return 6;
 
120
                case Operator::power:
 
121
                        return 7;
 
122
                default:
 
123
                        return 1000;
 
124
        }
 
125
}
 
126
 
 
127
QString StringExpressionWriter::accept ( const Analitza::Apply* a )
 
128
{
 
129
        Operator op=a->firstOperator();
 
130
        QStringList ret;
 
131
        QString toret;
 
132
        QString bounds;
 
133
        QStringList bvars=a->bvarStrings();
 
134
        
 
135
        if(a->ulimit() || a->dlimit()) {
 
136
                bounds += '=';
 
137
                if(a->dlimit())
 
138
                        bounds += a->dlimit()->visit(this);
 
139
                bounds += "..";
 
140
                if(a->ulimit())
 
141
                        bounds += a->ulimit()->visit(this);
 
142
        }
 
143
        else if(a->domain())
 
144
                bounds += '@'+a->domain()->visit(this);
 
145
        
 
146
        foreach(Object* o, a->m_params) {
 
147
                Object::ObjectType type=o->type();
 
148
                switch(type) {
 
149
                        case Object::oper:
 
150
                                Q_ASSERT(false);
 
151
                                break;
 
152
                        case Object::variable:
 
153
                                ret << static_cast<const Ci*>(o)->visit(this);
 
154
                                break;
 
155
                        case Object::apply: {
 
156
                                const Apply *c = (const Apply*) o;
 
157
                                QString s = c->visit(this);
 
158
                                if(s_operators.contains(op.operatorType()) && !c->isUnary()) {
 
159
                                        Operator child_op = c->firstOperator();
 
160
                                        
 
161
                                        if(child_op.operatorType() && weight(&op, c->countValues())>=weight(&child_op, c->countValues()))
 
162
                                                s=QString("(%1)").arg(s);
 
163
                                }
 
164
                                ret << s;
 
165
                        }       break;
 
166
                        default:
 
167
                                ret << o->visit(this);
 
168
                                break;
 
169
                }
 
170
        }
 
171
        
 
172
        bool func=op.operatorType()==Operator::function;
 
173
        if(func) {
 
174
                QString n = ret.takeFirst();
 
175
                if(a->m_params.first()->type()!=Object::variable)
 
176
                        n='('+n+')';
 
177
                
 
178
                toret += QString("%1(%2)").arg(n).arg(ret.join(", "));
 
179
        } else if(ret.count()>1 && s_operators.contains(op.operatorType())) {
 
180
                toret += ret.join(s_operators.value(op.operatorType()));
 
181
        } else if(ret.count()==1 && op.operatorType()==Operator::minus)
 
182
                toret += '-'+ret[0];
 
183
        else if(op.operatorType()==Operator::selector) {
 
184
                QString value = ret.takeLast();
 
185
                if(a->m_params.last()->isApply())
 
186
                        value = '('+value+')';
 
187
                toret += QString("%1[%2]").arg(value).arg(ret.join(", "));
 
188
        } else {
 
189
                QString bounding;
 
190
                if(!bounds.isEmpty() || !bvars.isEmpty()) {
 
191
                        if(bvars.count()!=1) bounding +='(';
 
192
                        bounding += bvars.join(", ");
 
193
                        if(bvars.count()!=1) bounding +=')';
 
194
                        
 
195
                        bounding = ':'+bounding +bounds;
 
196
                }
 
197
                        
 
198
                toret += QString("%1(%2%3)").arg(op.visit(this)).arg(ret.join(", ")).arg(bounding);
 
199
        }
 
200
        
 
201
        return toret;
 
202
}
 
203
 
 
204
QString StringExpressionWriter::accept(const Container* var)
 
205
{
 
206
        QStringList ret = allValues(var->constBegin(), var->constEnd(), this);
 
207
        
 
208
        QString toret;
 
209
        switch(var->containerType()) {
 
210
                case Container::declare:
 
211
                        toret += ret.join(":=");
 
212
                        break;
 
213
                case Container::lambda: {
 
214
                        QString last=ret.takeLast();
 
215
                        QStringList bvars = var->bvarStrings();
 
216
                        if(bvars.count()!=1) toret +='(';
 
217
                        toret += bvars.join(", ");
 
218
                        if(bvars.count()!=1) toret +=')';
 
219
                        toret += "->" + last;
 
220
                }       break;
 
221
                case Container::math:
 
222
                        toret += ret.join("; ");
 
223
                        break;
 
224
                case Container::uplimit: //x->(n1..n2) is put at the same time
 
225
                case Container::downlimit:
 
226
                        break;
 
227
                case Container::bvar:
 
228
                        if(ret.count()>1) toret += '(';
 
229
                        toret += ret.join(", ");
 
230
                        if(ret.count()>1) toret += ')';
 
231
                        break;
 
232
                case Container::piece:
 
233
                        toret += ret[1]+" ? "+ret[0];
 
234
                        break;
 
235
                case Container::otherwise:
 
236
                        toret += "? "+ret[0];
 
237
                        break;
 
238
                default:
 
239
                        toret += var->tagName()+" { "+ret.join(", ")+" }";
 
240
                        break;
 
241
        }
 
242
        return toret;
 
243
}
 
244
 
 
245
QString StringExpressionWriter::accept(const CustomObject*)
 
246
{
 
247
        return "CustomObject";
 
248
}