1
/*************************************************************************************
2
* Copyright (C) 2008 by Aleix Pol <aleixpol@kde.org> *
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. *
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. *
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
*************************************************************************************/
19
#include "stringexpressionwriter.h"
23
#include "container.h"
24
#include <QStringList>
28
#include "analitzautils.h"
30
using namespace Analitza;
33
QStringList StringExpressionWriter::allValues(T it, const T& itEnd, ExpressionWriter* writer)
36
for(; it!=itEnd; ++it)
37
elements += (*it)->visit(writer);
43
QMap<Operator::OperatorType, QString> initOperators()
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, "-");
60
const QMap<Operator::OperatorType, QString> StringExpressionWriter::s_operators=initOperators();
62
StringExpressionWriter::StringExpressionWriter(const Object* o)
64
m_result=o->visit(this);
67
QString StringExpressionWriter::accept(const Ci* var)
72
QString StringExpressionWriter::accept(const Operator* op)
77
QString StringExpressionWriter::accept(const Vector* vec)
79
return QString("vector { %1 }").arg(allValues<Vector::const_iterator>(vec->constBegin(), vec->constEnd(), this).join(QString(", ")));
82
QString StringExpressionWriter::accept(const List* vec)
84
if(!vec->isEmpty() && vec->at(0)->type()==Object::value && static_cast<Cn*>(vec->at(0))->format()==Cn::Char)
85
return "\""+AnalitzaUtils::listToString(vec)+"\"";
87
return QString("list { %1 }").arg(allValues<List::const_iterator>(vec->constBegin(), vec->constEnd(), this).join(QString(", ")));
90
QString StringExpressionWriter::accept(const Cn* var)
93
return var->isTrue() ? "true" : "false";
95
return QString::number(var->value(), 'g', 12);
98
int StringExpressionWriter::weight(const Operator* op, int size)
100
switch(op->operatorType()) {
110
case Operator::minus:
111
return size==1 ? 8 : 3;
112
case Operator::times:
114
case Operator::divide:
120
case Operator::power:
127
QString StringExpressionWriter::accept ( const Analitza::Apply* a )
129
Operator op=a->firstOperator();
133
QStringList bvars=a->bvarStrings();
135
if(a->ulimit() || a->dlimit()) {
138
bounds += a->dlimit()->visit(this);
141
bounds += a->ulimit()->visit(this);
144
bounds += '@'+a->domain()->visit(this);
146
foreach(Object* o, a->m_params) {
147
Object::ObjectType type=o->type();
152
case Object::variable:
153
ret << static_cast<const Ci*>(o)->visit(this);
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();
161
if(child_op.operatorType() && weight(&op, c->countValues())>=weight(&child_op, c->countValues()))
162
s=QString("(%1)").arg(s);
167
ret << o->visit(this);
172
bool func=op.operatorType()==Operator::function;
174
QString n = ret.takeFirst();
175
if(a->m_params.first()->type()!=Object::variable)
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)
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(", "));
190
if(!bounds.isEmpty() || !bvars.isEmpty()) {
191
if(bvars.count()!=1) bounding +='(';
192
bounding += bvars.join(", ");
193
if(bvars.count()!=1) bounding +=')';
195
bounding = ':'+bounding +bounds;
198
toret += QString("%1(%2%3)").arg(op.visit(this)).arg(ret.join(", ")).arg(bounding);
204
QString StringExpressionWriter::accept(const Container* var)
206
QStringList ret = allValues(var->constBegin(), var->constEnd(), this);
209
switch(var->containerType()) {
210
case Container::declare:
211
toret += ret.join(":=");
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;
221
case Container::math:
222
toret += ret.join("; ");
224
case Container::uplimit: //x->(n1..n2) is put at the same time
225
case Container::downlimit:
227
case Container::bvar:
228
if(ret.count()>1) toret += '(';
229
toret += ret.join(", ");
230
if(ret.count()>1) toret += ')';
232
case Container::piece:
233
toret += ret[1]+" ? "+ret[0];
235
case Container::otherwise:
236
toret += "? "+ret[0];
239
toret += var->tagName()+" { "+ret.join(", ")+" }";
245
QString StringExpressionWriter::accept(const CustomObject*)
247
return "CustomObject";