1 /*
2 
3 	 _____  __ _____________ _______  ______ ___________
4 	/     \|  |  \____ \__  \\_  __ \/  ___// __ \_  __ \
5    |  Y Y  \  |  /  |_> > __ \|  | \/\___ \\  ___/|  | \/
6    |__|_|  /____/|   __(____  /__|  /____  >\___  >__|
7 		 \/      |__|       \/           \/     \/
8    Copyright (C) 2004 - 2020 Ingo Berg
9 
10 	Redistribution and use in source and binary forms, with or without modification, are permitted
11 	provided that the following conditions are met:
12 
13 	  * Redistributions of source code must retain the above copyright notice, this list of
14 		conditions and the following disclaimer.
15 	  * Redistributions in binary form must reproduce the above copyright notice, this list of
16 		conditions and the following disclaimer in the documentation and/or other materials provided
17 		with the distribution.
18 
19 	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20 	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 	FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 	CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 	DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 	IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26 	OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 
29 #include "muParserCallback.h"
30 
31 #if defined(_MSC_VER)
32 	#pragma warning(push)
33 	#pragma warning(disable : 26812)
34 #endif
35 
36 /** \file
37 	\brief Implementation of the parser callback class.
38 */
39 
40 
41 namespace mu
42 {
ParserCallback(fun_type0 a_pFun,bool a_bAllowOpti)43 	ParserCallback::ParserCallback(fun_type0 a_pFun, bool a_bAllowOpti)
44 		:m_pFun((void*)a_pFun)
45 		, m_iArgc(0)
46 		, m_iPri(-1)
47 		, m_eOprtAsct(oaNONE)
48 		, m_iCode(cmFUNC)
49 		, m_iType(tpDBL)
50 		, m_bAllowOpti(a_bAllowOpti)
51 	{}
52 
53 
ParserCallback(fun_type1 a_pFun,bool a_bAllowOpti,int a_iPrec,ECmdCode a_iCode)54 	ParserCallback::ParserCallback(fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec, ECmdCode a_iCode)
55 		:m_pFun((void*)a_pFun)
56 		, m_iArgc(1)
57 		, m_iPri(a_iPrec)
58 		, m_eOprtAsct(oaNONE)
59 		, m_iCode(a_iCode)
60 		, m_iType(tpDBL)
61 		, m_bAllowOpti(a_bAllowOpti)
62 	{}
63 
64 
65 
66 	/** \brief Constructor for constructing function callbacks taking two arguments.
67 		\throw nothrow
68 	*/
ParserCallback(fun_type2 a_pFun,bool a_bAllowOpti)69 	ParserCallback::ParserCallback(fun_type2 a_pFun, bool a_bAllowOpti)
70 		:m_pFun((void*)a_pFun)
71 		, m_iArgc(2)
72 		, m_iPri(-1)
73 		, m_eOprtAsct(oaNONE)
74 		, m_iCode(cmFUNC)
75 		, m_iType(tpDBL)
76 		, m_bAllowOpti(a_bAllowOpti)
77 	{}
78 
79 
80 	/** \brief Constructor for constructing binary operator callbacks.
81 		\param a_pFun Pointer to a static function taking two arguments
82 		\param a_bAllowOpti A flag indicating this function can be optimized
83 		\param a_iPrec The operator precedence
84 		\param a_eOprtAsct The operators associativity
85 		\throw nothrow
86 	*/
ParserCallback(fun_type2 a_pFun,bool a_bAllowOpti,int a_iPrec,EOprtAssociativity a_eOprtAsct)87 	ParserCallback::ParserCallback(fun_type2 a_pFun,
88 		bool a_bAllowOpti,
89 		int a_iPrec,
90 		EOprtAssociativity a_eOprtAsct)
91 		:m_pFun((void*)a_pFun)
92 		, m_iArgc(2)
93 		, m_iPri(a_iPrec)
94 		, m_eOprtAsct(a_eOprtAsct)
95 		, m_iCode(cmOPRT_BIN)
96 		, m_iType(tpDBL)
97 		, m_bAllowOpti(a_bAllowOpti)
98 	{}
99 
100 
ParserCallback(fun_type3 a_pFun,bool a_bAllowOpti)101 	ParserCallback::ParserCallback(fun_type3 a_pFun, bool a_bAllowOpti)
102 		:m_pFun((void*)a_pFun)
103 		, m_iArgc(3)
104 		, m_iPri(-1)
105 		, m_eOprtAsct(oaNONE)
106 		, m_iCode(cmFUNC)
107 		, m_iType(tpDBL)
108 		, m_bAllowOpti(a_bAllowOpti)
109 	{}
110 
111 
ParserCallback(fun_type4 a_pFun,bool a_bAllowOpti)112 	ParserCallback::ParserCallback(fun_type4 a_pFun, bool a_bAllowOpti)
113 		:m_pFun((void*)a_pFun)
114 		, m_iArgc(4)
115 		, m_iPri(-1)
116 		, m_eOprtAsct(oaNONE)
117 		, m_iCode(cmFUNC)
118 		, m_iType(tpDBL)
119 		, m_bAllowOpti(a_bAllowOpti)
120 	{}
121 
122 
ParserCallback(fun_type5 a_pFun,bool a_bAllowOpti)123 	ParserCallback::ParserCallback(fun_type5 a_pFun, bool a_bAllowOpti)
124 		:m_pFun((void*)a_pFun)
125 		, m_iArgc(5)
126 		, m_iPri(-1)
127 		, m_eOprtAsct(oaNONE)
128 		, m_iCode(cmFUNC)
129 		, m_iType(tpDBL)
130 		, m_bAllowOpti(a_bAllowOpti)
131 	{}
132 
133 
ParserCallback(fun_type6 a_pFun,bool a_bAllowOpti)134 	ParserCallback::ParserCallback(fun_type6 a_pFun, bool a_bAllowOpti)
135 		:m_pFun((void*)a_pFun)
136 		, m_iArgc(6)
137 		, m_iPri(-1)
138 		, m_eOprtAsct(oaNONE)
139 		, m_iCode(cmFUNC)
140 		, m_iType(tpDBL)
141 		, m_bAllowOpti(a_bAllowOpti)
142 	{}
143 
144 
ParserCallback(fun_type7 a_pFun,bool a_bAllowOpti)145 	ParserCallback::ParserCallback(fun_type7 a_pFun, bool a_bAllowOpti)
146 		:m_pFun((void*)a_pFun)
147 		, m_iArgc(7)
148 		, m_iPri(-1)
149 		, m_eOprtAsct(oaNONE)
150 		, m_iCode(cmFUNC)
151 		, m_iType(tpDBL)
152 		, m_bAllowOpti(a_bAllowOpti)
153 	{}
154 
155 
ParserCallback(fun_type8 a_pFun,bool a_bAllowOpti)156 	ParserCallback::ParserCallback(fun_type8 a_pFun, bool a_bAllowOpti)
157 		:m_pFun((void*)a_pFun)
158 		, m_iArgc(8)
159 		, m_iPri(-1)
160 		, m_eOprtAsct(oaNONE)
161 		, m_iCode(cmFUNC)
162 		, m_iType(tpDBL)
163 		, m_bAllowOpti(a_bAllowOpti)
164 	{}
165 
166 
ParserCallback(fun_type9 a_pFun,bool a_bAllowOpti)167 	ParserCallback::ParserCallback(fun_type9 a_pFun, bool a_bAllowOpti)
168 		:m_pFun((void*)a_pFun)
169 		, m_iArgc(9)
170 		, m_iPri(-1)
171 		, m_eOprtAsct(oaNONE)
172 		, m_iCode(cmFUNC)
173 		, m_iType(tpDBL)
174 		, m_bAllowOpti(a_bAllowOpti)
175 	{}
176 
177 
ParserCallback(fun_type10 a_pFun,bool a_bAllowOpti)178 	ParserCallback::ParserCallback(fun_type10 a_pFun, bool a_bAllowOpti)
179 		:m_pFun((void*)a_pFun)
180 		, m_iArgc(10)
181 		, m_iPri(-1)
182 		, m_eOprtAsct(oaNONE)
183 		, m_iCode(cmFUNC)
184 		, m_iType(tpDBL)
185 		, m_bAllowOpti(a_bAllowOpti)
186 	{}
187 
188 
ParserCallback(bulkfun_type0 a_pFun,bool a_bAllowOpti)189 	ParserCallback::ParserCallback(bulkfun_type0 a_pFun, bool a_bAllowOpti)
190 		:m_pFun((void*)a_pFun)
191 		, m_iArgc(0)
192 		, m_iPri(-1)
193 		, m_eOprtAsct(oaNONE)
194 		, m_iCode(cmFUNC_BULK)
195 		, m_iType(tpDBL)
196 		, m_bAllowOpti(a_bAllowOpti)
197 	{}
198 
199 
ParserCallback(bulkfun_type1 a_pFun,bool a_bAllowOpti)200 	ParserCallback::ParserCallback(bulkfun_type1 a_pFun, bool a_bAllowOpti)
201 		:m_pFun((void*)a_pFun)
202 		, m_iArgc(1)
203 		, m_iPri(-1)
204 		, m_eOprtAsct(oaNONE)
205 		, m_iCode(cmFUNC_BULK)
206 		, m_iType(tpDBL)
207 		, m_bAllowOpti(a_bAllowOpti)
208 	{}
209 
210 
211 	/** \brief Constructor for constructing function callbacks taking two arguments.
212 		\throw nothrow
213 	*/
ParserCallback(bulkfun_type2 a_pFun,bool a_bAllowOpti)214 	ParserCallback::ParserCallback(bulkfun_type2 a_pFun, bool a_bAllowOpti)
215 		:m_pFun((void*)a_pFun)
216 		, m_iArgc(2)
217 		, m_iPri(-1)
218 		, m_eOprtAsct(oaNONE)
219 		, m_iCode(cmFUNC_BULK)
220 		, m_iType(tpDBL)
221 		, m_bAllowOpti(a_bAllowOpti)
222 	{}
223 
224 
ParserCallback(bulkfun_type3 a_pFun,bool a_bAllowOpti)225 	ParserCallback::ParserCallback(bulkfun_type3 a_pFun, bool a_bAllowOpti)
226 		:m_pFun((void*)a_pFun)
227 		, m_iArgc(3)
228 		, m_iPri(-1)
229 		, m_eOprtAsct(oaNONE)
230 		, m_iCode(cmFUNC_BULK)
231 		, m_iType(tpDBL)
232 		, m_bAllowOpti(a_bAllowOpti)
233 	{}
234 
235 
ParserCallback(bulkfun_type4 a_pFun,bool a_bAllowOpti)236 	ParserCallback::ParserCallback(bulkfun_type4 a_pFun, bool a_bAllowOpti)
237 		:m_pFun((void*)a_pFun)
238 		, m_iArgc(4)
239 		, m_iPri(-1)
240 		, m_eOprtAsct(oaNONE)
241 		, m_iCode(cmFUNC_BULK)
242 		, m_iType(tpDBL)
243 		, m_bAllowOpti(a_bAllowOpti)
244 	{}
245 
246 
ParserCallback(bulkfun_type5 a_pFun,bool a_bAllowOpti)247 	ParserCallback::ParserCallback(bulkfun_type5 a_pFun, bool a_bAllowOpti)
248 		:m_pFun((void*)a_pFun)
249 		, m_iArgc(5)
250 		, m_iPri(-1)
251 		, m_eOprtAsct(oaNONE)
252 		, m_iCode(cmFUNC_BULK)
253 		, m_iType(tpDBL)
254 		, m_bAllowOpti(a_bAllowOpti)
255 	{}
256 
257 
ParserCallback(bulkfun_type6 a_pFun,bool a_bAllowOpti)258 	ParserCallback::ParserCallback(bulkfun_type6 a_pFun, bool a_bAllowOpti)
259 		:m_pFun((void*)a_pFun)
260 		, m_iArgc(6)
261 		, m_iPri(-1)
262 		, m_eOprtAsct(oaNONE)
263 		, m_iCode(cmFUNC_BULK)
264 		, m_iType(tpDBL)
265 		, m_bAllowOpti(a_bAllowOpti)
266 	{}
267 
268 
ParserCallback(bulkfun_type7 a_pFun,bool a_bAllowOpti)269 	ParserCallback::ParserCallback(bulkfun_type7 a_pFun, bool a_bAllowOpti)
270 		:m_pFun((void*)a_pFun)
271 		, m_iArgc(7)
272 		, m_iPri(-1)
273 		, m_eOprtAsct(oaNONE)
274 		, m_iCode(cmFUNC_BULK)
275 		, m_iType(tpDBL)
276 		, m_bAllowOpti(a_bAllowOpti)
277 	{}
278 
279 
ParserCallback(bulkfun_type8 a_pFun,bool a_bAllowOpti)280 	ParserCallback::ParserCallback(bulkfun_type8 a_pFun, bool a_bAllowOpti)
281 		:m_pFun((void*)a_pFun)
282 		, m_iArgc(8)
283 		, m_iPri(-1)
284 		, m_eOprtAsct(oaNONE)
285 		, m_iCode(cmFUNC_BULK)
286 		, m_iType(tpDBL)
287 		, m_bAllowOpti(a_bAllowOpti)
288 	{}
289 
290 
ParserCallback(bulkfun_type9 a_pFun,bool a_bAllowOpti)291 	ParserCallback::ParserCallback(bulkfun_type9 a_pFun, bool a_bAllowOpti)
292 		:m_pFun((void*)a_pFun)
293 		, m_iArgc(9)
294 		, m_iPri(-1)
295 		, m_eOprtAsct(oaNONE)
296 		, m_iCode(cmFUNC_BULK)
297 		, m_iType(tpDBL)
298 		, m_bAllowOpti(a_bAllowOpti)
299 	{}
300 
301 
ParserCallback(bulkfun_type10 a_pFun,bool a_bAllowOpti)302 	ParserCallback::ParserCallback(bulkfun_type10 a_pFun, bool a_bAllowOpti)
303 		:m_pFun((void*)a_pFun)
304 		, m_iArgc(10)
305 		, m_iPri(-1)
306 		, m_eOprtAsct(oaNONE)
307 		, m_iCode(cmFUNC_BULK)
308 		, m_iType(tpDBL)
309 		, m_bAllowOpti(a_bAllowOpti)
310 	{}
311 
312 
ParserCallback(multfun_type a_pFun,bool a_bAllowOpti)313 	ParserCallback::ParserCallback(multfun_type a_pFun, bool a_bAllowOpti)
314 		:m_pFun((void*)a_pFun)
315 		, m_iArgc(-1)
316 		, m_iPri(-1)
317 		, m_eOprtAsct(oaNONE)
318 		, m_iCode(cmFUNC)
319 		, m_iType(tpDBL)
320 		, m_bAllowOpti(a_bAllowOpti)
321 	{}
322 
323 
ParserCallback(strfun_type1 a_pFun,bool a_bAllowOpti)324 	ParserCallback::ParserCallback(strfun_type1 a_pFun, bool a_bAllowOpti)
325 		:m_pFun((void*)a_pFun)
326 		, m_iArgc(0)
327 		, m_iPri(-1)
328 		, m_eOprtAsct(oaNONE)
329 		, m_iCode(cmFUNC_STR)
330 		, m_iType(tpSTR)
331 		, m_bAllowOpti(a_bAllowOpti)
332 	{}
333 
334 
ParserCallback(strfun_type2 a_pFun,bool a_bAllowOpti)335 	ParserCallback::ParserCallback(strfun_type2 a_pFun, bool a_bAllowOpti)
336 		:m_pFun((void*)a_pFun)
337 		, m_iArgc(1)
338 		, m_iPri(-1)
339 		, m_eOprtAsct(oaNONE)
340 		, m_iCode(cmFUNC_STR)
341 		, m_iType(tpSTR)
342 		, m_bAllowOpti(a_bAllowOpti)
343 	{}
344 
345 
ParserCallback(strfun_type3 a_pFun,bool a_bAllowOpti)346 	ParserCallback::ParserCallback(strfun_type3 a_pFun, bool a_bAllowOpti)
347 		:m_pFun((void*)a_pFun)
348 		, m_iArgc(2)
349 		, m_iPri(-1)
350 		, m_eOprtAsct(oaNONE)
351 		, m_iCode(cmFUNC_STR)
352 		, m_iType(tpSTR)
353 		, m_bAllowOpti(a_bAllowOpti)
354 	{}
355 
356 
ParserCallback(strfun_type4 a_pFun,bool a_bAllowOpti)357 	ParserCallback::ParserCallback(strfun_type4 a_pFun, bool a_bAllowOpti)
358 		:m_pFun((void*)a_pFun)
359 		, m_iArgc(3)
360 		, m_iPri(-1)
361 		, m_eOprtAsct(oaNONE)
362 		, m_iCode(cmFUNC_STR)
363 		, m_iType(tpSTR)
364 		, m_bAllowOpti(a_bAllowOpti)
365 	{}
366 
367 
ParserCallback(strfun_type5 a_pFun,bool a_bAllowOpti)368 	ParserCallback::ParserCallback(strfun_type5 a_pFun, bool a_bAllowOpti)
369 		:m_pFun((void*)a_pFun)
370 		, m_iArgc(4)
371 		, m_iPri(-1)
372 		, m_eOprtAsct(oaNONE)
373 		, m_iCode(cmFUNC_STR)
374 		, m_iType(tpSTR)
375 		, m_bAllowOpti(a_bAllowOpti)
376 	{}
377 
378 
379 	/** \brief Default constructor.
380 		\throw nothrow
381 	*/
ParserCallback()382 	ParserCallback::ParserCallback()
383 		:m_pFun(0)
384 		, m_iArgc(0)
385 		, m_iPri(-1)
386 		, m_eOprtAsct(oaNONE)
387 		, m_iCode(cmUNKNOWN)
388 		, m_iType(tpVOID)
389 		, m_bAllowOpti(0)
390 	{}
391 
392 
393 	/** \brief Copy constructor.
394 		\throw nothrow
395 	*/
ParserCallback(const ParserCallback & ref)396 	ParserCallback::ParserCallback(const ParserCallback& ref)
397 	{
398 		m_pFun = ref.m_pFun;
399 		m_iArgc = ref.m_iArgc;
400 		m_bAllowOpti = ref.m_bAllowOpti;
401 		m_iCode = ref.m_iCode;
402 		m_iType = ref.m_iType;
403 		m_iPri = ref.m_iPri;
404 		m_eOprtAsct = ref.m_eOprtAsct;
405 	}
406 
operator =(const ParserCallback & ref)407   ParserCallback & ParserCallback::operator=(const ParserCallback & ref)
408   {
409     if (this != &ref)
410     {
411       m_pFun = ref.m_pFun;
412       m_iArgc = ref.m_iArgc;
413       m_bAllowOpti = ref.m_bAllowOpti;
414       m_iCode = ref.m_iCode;
415       m_iType = ref.m_iType;
416       m_iPri = ref.m_iPri;
417       m_eOprtAsct = ref.m_eOprtAsct;
418     }
419     return *this;
420   }
421 
422 	/** \brief Clone this instance and return a pointer to the new instance. */
Clone() const423 	ParserCallback* ParserCallback::Clone() const
424 	{
425 		return new ParserCallback(*this);
426 	}
427 
428 
429 	/** \brief Return tru if the function is conservative.
430 
431 		Conservative functions return always the same result for the same argument.
432 		\throw nothrow
433 	*/
IsOptimizable() const434 	bool ParserCallback::IsOptimizable() const
435 	{
436 		return m_bAllowOpti;
437 	}
438 
439 
440 	/** \brief Get the callback address for the parser function.
441 
442 		The type of the address is void. It needs to be recasted according to the
443 		argument number to the right type.
444 
445 		\throw nothrow
446 		\return #pFun
447 	*/
GetAddr() const448 	void* ParserCallback::GetAddr() const
449 	{
450 		return m_pFun;
451 	}
452 
453 
454 	/** \brief Return the callback code. */
GetCode() const455 	ECmdCode  ParserCallback::GetCode() const
456 	{
457 		return m_iCode;
458 	}
459 
460 
GetType() const461 	ETypeCode ParserCallback::GetType() const
462 	{
463 		return m_iType;
464 	}
465 
466 
467 	/** \brief Return the operator precedence.
468 		\throw nothrown
469 
470 	   Only valid if the callback token is an operator token (binary or infix).
471 	*/
GetPri() const472 	int ParserCallback::GetPri()  const
473 	{
474 		return m_iPri;
475 	}
476 
477 
478 	/** \brief Return the operators associativity.
479 		\throw nothrown
480 
481 	   Only valid if the callback token is a binary operator token.
482 	*/
GetAssociativity() const483 	EOprtAssociativity ParserCallback::GetAssociativity() const
484 	{
485 		return m_eOprtAsct;
486 	}
487 
488 
489 	/** \brief Returns the number of function Arguments. */
GetArgc() const490 	int ParserCallback::GetArgc() const
491 	{
492 		return m_iArgc;
493 	}
494 } // namespace mu
495 
496 #if defined(_MSC_VER)
497 	#pragma warning(pop)
498 #endif
499