1/*************************************************************************************
2 * Copyright (C) 2007 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#ifndef EXPRESSION_H
20#define EXPRESSION_H
21
22#include <QStringList>
23#include <QSharedDataPointer>
24
25#include "analitzaexport.h"
26#include "object.h"
27
28namespace Analitza
29{
30class Ci;
31class Container;
32class Cn;
33
34/**
35 * \class Expression
36 *
37 * \ingroup AnalitzaModule
38 *
39 * \brief Represents a mathematical expression.
40 *
41 * Expression let to convert it to string, MathML and make some little queries
42 * to it, without calculating anything.
43 */
44
45class ANALITZA_EXPORT Expression
46{
47 public:
48 typedef void (*CustomObjectDestructor)(const QVariant&);
49 /**
50 * Constructs an empty Expression.
51 */
52 Expression();
53
54 /**
55 * Copy constructor, copies the whole object to the constructed one.
56 */
57 Expression(const Expression& e);
58
59 /**
60 * Creates an expression from a value
61 */
62 Expression(const Cn& e);
63
64 explicit Expression(Object* o);
65
66 /**
67 * Constructor. Parses an expression and creates the object.
68 * @param exp expression to be assigned
69 * @param mathml format of the expression
70 */
71 explicit Expression(const QString& exp, bool mathml=false);
72
73 /** Destructor */
74 ~Expression();
75
76 /**
77 * Sets an expression @p exp which is not in MathML format. Returns whether it was correctly assigned or not.
78 */
79 bool setText(const QString &exp);
80
81 /**
82 * Sets an expression @p exp which is in MathML format. Returns whether it was correctly assigned or not.
83 */
84 bool setMathML(const QString &exp);
85
86 /**
87 * Returns the list of errors that had experienced while building the expression.
88 */
89 QStringList error() const;
90
91 /** Adds a new error @p error to the expression, to be reported afterwards. */
92 void addError(const QString& error);
93
94 /**
95 * Returns whether this is a correct expression.
96 */
97 bool isCorrect() const;
98
99 /**
100 * Returns whether the @p e is equal.
101 */
102 bool operator==(const Expression& e) const;
103
104 bool operator!=(const Expression& e) const;
105
106 /**
107 * Copy assignment. Copies the @p e expression here.
108 */
109 Expression operator=(const Expression& e);
110
111 /**
112 * Returns whether it is a lambda-expression.
113 */
114 bool isLambda() const;
115
116 /**
117 * Returns the expression of the lambda body (without resolving the dependencies)
118 */
119 Expression lambdaBody() const Q_REQUIRED_RESULT;
120
121 /**
122 * Returns whether it is a vector expression.
123 */
124 bool isVector() const;
125
126 /**
127 * Returns whether it is a list expression.
128 */
129 bool isList() const;
130
131 /**
132 * Returns whether it is a string expression (a list of chars).
133 */
134 bool isString() const;
135
136 /**
137 * Returns the element at @p position in a vector
138 */
139 Expression elementAt(int position) const;
140
141 /**
142 * sets an expression value @p value to a @p position
143 */
144 void setElementAt(int position, const Analitza::Expression& exp);
145
146 /**
147 * Returns the tree associated to this object.
148 */
149 const Object* tree() const;
150
151 /**
152 * Returns the tree associated to this object.
153 */
154 Object* tree();
155
156 void setTree(Object* o);
157 /**
158 * Converts the expression to a string expression.
159 */
160 QString toString() const;
161
162 /**
163 * Converts the expression to MathML.
164 */
165 QString toMathML() const;
166
167 /**
168 * Exports the expression to HTML.
169 */
170 QString toHtml() const;
171
172 /**
173 * Converts the expression to MathML Presentation Markup.
174 */
175 QString toMathMLPresentation() const;
176
177 /** @returns the contained string value */
178 QString stringValue() const;
179
180 /**
181 * Invalidates the data of the expression.
182 */
183 void clear();
184
185 /**
186 * @returns Lists the global bounded variables in the expression
187 */
188 QStringList bvarList() const;
189
190 /** @returns Value representation of the expression. */
191 Cn toReal() const;
192
193 /** @returns true if the expression is a value, false otherwise. */
194 bool isReal() const;
195
196 /** @returns true if the expression is a custom object, false otherwise. */
197 bool isCustomObject() const;
198
199 /** @returns a list of the parameters in case this expression represents
200 a lambda construction. */
201 QList<Ci*> parameters() const;
202
203 /** In case it was a vector or list, it returns a list of each expression on the vector. */
204 QList<Expression> toExpressionList() const;
205
206 /** In case it contains a custom object it returns its value. */
207 QVariant customObjectValue() const;
208
209 /** renames the @p depth -th variable into @p newName */
210 void renameArgument(int depth, const QString& newName);
211
212 /** @returns whether it's an equation */
213 bool isEquation() const;
214
215 /** @returns whether it's a declaration */
216 bool isDeclaration() const;
217
218 /** @returns the name of the expression. If it's not a declaration
219 * then an empty string it's returned.
220 */
221 QString name() const;
222
223 /** @returns the value of the declaration. If it's not a declaration
224 * then an expression it's returned.
225 */
226 Expression declarationValue() const;
227
228 /** @returns the expression that evaluates the current equation to equal 0 */
229 Expression equationToFunction() const;
230
231 QStringList comments() const;
232
233 /**
234 * Converts a @p tag to an object type.
235 */
236 static enum Object::ObjectType whatType(const QString& tag);
237
238 /**
239 * @returns whether @p s is MathML or not. Very simple.
240 */
241 static bool isMathML(const QString& s) { return !s.isEmpty() && s[0]=='<'; }
242
243 static void computeDepth(Object* o);
244
245 /**
246 * @returns an expression containing a list of every expression passed on @p exps on the form:
247 * list { exps[0], exps[1], ... }
248 */
249 static Expression constructList(const QList<Expression> & exps);
250
251 /** creates an expression filled with just a custom object */
252 static Expression constructCustomObject(const QVariant& custom, Analitza::Expression::CustomObjectDestructor d);
253
254 /** creates an expression filled with just a string */
255 static Expression constructString(const QString& str);
256
257 /** @returns if a non-mathml expression is fully introduced (e.g. has closed all parentheses).
258 @param justempty tells if it's an expression with just spaces and comments
259 */
260 static bool isCompleteExpression(const QString& exp, bool justempty=false);
261 private:
262 class ExpressionPrivate;
263 QSharedDataPointer<ExpressionPrivate> d;
264 QStringList m_comments;
265};
266
267}
268
269#endif
270