1 /** \file
2 \brief Definition of basic types used by muParserX
3
4 <pre>
5 __________ ____ ___
6 _____ __ _\______ \_____ _______ ______ __________\ \/ /
7 / \| | \ ___/\__ \\_ __ \/ ___// __ \_ __ \ /
8 | Y Y \ | / | / __ \| | \/\___ \\ ___/| | \/ \
9 |__|_| /____/|____| (____ /__| /____ >\___ >__| /___/\ \
10 \/ \/ \/ \/ \_/
11 Copyright (C) 2016, Ingo Berg
12 All rights reserved.
13
14 Redistribution and use in source and binary forms, with or without
15 modification, are permitted provided that the following conditions are met:
16
17 * Redistributions of source code must retain the above copyright notice,
18 this list of conditions and the following disclaimer.
19 * Redistributions in binary form must reproduce the above copyright notice,
20 this list of conditions and the following disclaimer in the documentation
21 and/or other materials provided with the distribution.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 POSSIBILITY OF SUCH DAMAGE.
33 </pre>
34 */
35 #ifndef MUP_TYPES_H
36 #define MUP_TYPES_H
37
38 //--- Standard include ------------------------------------------------------
39 #include <string>
40 #include <iostream>
41 #include <sstream>
42 #include <vector>
43 #include <map>
44 #include <complex>
45
46 //--- muParserX framework ---------------------------------------------------
47 #include "suSortPred.h" // We need the string utils sorting predicates
48 #include "mpDefines.h"
49 #include "mpMatrix.h"
50 #include "mpCompat.h"
51
52
53 MUP_NAMESPACE_START
54
55 // Forward declarations
56 class IValueReader;
57 class IOprtBin;
58 class IOprtPostfix;
59 class IOprtInfix;
60 class IFunction;
61 class IToken;
62 class ICallback;
63 class IValue;
64 class ParserXBase;
65 class Value;
66 class Variable;
67 class TokenReader;
68 class IOprtBinShortcut;
69
70 // smart pointer types
71 template<typename T>
72 class TokenPtr;
73
74 /** \brief Type of a managed pointer storing parser tokens. */
75 typedef TokenPtr<IToken> ptr_tok_type;
76
77 /** \brief Type of a managed pointer storing callback tokens. */
78 typedef TokenPtr<ICallback> ptr_cal_type;
79
80 /** \brief Type of a managed pointer storing value tokens. */
81 typedef TokenPtr<IValue> ptr_val_type;
82
83 /** \brief Type of a managed pointer storing binary operator tokens. */
84 typedef TokenPtr<IOprtBin> ptr_binop_type;
85
86 /** \brief Type for a vector of tokens. */
87 typedef std::vector<ptr_tok_type> token_vec_type;
88
89 /** \brief Type for a vector of value items. */
90 typedef std::vector<ptr_val_type> val_vec_type;
91
92 // parser type definitions
93
94 /** \brief Parser datatype for floating point value. */
95 typedef MUP_FLOAT_TYPE float_type;
96
97 /** \brief Parser datatype for integer valuse. */
98 typedef MUP_INT_TYPE int_type;
99
100 /** \brief The basic type used for representing complex numbers. */
101 typedef std::complex<float_type> cmplx_type;
102
103 /** \brief Parser boolean datatype.
104
105 This must be bool! The only reason for this typedef is that I need the name bool_type
106 for a preprocessor macro definition to avoid inconsistent naming of the macro parameters.
107 */
108 typedef bool bool_type;
109
110 /** \brief The parsers underlying matrix type. */
111 typedef Matrix<Value> matrix_type;
112
113 /** \brief Parser datatype for strings. */
114 typedef MUP_STRING_TYPE string_type;
115
116 /** \brief Character type of the parser. */
117 typedef string_type::value_type char_type;
118
119 typedef std::basic_stringstream<char_type, std::char_traits<char_type>, std::allocator<char_type> > stringstream_type;
120
121 /** \brief Type of a vector holding pointers to value reader objects. */
122 typedef std::vector<IValueReader*> readervec_type;
123
124 /** \brief type for the parser variable storage. */
125 typedef std::map<string_type, ptr_tok_type> var_maptype;
126
127 /** \brief type of a container used to store parser values. */
128 typedef std::map<string_type, ptr_tok_type> val_maptype;
129
130 /** \brief Type of a container that binds Callback object pointer
131 to operator identifiers. */
132 typedef std::map<string_type, ptr_tok_type> fun_maptype;
133
134 /** \breief Type of a container that short circuit operator object pointer*/
135 typedef std::map<string_type, ptr_tok_type> oprt_bin_shortcut_maptype;
136
137 /** \brief Type of a container that binds Callback object pointer
138 to operator identifiers.
139 */
140 typedef std::map<string_type, ptr_tok_type, su::pred::SortByLength<string_type> > oprt_bin_maptype;
141
142 /** \brief Type of a map for storing postfix operators by their name. */
143 typedef std::map<string_type, ptr_tok_type> oprt_pfx_maptype;
144
145 /** \brief Type of a map for storing infix operators by their name. */
146 typedef std::map<string_type, ptr_tok_type> oprt_ifx_maptype;
147
148 //------------------------------------------------------------------------------
149 /** \brief Bytecode values.
150 \attention The order of the operator entries must match the order in
151 ParserXBase::c_DefaultOprt!
152 */
153 enum ECmdCode
154 {
155 // The following are codes for built in binary operators
156 // apart from built in operators the user has the opportunity to
157 // add user defined operators.
158 cmBO = 0, ///< Operator item: opening bracket
159 cmBC = 1, ///< Operator item: closing bracket
160 cmIO = 2, ///< Operator item: index operator opening
161 cmIC = 3, ///< Operator item: index operator closing
162 cmCBO = 4, ///< Operator item: curly bracket (opening)
163 cmCBC = 5, ///< Operator item: curly bracket (closing)
164 cmARG_SEP = 6, ///< Operator item: comma
165 cmIF = 7, ///< Ternary if then else operator
166 cmELSE = 8, ///< Ternary if then else operator
167 cmENDIF = 9, ///< Ternary if then else operator
168 cmJMP = 10, ///< Reserved for future use
169 cmVAL = 11, ///< value item
170 cmFUNC = 12, ///< Code for a function item
171 cmOPRT_BIN = 13, ///< Binary operator
172 cmOPRT_INFIX = 14, ///< Infix operator
173 cmOPRT_POSTFIX = 15, ///< Postfix operator
174 cmSHORTCUT_BEGIN = 16, ///< Short circuit operator && / ||
175 cmSHORTCUT_END = 17, ///< Short circuit operator && / ||
176 cmEOE = 18, ///< End of expression
177
178 // The following codes are reserved in case i will ever turn this
179 // into a scripting language
180 cmSCRIPT_NEWLINE = 19, ///< Newline
181 cmSCRIPT_COMMENT = 20,
182 cmSCRIPT_WHILE = 21, ///< Reserved for future use
183 cmSCRIPT_GOTO = 22, ///< Reserved for future use
184 cmSCRIPT_LABEL = 23, ///< Reserved for future use
185 cmSCRIPT_FOR = 24, ///< Reserved for future use
186 cmSCRIPT_IF = 25, ///< Reserved for future use
187 cmSCRIPT_ELSE = 26, ///< Reserved for future use
188 cmSCRIPT_ELSEIF = 27, ///< Reserved for future use
189 cmSCRIPT_ENDIF = 28, ///< Reserved for future use
190 cmSCRIPT_FUNCTION = 29, ///< Reserved for future use
191
192 // misc codes
193 cmUNKNOWN = 30, ///< uninitialized item
194 cmCOUNT ///< Dummy entry for counting the enum values
195 }; // ECmdCode
196
197
198 //------------------------------------------------------------------------------
199 /** \brief Strings assigned to the enum codes of ECmdCode.
200
201 Used for debugging purposes only.
202 */
203 extern const char_type *g_sCmdCode[];
204
205 //------------------------------------------------------------------------------
206 enum EPackages
207 {
208 pckCOMMON = 1 << 0,
209 pckUNIT = 1 << 1,
210 pckCOMPLEX = 1 << 2,
211 pckNON_COMPLEX = 1 << 3,
212 pckSTRING = 1 << 4,
213 pckMATRIX = 1 << 5,
214 pckALL_COMPLEX = pckCOMMON | pckCOMPLEX | pckSTRING | pckUNIT | pckMATRIX,
215 pckALL_NON_COMPLEX = pckCOMMON | pckNON_COMPLEX | pckSTRING | pckUNIT | pckMATRIX
216 };
217
218 //------------------------------------------------------------------------------
219 /** \brief Syntax codes.
220
221 The syntax codes control the syntax check done during the first time parsing of
222 the expression string. They are flags that indicate which tokens are allowed next
223 if certain tokens are identified.
224 */
225 enum ESynCodes
226 {
227 noBO = 1 << 0, ///< to avoid i.e. "cos(7)("
228 noBC = 1 << 1, ///< to avoid i.e. "sin)" or "()"
229 noIO = 1 << 2, ///< No opening bracket "["
230 noIC = 1 << 3, ///< No closing bracket "]"
231 noCBO = 1 << 4, ///< No opening curly bracket
232 noCBC = 1 << 5, ///< No opening closing bracket
233 noVAL = 1 << 6, ///< to avoid i.e. "tan 2" or "sin(8)3.14"
234 noVAR = 1 << 7, ///< to avoid i.e. "sin a" or "sin(8)a"
235 noCOMMA = 1 << 8, ///< to avoid i.e. ",," or "+," ...
236 noFUN = 1 << 9, ///< to avoid i.e. "sqrt cos" or "(1)sin"
237 noOPT = 1 << 10, ///< to avoid i.e. "(+)"
238 noPFX = 1 << 11, ///< to avoid i.e. "(5!!)" "sin!"
239 noIFX = 1 << 12, ///< to avoid i.e. "++4" "!!4"
240 noEND = 1 << 13, ///< to avoid unexpected end of expression
241 noIF = 1 << 14,
242 noELSE = 1 << 15,
243 noNEWLINE = 1 << 16, ///< to avoid i.e. "a+\nb" or "sin(\na)"
244
245 sfSTART_OF_LINE = noOPT | noBC | noPFX | noCOMMA | noIO | noIC | noIF | noELSE,
246 sfALLOW_NONE = ~0 ///< All of he above flags set
247 };
248
249 //------------------------------------------------------------------------------
250 /** \brief Binary operator associativity values. */
251 enum EOprtAsct
252 {
253 oaNONE = 0,
254 oaLEFT = 1,
255 oaRIGHT = 2
256 };
257
258 //------------------------------------------------------------------------------
259 /** \brief Parser operator precedence values.
260
261 These are predefined values for the operator precedence.
262 */
263 enum EOprtPrecedence
264 {
265 // assignment operators
266 prASSIGN = -1,
267
268 // if-then-else
269 prIF_THEN_ELSE = 0,
270
271 // binary operators
272 prLOGIC_OR = 1,
273 // prLOGIC_XOR = 2,
274 prLOGIC_AND = 3,
275 prBIT_OR = 4,
276 prBIT_XOR = 5,
277 prBIT_AND = 6,
278
279 prRELATIONAL1 = 7, ///< For "==", "!="
280 prRELATIONAL2 = 8, ///< Relational operators "<", "<=", ">", ">="
281 prSHIFT = 9, ///< Shift operators "<<", ">>"
282
283 prCOLON = 10, ///< Colon operator
284
285 prADD_SUB = 11, ///< addition
286 prMUL_DIV = 12, ///< multiplication/division
287 prPOW = 13, ///< power operator priority (highest)
288
289 // infix operators
290 prINFIX = 12, ///< Signs have a higher priority than ADD_SUB, but lower than power operator
291 prPOSTFIX = 12 ///< Postfix operator priority (currently unused)
292 };
293
294 /** \brief Error codes.
295
296 This is the complete list of all error codes used by muparserx
297 */
298 enum EErrorCodes
299 {
300 // Expression syntax errors
301 ecUNEXPECTED_OPERATOR = 0, ///< Unexpected binary operator found
302 ecUNASSIGNABLE_TOKEN = 1, ///< Token cant be identified.
303 ecUNEXPECTED_EOF = 2, ///< Unexpected end of expression. (Example: "2+sin(")
304 ecUNEXPECTED_COMMA = 3, ///< An unexpected comma has been found. (Example: "1,23")
305 ecUNEXPECTED_VAL = 4, ///< An unexpected value token has been found
306 ecUNEXPECTED_VAR = 5, ///< An unexpected variable token has been found
307 ecUNEXPECTED_PARENS = 6, ///< Unexpected Parenthesis, opening or closing
308 ecUNEXPECTED_STR = 7, ///< A string has been found at an inapropriate position
309 ecUNEXPECTED_CONDITIONAL = 8,
310 ecUNEXPECTED_NEWLINE = 9,
311 ecSTRING_EXPECTED = 10, ///< A string function has been called with a different type of argument
312 ecVAL_EXPECTED = 11, ///< A numerical function has been called with a non value type of argument
313 ecMISSING_PARENS = 12, ///< Missing parens. (Example: "3*sin(3")
314 ecMISSING_ELSE_CLAUSE = 13,
315 ecMISPLACED_COLON = 14,
316 ecUNEXPECTED_FUN = 15, ///< Unexpected function found. (Example: "sin(8)cos(9)")
317 ecUNTERMINATED_STRING = 16, ///< unterminated string constant. (Example: "3*valueof("hello)")
318 ecTOO_MANY_PARAMS = 17, ///< Too many function parameters
319 ecTOO_FEW_PARAMS = 18, ///< Too few function parameters. (Example: "ite(1<2,2)")
320 ecTYPE_CONFLICT = 19, ///< Generic type conflict
321 ecTYPE_CONFLICT_FUN = 20, ///< Function argument type conflict.
322 ecTYPE_CONFLICT_IDX = 21, ///< Function argument type conflict.
323 ecINVALID_TYPE = 22,
324 ecINVALID_TYPECAST = 23, ///< Invalid Value token cast.
325 ecARRAY_SIZE_MISMATCH = 24, ///< Array size mismatch during a vector operation
326 ecNOT_AN_ARRAY = 25, ///< Using the index operator on a scalar variable
327 ecUNEXPECTED_SQR_BRACKET = 26, ///< Invalid use of the index operator
328 ecUNEXPECTED_CURLY_BRACKET = 27, ///< Invalid use of the index operator
329
330 ecINVALID_NAME = 28, ///< Invalid function, variable or constant name.
331 ecBUILTIN_OVERLOAD = 29, ///< Trying to overload builtin operator
332 ecINVALID_FUN_PTR = 30, ///< Invalid callback function pointer
333 ecINVALID_VAR_PTR = 31, ///< Invalid variable pointer
334 ecINVALID_PARAMETER = 32, ///< Invalid function parameter
335 ecINVALID_NUMBER_OF_PARAMETERS = 33,
336
337 ecNAME_CONFLICT = 34, ///< Name conflict
338 ecOPT_PRI = 35, ///< Invalid operator priority
339 ecASSIGNEMENT_TO_VALUE = 36, ///< Assignment to operator (3=4 instead of a=4)
340
341 //
342 ecDOMAIN_ERROR = 37, ///< Trying to use func/oprtr with out-of-domain input args
343 ecDIV_BY_ZERO = 38, ///< Division by zero (currently unused)
344 ecGENERIC = 39, ///< Generic error
345
346 ecINDEX_OUT_OF_BOUNDS = 40, ///< Array index is out of bounds
347 ecINDEX_DIMENSION = 41,
348 ecMISSING_SQR_BRACKET = 42, ///< The index operator was not closed properly (i.e. "v[3")
349 ecMISSING_CURLY_BRACKET = 43,
350 ecEVAL = 44, ///< Error while evaluating function / operator
351 ecOVERFLOW = 45, ///< Overflow (possibly) occurred
352
353 // Matrix errors
354 ecMATRIX_DIMENSION_MISMATCH = 46,
355
356 // string related errors
357 ecUNKNOWN_ESCAPE_SEQUENCE = 47,
358
359 // already-defined item errors
360 ecVARIABLE_DEFINED = 48, ///< Variable is already defined
361 ecCONSTANT_DEFINED = 49, ///< Constant is already defined
362 ecFUNOPRT_DEFINED = 50, ///< Function/operator is already defined
363
364 // internal errors
365 ecINTERNAL_ERROR = 51, ///< Internal error of any kind.
366
367 // The last two are special entries
368 ecCOUNT, ///< This is no error code, It just stores just the total number of error codes
369 ecUNDEFINED = -1 ///< Undefined message, placeholder to detect unassigned error messages
370 };
371
372 #if defined(_UNICODE)
373
374 //------------------------------------------------------------------------------
375 /** \brief Encapsulate wcout. */
console()376 inline std::wostream& console()
377 {
378 return std::wcout;
379 }
380
381 //------------------------------------------------------------------------------
382 /** \brief Encapsulate cin. */
console_in()383 inline std::wistream& console_in()
384 {
385 return std::wcin;
386 }
387
388 #else
389
390 /** \brief Encapsulate cout.
391
392 Used for supporting UNICODE more easily.
393 */
console()394 inline std::ostream& console()
395 {
396 return std::cout;
397 }
398
399 /** \brief Encapsulate cin.
400
401 Used for supporting UNICODE more easily.
402 */
console_in()403 inline std::istream& console_in()
404 {
405 return std::cin;
406 }
407
408 #endif // _UNICODE
409
410 } // namespace mu
411
412 #endif
413