]> Shamusworld >> Repos - architektonas/blob - fparser/fparser.cc
Fixed problem with MDI activation.
[architektonas] / fparser / fparser.cc
1 /***************************************************************************\
2 |* Function Parser for C++ v4.3                                            *|
3 |*-------------------------------------------------------------------------*|
4 |* Copyright: Juha Nieminen, Joel Yliluoma                                 *|
5 |*                                                                         *|
6 |* This library is distributed under the terms of the                      *|
7 |* GNU Lesser General Public License version 3.                            *|
8 |* (See lgpl.txt and gpl.txt for the license text.)                        *|
9 \***************************************************************************/
10
11 #include "fpconfig.hh"
12 #include "fparser.hh"
13
14 #include <set>
15 #include <cstdlib>
16 #include <cstring>
17 #include <cctype>
18 #include <cmath>
19 #include <cassert>
20 #include <limits>
21 using namespace std;
22
23 #include "fptypes.hh"
24 using namespace FUNCTIONPARSERTYPES;
25
26 #ifdef FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA
27 #ifndef FP_USE_THREAD_SAFE_EVAL
28 #define FP_USE_THREAD_SAFE_EVAL
29 #endif
30 #endif
31
32 #ifdef __GNUC__
33 # define likely(x)       __builtin_expect(!!(x), 1)
34 # define unlikely(x)     __builtin_expect(!!(x), 0)
35 #else
36 # define likely(x)   (x)
37 # define unlikely(x) (x)
38 #endif
39
40
41 //=========================================================================
42 // Opcode analysis functions
43 //=========================================================================
44 // These functions are used by the Parse() bytecode optimizer (mostly from
45 // code in fp_opcode_add.inc).
46
47 bool FUNCTIONPARSERTYPES::IsLogicalOpcode(unsigned op)
48 {
49     switch(op)
50     {
51       case cAnd: case cAbsAnd:
52       case cOr:  case cAbsOr:
53       case cNot: case cAbsNot:
54       case cNotNot: case cAbsNotNot:
55       case cEqual: case cNEqual:
56       case cLess: case cLessOrEq:
57       case cGreater: case cGreaterOrEq:
58           return true;
59       default: break;
60     }
61     return false;
62 }
63
64 bool FUNCTIONPARSERTYPES::IsComparisonOpcode(unsigned op)
65 {
66     switch(op)
67     {
68       case cEqual: case cNEqual:
69       case cLess: case cLessOrEq:
70       case cGreater: case cGreaterOrEq:
71           return true;
72       default: break;
73     }
74     return false;
75 }
76
77 unsigned FUNCTIONPARSERTYPES::OppositeComparisonOpcode(unsigned op)
78 {
79     switch(op)
80     {
81       case cLess: return cGreater;
82       case cGreater: return cLess;
83       case cLessOrEq: return cGreaterOrEq;
84       case cGreaterOrEq: return cLessOrEq;
85     }
86     return op;
87 }
88
89 bool FUNCTIONPARSERTYPES::IsNeverNegativeValueOpcode(unsigned op)
90 {
91     switch(op)
92     {
93       case cAnd: case cAbsAnd:
94       case cOr:  case cAbsOr:
95       case cNot: case cAbsNot:
96       case cNotNot: case cAbsNotNot:
97       case cEqual: case cNEqual:
98       case cLess: case cLessOrEq:
99       case cGreater: case cGreaterOrEq:
100       case cSqrt: case cRSqrt: case cSqr:
101       case cHypot:
102       case cAbs:
103       case cAcos: case cCosh:
104           return true;
105       default: break;
106     }
107     return false;
108 }
109
110 bool FUNCTIONPARSERTYPES::IsAlwaysIntegerOpcode(unsigned op)
111 {
112     switch(op)
113     {
114       case cAnd: case cAbsAnd:
115       case cOr:  case cAbsOr:
116       case cNot: case cAbsNot:
117       case cNotNot: case cAbsNotNot:
118       case cEqual: case cNEqual:
119       case cLess: case cLessOrEq:
120       case cGreater: case cGreaterOrEq:
121       case cInt: case cFloor: case cCeil: case cTrunc:
122           return true;
123       default: break;
124     }
125     return false;
126 }
127
128 bool FUNCTIONPARSERTYPES::IsUnaryOpcode(unsigned op)
129 {
130     switch(op)
131     {
132       case cInv: case cNeg:
133       case cNot: case cAbsNot:
134       case cNotNot: case cAbsNotNot:
135       case cSqr: case cRSqrt:
136       case cDeg: case cRad:
137           return true;
138     }
139     return (op < FUNC_AMOUNT && Functions[op].params == 1);
140 }
141
142 bool FUNCTIONPARSERTYPES::IsBinaryOpcode(unsigned op)
143 {
144     switch(op)
145     {
146       case cAdd: case cSub: case cRSub:
147       case cMul: case cDiv: case cRDiv:
148       case cMod:
149       case cEqual: case cNEqual: case cLess:
150       case cLessOrEq: case cGreater: case cGreaterOrEq:
151       case cAnd: case cAbsAnd:
152       case cOr: case cAbsOr:
153           return true;
154     }
155     return (op < FUNC_AMOUNT && Functions[op].params == 2);
156 }
157
158 bool FUNCTIONPARSERTYPES::HasInvalidRangesOpcode(unsigned op)
159 {
160 #ifndef FP_NO_EVALUATION_CHECKS
161     // Returns true, if the given opcode has a range of
162     // input values that gives an error.
163     switch(op)
164     {
165       case cAcos: // allowed range: |x| <= 1
166       case cAsin: // allowed range: |x| <= 1
167       case cAcosh: // allowed range: x >= 1
168       case cAtanh: // allowed range: |x| < 1
169           //case cCot: // note: no range, just separate values
170           //case cCsc: // note: no range, just separate values
171       case cLog: // allowed range: x > 0
172       case cLog2: // allowed range: x > 0
173       case cLog10: // allowed range: x > 0
174 #ifdef FP_SUPPORT_OPTIMIZER
175       case cLog2by: // allowed range: x > 0
176 #endif
177           //case cPow: // note: no range, just separate values
178           //case cSec: // note: no range, just separate values
179       case cSqrt: // allowed range: x >= 0
180       case cRSqrt: // allowed range: x > 0
181           //case cDiv: // note: no range, just separate values
182           //case cRDiv: // note: no range, just separate values
183           //case cInv: // note: no range, just separate values
184           return true;
185     }
186 #endif
187     return false;
188 }
189
190
191 //=========================================================================
192 // Mathematical template functions
193 //=========================================================================
194 /* fp_pow() is a wrapper for std::pow()
195  * that produces an identical value for
196  * exp(1) ^ 2.0  (0x4000000000000000)
197  * as exp(2.0)   (0x4000000000000000)
198  * - std::pow() on x86_64
199  * produces 2.0  (0x3FFFFFFFFFFFFFFF) instead!
200  * See comments below for other special traits.
201  */
202 namespace
203 {
204     template<typename ValueT>
205     inline ValueT fp_pow_with_exp_log(const ValueT& x, const ValueT& y)
206     {
207         // Exponentiation using exp(log(x)*y).
208         // See http://en.wikipedia.org/wiki/Exponentiation#Real_powers
209         // Requirements: x > 0.
210         return fp_exp(fp_log(x) * y);
211     }
212
213     template<typename ValueT>
214     inline ValueT fp_powi(ValueT x, unsigned long y)
215     {
216         // Fast binary exponentiation algorithm
217         // See http://en.wikipedia.org/wiki/Exponentiation_by_squaring
218         // Requirements: y is non-negative integer.
219         ValueT result(1);
220         while(y != 0)
221         {
222             if(y & 1) { result *= x; y -= 1; }
223             else      { x *= x;      y /= 2; }
224         }
225         return result;
226     }
227 }
228
229 template<typename ValueT>
230 ValueT FUNCTIONPARSERTYPES::fp_pow(const ValueT& x, const ValueT& y)
231 {
232     if(x == ValueT(1)) return ValueT(1);
233     // y is now zero or positive
234     if(isLongInteger(y))
235     {
236         // Use fast binary exponentiation algorithm
237         if(y >= ValueT(0))
238             return fp_powi(x,              makeLongInteger(y));
239         else
240             return ValueT(1) / fp_powi(x, -makeLongInteger(y));
241     }
242     if(y >= ValueT(0))
243     {
244         // y is now positive. Calculate using exp(log(x)*y).
245         if(x > ValueT(0)) return fp_pow_with_exp_log(x, y);
246         if(x == ValueT(0)) return ValueT(0);
247         // At this point, y > 0.0 and x is known to be < 0.0,
248         // because positive and zero cases are already handled.
249         if(!isInteger(y*ValueT(16)))
250             return -fp_pow_with_exp_log(-x, y);
251         // ^This is not technically correct, but it allows
252         // functions such as cbrt(x^5), that is, x^(5/3),
253         // to be evaluated when x is negative.
254         // It is too complicated (and slow) to test whether y
255         // is a formed from a ratio of an integer to an odd integer.
256         // (And due to floating point inaccuracy, pointless too.)
257         // For example, x^1.30769230769... is
258         // actually x^(17/13), i.e. (x^17) ^ (1/13).
259         // (-5)^(17/13) gives us now -8.204227562330453.
260         // To see whether the result is right, we can test the given
261         // root: (-8.204227562330453)^13 gives us the value of (-5)^17,
262         // which proves that the expression was correct.
263         //
264         // The y*16 check prevents e.g. (-4)^(3/2) from being calculated,
265         // as it would confuse functioninfo when pow() returns no error
266         // but sqrt() does when the formula is converted into sqrt(x)*x.
267         //
268         // The errors in this approach are:
269         //     (-2)^sqrt(2) should produce NaN
270         //                  or actually sqrt(2)I + 2^sqrt(2),
271         //                  produces -(2^sqrt(2)) instead.
272         //                  (Impact: Neglible)
273         // Thus, at worst, we're changing a NaN (or complex)
274         // result into a negative real number result.
275     }
276     else
277     {
278         // y is negative. Utilize the x^y = 1/(x^-y) identity.
279         if(x > ValueT(0)) return fp_pow_with_exp_log(ValueT(1) / x, -y);
280         if(x < ValueT(0))
281         {
282             if(!isInteger(y*ValueT(-16)))
283                 return -fp_pow_with_exp_log(ValueT(-1) / x, -y);
284             // ^ See comment above.
285         }
286         // Remaining case: 0.0 ^ negative number
287     }
288     // This is reached when:
289     //      x=0, and y<0
290     //      x<0, and y*16 is either positive or negative integer
291     // It is used for producing error values and as a safe fallback.
292     return fp_pow_base(x, y);
293 }
294
295
296 //=========================================================================
297 // Elementary (atom) parsing functions
298 //=========================================================================
299 namespace
300 {
301     /* Reads an UTF8-encoded sequence which forms a valid identifier name from
302        the given input string and returns its length. If bit 31 is set, the
303        return value also contains the internal function opcode (defined in
304        fptypes.hh) that matches the name.
305     */
306     unsigned readIdentifierForFloatType(const char* input)
307     {
308         /* Assuming unsigned = 32 bits:
309               76543210 76543210 76543210 76543210
310            Return value if built-in function:
311               1PPPPPPP PPPPPPPP LLLLLLLL LLLLLLLL
312                 P = function opcode      (15 bits)
313                 L = function name length (16 bits)
314            Return value if not built-in function:
315               0LLLLLLL LLLLLLLL LLLLLLLL LLLLLLLL
316                 L = identifier length (31 bits)
317            If unsigned has more than 32 bits, the other
318            higher order bits are to be assumed zero.
319         */
320 #include "fp_identifier_parser.inc"
321         return 0;
322     }
323
324     inline unsigned readIdentifierForIntType(const char* input)
325     {
326         const unsigned value = readIdentifierForFloatType(input);
327         if((value & 0x80000000U) != 0 &&
328            !Functions[(value >> 16) & 0x7FFF].okForInt())
329             return value & 0xFFFF;
330         return value;
331     }
332
333     template<typename Value_t>
334     inline unsigned readIdentifier(const char* input)
335     {
336         return IsIntType<Value_t>::result
337                 ? readIdentifierForIntType(input)
338                 : readIdentifierForFloatType(input);
339     }
340
341     // Returns true if the entire string is a valid identifier
342     template<typename Value_t>
343     bool containsOnlyValidIdentifierChars(const std::string& name)
344     {
345         if(name.empty()) return false;
346         return readIdentifier<Value_t>(name.c_str()) == (unsigned) name.size();
347     }
348
349
350     // -----------------------------------------------------------------------
351     // Wrappers for strto... functions
352     // -----------------------------------------------------------------------
353     template<typename Value_t>
354     inline Value_t fp_parseLiteral(const char* str, char** endptr)
355     {
356         return strtod(str, endptr);
357     }
358
359 #ifdef FP_SUPPORT_FLOAT_TYPE
360     template<>
361     inline float fp_parseLiteral<float>(const char* str, char** endptr)
362     {
363         return strtof(str, endptr);
364     }
365 #endif
366
367 #ifdef FP_SUPPORT_LONG_DOUBLE_TYPE
368     template<>
369     inline long double fp_parseLiteral<long double>(const char* str,
370                                                     char** endptr)
371     {
372         return strtold(str, endptr);
373     }
374 #endif
375
376 #ifdef FP_SUPPORT_LONG_INT_TYPE
377     template<>
378     inline long fp_parseLiteral<long>(const char* str, char** endptr)
379     {
380         return strtol(str, endptr, 10);
381     }
382 #endif
383
384
385     // -----------------------------------------------------------------------
386     // Hexadecimal floating point literal parsing
387     // -----------------------------------------------------------------------
388     inline int testXdigit(unsigned c)
389     {
390         if((c-'0') < 10u) return c&15; // 0..9
391         if(((c|0x20)-'a') < 6u) return 9+(c&15); // A..F or a..f
392         return -1; // Not a hex digit
393     }
394
395     template<typename elem_t, unsigned n_limbs, unsigned limb_bits>
396     inline void addXdigit(elem_t* buffer, unsigned nibble)
397     {
398         for(unsigned p=0; p<n_limbs; ++p)
399         {
400             unsigned carry = unsigned( buffer[p] >> (elem_t)(limb_bits-4) );
401             buffer[p] = (buffer[p] << 4) | nibble;
402             nibble = carry;
403         }
404     }
405
406     template<typename Value_t>
407     Value_t parseHexLiteral(const char* str, char** endptr)
408     {
409         const unsigned bits_per_char = 8;
410
411         const int MantissaBits =
412             std::numeric_limits<Value_t>::radix == 2
413             ? std::numeric_limits<Value_t>::digits
414             : (((sizeof(Value_t) * bits_per_char) &~ 3) - 4);
415
416         typedef unsigned long elem_t;
417         const int ExtraMantissaBits = 4 + ((MantissaBits+3)&~3); // Store one digit more for correct rounding
418         const unsigned limb_bits = sizeof(elem_t) * bits_per_char;
419         const unsigned n_limbs   = (ExtraMantissaBits + limb_bits-1) / limb_bits;
420         elem_t mantissa_buffer[n_limbs] = { 0 };
421
422         int n_mantissa_bits = 0; // Track the number of bits
423         int exponent = 0; // The exponent that will be used to multiply the mantissa
424         // Read integer portion
425         while(true)
426         {
427             int xdigit = testXdigit(*str);
428             if(xdigit < 0) break;
429             addXdigit<elem_t,n_limbs,limb_bits> (mantissa_buffer, xdigit);
430             ++str;
431
432             n_mantissa_bits += 4;
433             if(n_mantissa_bits >= ExtraMantissaBits)
434             {
435                 // Exhausted the precision. Parse the rest (until exponent)
436                 // normally but ignore the actual digits.
437                 for(; testXdigit(*str) >= 0; ++str)
438                     exponent += 4;
439                 // Read but ignore decimals
440                 if(*str == '.')
441                     for(++str; testXdigit(*str) >= 0; ++str)
442                         {}
443                 goto read_exponent;
444             }
445         }
446         // Read decimals
447         if(*str == '.')
448             for(++str; ; )
449             {
450                 int xdigit = testXdigit(*str);
451                 if(xdigit < 0) break;
452                 addXdigit<elem_t,n_limbs,limb_bits> (mantissa_buffer, xdigit);
453                 ++str;
454
455                 exponent -= 4;
456                 n_mantissa_bits += 4;
457                 if(n_mantissa_bits >= ExtraMantissaBits)
458                 {
459                     // Exhausted the precision. Skip the rest
460                     // of the decimals, until the exponent.
461                     while(testXdigit(*str) >= 0)
462                         ++str;
463                     break;
464                 }
465             }
466
467         // Read exponent
468     read_exponent:
469         if(*str == 'p' || *str == 'P')
470         {
471             const char* str2 = str+1;
472             long p_exponent = strtol(str2, (char**) &str2, 10);
473             if(str2 != str+1 && p_exponent == (long)(int)p_exponent)
474             {
475                 exponent += (int)p_exponent;
476                 str = str2;
477             }
478         }
479
480         if(endptr) *endptr = (char*) str;
481
482         Value_t result = ldexp(Value_t(mantissa_buffer[0]), exponent);
483         for(unsigned p=1; p<n_limbs; ++p)
484         {
485             exponent += limb_bits;
486             result += ldexp(Value_t(mantissa_buffer[p]), exponent);
487         }
488         return result;
489     }
490
491 #ifdef FP_SUPPORT_LONG_INT_TYPE
492     template<>
493     long parseHexLiteral<long>(const char* str, char** endptr)
494     {
495         return strtol(str, endptr, 16);
496     }
497 #endif
498 }
499
500 //=========================================================================
501 // Utility functions
502 //=========================================================================
503 namespace
504 {
505     // -----------------------------------------------------------------------
506     // Add a new identifier to the specified identifier map
507     // -----------------------------------------------------------------------
508     // Return value will be false if the name already existed
509     template<typename Value_t>
510     bool addNewNameData(NamePtrsMap<Value_t>& namePtrs,
511                         std::pair<NamePtr, NameData<Value_t> >& newName,
512                         bool isVar)
513     {
514         typename NamePtrsMap<Value_t>::iterator nameIter =
515             namePtrs.lower_bound(newName.first);
516
517         if(nameIter != namePtrs.end() && newName.first == nameIter->first)
518         {
519             // redefining a var is not allowed.
520             if(isVar) return false;
521
522             // redefining other tokens is allowed, if the type stays the same.
523             if(nameIter->second.type != newName.second.type)
524                 return false;
525
526             // update the data
527             nameIter->second = newName.second;
528             return true;
529         }
530
531         if(!isVar)
532         {
533             // Allocate a copy of the name (pointer stored in the map key)
534             // However, for VARIABLEs, the pointer points to VariableString,
535             // which is managed separately. Thusly, only done when !IsVar.
536             char* namebuf = new char[newName.first.nameLength];
537             memcpy(namebuf, newName.first.name, newName.first.nameLength);
538             newName.first.name = namebuf;
539         }
540
541         namePtrs.insert(nameIter, newName);
542         return true;
543     }
544 }
545
546
547 //=========================================================================
548 // Data struct implementation
549 //=========================================================================
550 template<typename Value_t>
551 FunctionParserBase<Value_t>::Data::Data():
552     mReferenceCounter(1),
553     mVariablesAmount(0),
554     mStackSize(0)
555 {}
556
557 template<typename Value_t>
558 FunctionParserBase<Value_t>::Data::Data(const Data& rhs):
559     mReferenceCounter(0),
560     mVariablesAmount(rhs.mVariablesAmount),
561     mVariablesString(rhs.mVariablesString),
562     mNamePtrs(),
563     mFuncPtrs(rhs.mFuncPtrs),
564     mFuncParsers(rhs.mFuncParsers),
565     mByteCode(rhs.mByteCode),
566     mImmed(rhs.mImmed),
567 #ifndef FP_USE_THREAD_SAFE_EVAL
568     mStack(rhs.mStackSize),
569 #endif
570     mStackSize(rhs.mStackSize)
571 {
572     for(typename NamePtrsMap<Value_t>::const_iterator i = rhs.mNamePtrs.begin();
573         i != rhs.mNamePtrs.end();
574         ++i)
575     {
576         if(i->second.type == NameData<Value_t>::VARIABLE)
577         {
578             const size_t variableStringOffset =
579                 i->first.name - rhs.mVariablesString.c_str();
580             std::pair<NamePtr, NameData<Value_t> > tmp
581                 (NamePtr(&mVariablesString[variableStringOffset],
582                          i->first.nameLength),
583                  i->second);
584             mNamePtrs.insert(mNamePtrs.end(), tmp);
585         }
586         else
587         {
588             std::pair<NamePtr, NameData<Value_t> > tmp
589                 (NamePtr(new char[i->first.nameLength], i->first.nameLength),
590                  i->second );
591             memcpy(const_cast<char*>(tmp.first.name), i->first.name,
592                    tmp.first.nameLength);
593             mNamePtrs.insert(mNamePtrs.end(), tmp);
594         }
595     }
596 }
597
598 template<typename Value_t>
599 FunctionParserBase<Value_t>::Data::~Data()
600 {
601     for(typename NamePtrsMap<Value_t>::iterator i = mNamePtrs.begin();
602         i != mNamePtrs.end();
603         ++i)
604     {
605         if(i->second.type != NameData<Value_t>::VARIABLE)
606             delete[] i->first.name;
607     }
608 }
609
610
611 //=========================================================================
612 // FunctionParser constructors, destructor and assignment
613 //=========================================================================
614 template<typename Value_t>
615 FunctionParserBase<Value_t>::FunctionParserBase():
616     mDelimiterChar(0),
617     mParseErrorType(NO_FUNCTION_PARSED_YET), mEvalErrorType(0),
618     mData(new Data),
619     mUseDegreeConversion(false),
620     mEvalRecursionLevel(0),
621     mStackPtr(0), mErrorLocation(0)
622 {
623 }
624
625 template<typename Value_t>
626 FunctionParserBase<Value_t>::~FunctionParserBase()
627 {
628     if(--(mData->mReferenceCounter) == 0)
629         delete mData;
630 }
631
632 template<typename Value_t>
633 FunctionParserBase<Value_t>::FunctionParserBase(const FunctionParserBase& cpy):
634     mDelimiterChar(cpy.mDelimiterChar),
635     mParseErrorType(cpy.mParseErrorType),
636     mEvalErrorType(cpy.mEvalErrorType),
637     mData(cpy.mData),
638     mUseDegreeConversion(cpy.mUseDegreeConversion),
639     mEvalRecursionLevel(0),
640     mStackPtr(0), mErrorLocation(0)
641 {
642     ++(mData->mReferenceCounter);
643 }
644
645 template<typename Value_t>
646 FunctionParserBase<Value_t>&
647 FunctionParserBase<Value_t>::operator=(const FunctionParserBase& cpy)
648 {
649     if(mData != cpy.mData)
650     {
651         if(--(mData->mReferenceCounter) == 0) delete mData;
652
653         mDelimiterChar = cpy.mDelimiterChar;
654         mParseErrorType = cpy.mParseErrorType;
655         mEvalErrorType = cpy.mEvalErrorType;
656         mData = cpy.mData;
657         mUseDegreeConversion = cpy.mUseDegreeConversion;
658         mEvalRecursionLevel = cpy.mEvalRecursionLevel;
659
660         ++(mData->mReferenceCounter);
661     }
662
663     return *this;
664 }
665
666
667 template<typename Value_t>
668 void FunctionParserBase<Value_t>::setDelimiterChar(char c)
669 {
670     mDelimiterChar = c;
671 }
672
673
674 //---------------------------------------------------------------------------
675 // Copy-on-write method
676 //---------------------------------------------------------------------------
677 template<typename Value_t>
678 void FunctionParserBase<Value_t>::CopyOnWrite()
679 {
680     if(mData->mReferenceCounter > 1)
681     {
682         Data* oldData = mData;
683         mData = new Data(*oldData);
684         --(oldData->mReferenceCounter);
685         mData->mReferenceCounter = 1;
686     }
687 }
688
689 template<typename Value_t>
690 void FunctionParserBase<Value_t>::ForceDeepCopy()
691 {
692     CopyOnWrite();
693 }
694
695
696 //=========================================================================
697 // User-defined identifier addition functions
698 //=========================================================================
699 template<typename Value_t>
700 bool FunctionParserBase<Value_t>::AddConstant(const std::string& name,
701                                               Value_t value)
702 {
703     if(!containsOnlyValidIdentifierChars<Value_t>(name)) return false;
704
705     CopyOnWrite();
706     std::pair<NamePtr, NameData<Value_t> > newName
707         (NamePtr(name.data(), unsigned(name.size())),
708          NameData<Value_t>(NameData<Value_t>::CONSTANT, value));
709
710     return addNewNameData(mData->mNamePtrs, newName, false);
711 }
712
713 template<typename Value_t>
714 bool FunctionParserBase<Value_t>::AddUnit(const std::string& name,
715                                           Value_t value)
716 {
717     if(!containsOnlyValidIdentifierChars<Value_t>(name)) return false;
718
719     CopyOnWrite();
720     std::pair<NamePtr, NameData<Value_t> > newName
721         (NamePtr(name.data(), unsigned(name.size())),
722          NameData<Value_t>(NameData<Value_t>::UNIT, value));
723     return addNewNameData(mData->mNamePtrs, newName, false);
724 }
725
726 template<typename Value_t>
727 bool FunctionParserBase<Value_t>::AddFunction
728 (const std::string& name, FunctionPtr ptr, unsigned paramsAmount)
729 {
730     if(!containsOnlyValidIdentifierChars<Value_t>(name)) return false;
731
732     CopyOnWrite();
733     std::pair<NamePtr, NameData<Value_t> > newName
734         (NamePtr(name.data(), unsigned(name.size())),
735          NameData<Value_t>(NameData<Value_t>::FUNC_PTR,
736                            unsigned(mData->mFuncPtrs.size())));
737
738     const bool success = addNewNameData(mData->mNamePtrs, newName, false);
739     if(success)
740     {
741         mData->mFuncPtrs.push_back(typename Data::FuncPtrData());
742         mData->mFuncPtrs.back().mFuncPtr = ptr;
743         mData->mFuncPtrs.back().mParams = paramsAmount;
744     }
745     return success;
746 }
747
748 template<typename Value_t>
749 bool FunctionParserBase<Value_t>::CheckRecursiveLinking
750 (const FunctionParserBase* fp) const
751 {
752     if(fp == this) return true;
753     for(unsigned i = 0; i < fp->mData->mFuncParsers.size(); ++i)
754         if(CheckRecursiveLinking(fp->mData->mFuncParsers[i].mParserPtr))
755             return true;
756     return false;
757 }
758
759 template<typename Value_t>
760 bool FunctionParserBase<Value_t>::AddFunction(const std::string& name,
761                                               FunctionParserBase& fp)
762 {
763     if(!containsOnlyValidIdentifierChars<Value_t>(name) ||
764        CheckRecursiveLinking(&fp))
765         return false;
766
767     CopyOnWrite();
768     std::pair<NamePtr, NameData<Value_t> > newName
769         (NamePtr(name.data(), unsigned(name.size())),
770          NameData<Value_t>(NameData<Value_t>::PARSER_PTR,
771                            unsigned(mData->mFuncParsers.size())));
772
773     const bool success = addNewNameData(mData->mNamePtrs, newName, false);
774     if(success)
775     {
776         mData->mFuncParsers.push_back(typename Data::FuncPtrData());
777         mData->mFuncParsers.back().mParserPtr = &fp;
778         mData->mFuncParsers.back().mParams = fp.mData->mVariablesAmount;
779     }
780     return success;
781 }
782
783 template<typename Value_t>
784 bool FunctionParserBase<Value_t>::RemoveIdentifier(const std::string& name)
785 {
786     CopyOnWrite();
787
788     NamePtr namePtr(name.data(), unsigned(name.size()));
789
790     typename NamePtrsMap<Value_t>::iterator
791         nameIter = mData->mNamePtrs.find(namePtr);
792
793     if(nameIter != mData->mNamePtrs.end())
794     {
795         if(nameIter->second.type == NameData<Value_t>::VARIABLE)
796         {
797             // Illegal attempt to delete variables
798             return false;
799         }
800         delete[] nameIter->first.name;
801         mData->mNamePtrs.erase(nameIter);
802         return true;
803     }
804     return false;
805 }
806
807
808 //=========================================================================
809 // Function parsing
810 //=========================================================================
811 namespace
812 {
813     // Error messages returned by ErrorMsg():
814     const char* const ParseErrorMessage[]=
815     {
816         "Syntax error",                             // 0
817         "Mismatched parenthesis",                   // 1
818         "Missing ')'",                              // 2
819         "Empty parentheses",                        // 3
820         "Syntax error: Operator expected",          // 4
821         "Not enough memory",                        // 5
822         "An unexpected error occurred. Please make a full bug report "
823         "to the author",                            // 6
824         "Syntax error in parameter 'Vars' given to "
825         "FunctionParser::Parse()",                  // 7
826         "Illegal number of parameters to function", // 8
827         "Syntax error: Premature end of string",    // 9
828         "Syntax error: Expecting ( after function", // 10
829         "Syntax error: Unknown identifier",         // 11
830         "(No function has been parsed yet)",
831         ""
832     };
833
834     template<typename Value_t>
835     inline typename FunctionParserBase<Value_t>::ParseErrorType
836     noCommaError(char c)
837     {
838         return c == ')' ?
839             FunctionParserBase<Value_t>::ILL_PARAMS_AMOUNT :
840             FunctionParserBase<Value_t>::SYNTAX_ERROR;
841     }
842
843     template<typename Value_t>
844     inline typename FunctionParserBase<Value_t>::ParseErrorType
845     noParenthError(char c)
846     {
847         return c == ',' ?
848             FunctionParserBase<Value_t>::ILL_PARAMS_AMOUNT :
849             FunctionParserBase<Value_t>::MISSING_PARENTH;
850     }
851
852     template<unsigned offset>
853     struct IntLiteralMask
854     {
855         enum { mask =
856         //    (    1UL << ('-'-offset)) |
857             (0x3FFUL << ('0'-offset)) }; /* 0x3FF = 10 bits worth "1" */
858         // Note: If you change fparser to support negative numbers parsing
859         //       (as opposed to parsing them as cNeg followed by literal),
860         //       enable the '-' line above, and change the offset value
861         //       in BeginsLiteral() to '-' instead of '.'.
862     };
863
864     template<typename Value_t, unsigned offset>
865     struct LiteralMask
866     {
867         enum { mask =
868             (    1UL << ('.'-offset)) |
869             IntLiteralMask<offset>::mask };
870     };
871 #ifdef FP_SUPPORT_LONG_INT_TYPE
872     template<unsigned offset>
873     struct LiteralMask<long, offset>: public IntLiteralMask<offset>
874     {
875     };
876 #endif
877 #ifdef FP_SUPPORT_GMP_INT_TYPE
878     template<unsigned offset>
879     struct LiteralMask<GmpInt, offset>: public IntLiteralMask<offset>
880     {
881     };
882 #endif
883
884     template<unsigned offset>
885     struct SimpleSpaceMask
886     {
887         enum { mask =
888             (1UL << ('\r'-offset)) |
889             (1UL << ('\n'-offset)) |
890             (1UL << ('\v'-offset)) |
891             (1UL << ('\t'-offset)) |
892             (1UL << (' ' -offset)) };
893     };
894
895     template<typename Value_t>
896     inline bool BeginsLiteral(unsigned byte)
897     {
898         const unsigned n = sizeof(unsigned long)>=8 ? 0 : '.';
899         byte -= n;
900         if(byte > (unsigned char)('9'-n)) return false;
901         unsigned long shifted = 1UL << byte;
902         const unsigned long mask = LiteralMask<Value_t, n>::mask;
903         return (mask & shifted) != 0;
904     }
905
906     template<typename CharPtr>
907     inline void SkipSpace(CharPtr& function)
908     {
909 /*
910         Space characters in unicode:
911 U+0020  SPACE                      Depends on font, often adjusted (see below)
912 U+00A0  NO-BREAK SPACE             As a space, but often not adjusted
913 U+2000  EN QUAD                    1 en (= 1/2 em)
914 U+2001  EM QUAD                    1 em (nominally, the height of the font)
915 U+2002  EN SPACE                   1 en (= 1/2 em)
916 U+2003  EM SPACE                   1 em
917 U+2004  THREE-PER-EM SPACE         1/3 em
918 U+2005  FOUR-PER-EM SPACE          1/4 em
919 U+2006  SIX-PER-EM SPACE           1/6 em
920 U+2007  FIGURE SPACE               Tabular width, the width of digits
921 U+2008  PUNCTUATION SPACE          The width of a period .
922 U+2009  THIN SPACE                 1/5 em (or sometimes 1/6 em)
923 U+200A  HAIR SPACE                 Narrower than THIN SPACE
924 U+200B  ZERO WIDTH SPACE           Nominally no width, but may expand
925 U+202F  NARROW NO-BREAK SPACE      Narrower than NO-BREAK SPACE (or SPACE)
926 U+205F  MEDIUM MATHEMATICAL SPACE  4/18 em
927 U+3000  IDEOGRAPHIC SPACE          The width of ideographic (CJK) characters.
928         Also:
929 U+000A  \n
930 U+000D  \r
931 U+0009  \t
932 U+000B  \v
933         As UTF-8 sequences:
934             09
935             0A
936             0B
937             0D
938             20
939             C2 A0
940             E2 80 80-8B
941             E2 80 AF
942             E2 81 9F
943             E3 80 80
944 */
945         while(true)
946         {
947             const unsigned n = sizeof(unsigned long)>=8 ? 0 : '\t';
948             typedef signed char schar;
949             unsigned byte = (unsigned char)*function;
950             byte -= n;
951             // ^Note: values smaller than n intentionally become
952             //        big values here due to integer wrap. The
953             //        comparison below thus excludes them, making
954             //        the effective range 0x09..0x20 (32-bit)
955             //        or 0x00..0x20 (64-bit) within the if-clause.
956             if(byte <= (unsigned char)(' '-n))
957             {
958                 unsigned long shifted = 1UL << byte;
959                 const unsigned long mask = SimpleSpaceMask<n>::mask;
960                 if(mask & shifted)
961                     { ++function; continue; } // \r, \n, \t, \v and space
962                 break;
963             }
964             if(likely(byte < 0xC2-n)) break;
965
966             if(byte == 0xC2-n && function[1] == char(0xA0))
967                 { function += 2; continue; } // U+00A0
968             if(byte == 0xE3-n &&
969                function[1] == char(0x80) && function[2] == char(0x80))
970                 { function += 3; continue; } // U+3000
971             if(byte == 0xE2-n)
972             {
973                 if(function[1] == char(0x81))
974                 {
975                     if(function[2] != char(0x9F)) break;
976                     function += 3; // U+205F
977                     continue;
978                 }
979                 if(function[1] == char(0x80))
980                 if(function[2] == char(0xAF) || // U+202F
981                    schar(function[2]) <= schar(0x8B) // U+2000..U+200B
982                   )
983                 {
984                     function += 3;
985                     continue;
986                 }
987             }
988             break;
989         } // while(true)
990     } // SkipSpace(CharPtr& function)
991 }
992
993 // ---------------------------------------------------------------------------
994 // Return parse error message
995 // ---------------------------------------------------------------------------
996 template<typename Value_t>
997 const char* FunctionParserBase<Value_t>::ErrorMsg() const
998 {
999     return ParseErrorMessage[mParseErrorType];
1000 }
1001
1002
1003 // ---------------------------------------------------------------------------
1004 // Parse variables
1005 // ---------------------------------------------------------------------------
1006 template<typename Value_t>
1007 bool FunctionParserBase<Value_t>::ParseVariables
1008 (const std::string& inputVarString)
1009 {
1010     if(mData->mVariablesString == inputVarString) return true;
1011
1012     /* Delete existing variables from mNamePtrs */
1013     for(typename NamePtrsMap<Value_t>::iterator i =
1014             mData->mNamePtrs.begin();
1015         i != mData->mNamePtrs.end(); )
1016     {
1017         if(i->second.type == NameData<Value_t>::VARIABLE)
1018         {
1019             typename NamePtrsMap<Value_t>::iterator j (i);
1020             ++i;
1021             mData->mNamePtrs.erase(j);
1022         }
1023         else ++i;
1024     }
1025     mData->mVariablesString = inputVarString;
1026
1027     const std::string& vars = mData->mVariablesString;
1028     const unsigned len = unsigned(vars.size());
1029
1030     unsigned varNumber = VarBegin;
1031
1032     const char* beginPtr = vars.c_str();
1033     const char* finalPtr = beginPtr + len;
1034     while(beginPtr < finalPtr)
1035     {
1036         SkipSpace(beginPtr);
1037         unsigned nameLength = readIdentifier<Value_t>(beginPtr);
1038         if(nameLength == 0 || (nameLength & 0x80000000U)) return false;
1039         const char* endPtr = beginPtr + nameLength;
1040         SkipSpace(endPtr);
1041         if(endPtr != finalPtr && *endPtr != ',') return false;
1042
1043         std::pair<NamePtr, NameData<Value_t> > newName
1044             (NamePtr(beginPtr, nameLength),
1045              NameData<Value_t>(NameData<Value_t>::VARIABLE, varNumber++));
1046
1047         if(!addNewNameData(mData->mNamePtrs, newName, true))
1048         {
1049             return false;
1050         }
1051
1052         beginPtr = endPtr + 1;
1053     }
1054
1055     mData->mVariablesAmount = varNumber - VarBegin;
1056     return true;
1057 }
1058
1059 // ---------------------------------------------------------------------------
1060 // Parse() public interface functions
1061 // ---------------------------------------------------------------------------
1062 template<typename Value_t>
1063 int FunctionParserBase<Value_t>::Parse(const char* Function,
1064                                        const std::string& Vars,
1065                                        bool useDegrees)
1066 {
1067     CopyOnWrite();
1068
1069     if(!ParseVariables(Vars))
1070     {
1071         mParseErrorType = INVALID_VARS;
1072         return int(strlen(Function));
1073     }
1074
1075     return ParseFunction(Function, useDegrees);
1076 }
1077
1078 template<typename Value_t>
1079 int FunctionParserBase<Value_t>::Parse(const std::string& Function,
1080                                        const std::string& Vars,
1081                                        bool useDegrees)
1082 {
1083     CopyOnWrite();
1084
1085     if(!ParseVariables(Vars))
1086     {
1087         mParseErrorType = INVALID_VARS;
1088         return int(Function.size());
1089     }
1090
1091     return ParseFunction(Function.c_str(), useDegrees);
1092 }
1093
1094
1095 // ---------------------------------------------------------------------------
1096 // Main parsing function
1097 // ---------------------------------------------------------------------------
1098 template<typename Value_t>
1099 int FunctionParserBase<Value_t>::ParseFunction(const char* function,
1100                                                bool useDegrees)
1101 {
1102     mUseDegreeConversion = useDegrees;
1103     mParseErrorType = FP_NO_ERROR;
1104
1105     mData->mInlineVarNames.clear();
1106     mData->mByteCode.clear(); mData->mByteCode.reserve(128);
1107     mData->mImmed.clear(); mData->mImmed.reserve(128);
1108     mData->mStackSize = mStackPtr = 0;
1109
1110     mHasByteCodeFlags = false;
1111
1112     const char* ptr = Compile(function);
1113     mData->mInlineVarNames.clear();
1114
1115     if(mHasByteCodeFlags)
1116     {
1117         for(unsigned i = unsigned(mData->mByteCode.size()); i-- > 0; )
1118             mData->mByteCode[i] &= ~0x80000000U;
1119     }
1120
1121     if(mParseErrorType != FP_NO_ERROR) return int(mErrorLocation - function);
1122
1123     assert(ptr); // Should never be null at this point. It's a bug otherwise.
1124     if(*ptr)
1125     {
1126         if(mDelimiterChar == 0 || *ptr != mDelimiterChar)
1127             mParseErrorType = EXPECT_OPERATOR;
1128         return int(ptr - function);
1129     }
1130
1131 #ifndef FP_USE_THREAD_SAFE_EVAL
1132     mData->mStack.resize(mData->mStackSize);
1133 #endif
1134
1135     return -1;
1136 }
1137
1138
1139 //=========================================================================
1140 // Parsing and bytecode compiling functions
1141 //=========================================================================
1142 template<typename Value_t>
1143 inline const char* FunctionParserBase<Value_t>::SetErrorType(ParseErrorType t,
1144                                                              const char* pos)
1145 {
1146     mParseErrorType = t;
1147     mErrorLocation = pos;
1148     return 0;
1149 }
1150
1151 template<typename Value_t>
1152 inline void FunctionParserBase<Value_t>::incStackPtr()
1153 {
1154     if(++mStackPtr > mData->mStackSize) ++(mData->mStackSize);
1155 }
1156
1157 namespace
1158 {
1159     const unsigned char powi_factor_table[128] =
1160     {
1161         0,1,0,0,0,0,0,0, 0, 0,0,0,0,0,0,3,/*   0 -  15 */
1162         0,0,0,0,0,0,0,0, 0, 5,0,3,0,0,3,0,/*  16 -  31 */
1163         0,0,0,0,0,0,0,3, 0, 0,0,0,0,5,0,0,/*  32 -  47 */
1164         0,0,5,3,0,0,3,5, 0, 3,0,0,3,0,0,3,/*  48 -  63 */
1165         0,0,0,0,0,0,0,0, 0, 0,0,3,0,0,3,0,/*  64 -  79 */
1166         0,9,0,0,0,5,0,3, 0, 0,5,7,0,0,0,5,/*  80 -  95 */
1167         0,0,0,3,5,0,3,0, 0, 3,0,0,3,0,5,3,/*  96 - 111 */
1168         0,0,3,5,0,9,0,7, 3,11,0,3,0,5,3,0,/* 112 - 127 */
1169     };
1170
1171     inline int get_powi_factor(long abs_int_exponent)
1172     {
1173         if(abs_int_exponent >= int(sizeof(powi_factor_table))) return 0;
1174         return powi_factor_table[abs_int_exponent];
1175     }
1176
1177 #if 0
1178     int EstimatePowiComplexity(int abs_int_exponent)
1179     {
1180         int cost = 0;
1181         while(abs_int_exponent > 1)
1182         {
1183             int factor = get_powi_factor(abs_int_exponent);
1184             if(factor)
1185             {
1186                 cost += EstimatePowiComplexity(factor);
1187                 abs_int_exponent /= factor;
1188                 continue;
1189             }
1190             if(!(abs_int_exponent & 1))
1191             {
1192                 abs_int_exponent /= 2;
1193                 cost += 3; // sqr
1194             }
1195             else
1196             {
1197                 cost += 4; // dup+mul
1198                 abs_int_exponent -= 1;
1199             }
1200         }
1201         return cost;
1202     }
1203 #endif
1204
1205     bool IsEligibleIntPowiExponent(long int_exponent)
1206     {
1207         if(int_exponent == 0) return false;
1208         long abs_int_exponent = int_exponent;
1209     #if 0
1210         int cost = 0;
1211
1212         if(abs_int_exponent < 0)
1213         {
1214             cost += 11;
1215             abs_int_exponent = -abs_int_exponent;
1216         }
1217
1218         cost += EstimatePowiComplexity(abs_int_exponent);
1219
1220         return cost < (10*3 + 4*4);
1221     #else
1222         if(abs_int_exponent < 0) abs_int_exponent = -abs_int_exponent;
1223
1224         return (abs_int_exponent >= 1)
1225             && (abs_int_exponent <= 46 ||
1226               (abs_int_exponent <= 1024 &&
1227               (abs_int_exponent & (abs_int_exponent - 1)) == 0));
1228     #endif
1229     }
1230
1231 #ifdef FP_EPSILON
1232     const double EpsilonOrZero = FP_EPSILON;
1233 #else
1234     const double EpsilonOrZero = 0.0;
1235 #endif
1236
1237 }
1238
1239 template<typename Value_t>
1240 inline void FunctionParserBase<Value_t>::AddImmedOpcode(Value_t value)
1241 {
1242     mData->mImmed.push_back(value);
1243     mData->mByteCode.push_back(cImmed);
1244 }
1245
1246 template<typename Value_t>
1247 inline void FunctionParserBase<Value_t>::CompilePowi(long abs_int_exponent)
1248 {
1249     int num_muls=0;
1250     while(abs_int_exponent > 1)
1251     {
1252         long factor = get_powi_factor(abs_int_exponent);
1253         if(factor)
1254         {
1255             CompilePowi(factor);
1256             abs_int_exponent /= factor;
1257             continue;
1258         }
1259         if(!(abs_int_exponent & 1))
1260         {
1261             abs_int_exponent /= 2;
1262             mData->mByteCode.push_back(cSqr);
1263             // ^ Don't put AddFunctionOpcode here,
1264             //   it would slow down a great deal.
1265         }
1266         else
1267         {
1268             mData->mByteCode.push_back(cDup);
1269             incStackPtr();
1270             abs_int_exponent -= 1;
1271             ++num_muls;
1272         }
1273     }
1274     if(num_muls > 0)
1275     {
1276         mData->mByteCode.resize(mData->mByteCode.size()+num_muls, cMul);
1277         mStackPtr -= num_muls;
1278     }
1279 }
1280
1281 template<typename Value_t>
1282 inline bool FunctionParserBase<Value_t>::TryCompilePowi(Value_t original_immed)
1283 {
1284     Value_t changed_immed = original_immed;
1285     for(int sqrt_count=0; /**/; ++sqrt_count)
1286     {
1287         long int_exponent = makeLongInteger(changed_immed);
1288         if(isLongInteger(changed_immed) &&
1289            IsEligibleIntPowiExponent(int_exponent))
1290         {
1291             long abs_int_exponent = int_exponent;
1292             if(abs_int_exponent < 0)
1293                 abs_int_exponent = -abs_int_exponent;
1294
1295             mData->mImmed.pop_back(); mData->mByteCode.pop_back();
1296             --mStackPtr;
1297             // ^Though the above is accounted for by the procedure
1298             // that generates cPow, we need it for correct cFetch
1299             // indexes in CompilePowi().
1300
1301             while(sqrt_count > 0)
1302             {
1303                 int opcode = cSqrt;
1304                 if(sqrt_count == 1 && int_exponent < 0)
1305                 {
1306                     opcode = cRSqrt;
1307                     int_exponent = -int_exponent;
1308                 }
1309                 mData->mByteCode.push_back(opcode);
1310                 --sqrt_count;
1311             }
1312             if((abs_int_exponent & 1) == 0)
1313             {
1314                 // This special rule fixes the optimization
1315                 // shortcoming of (-x)^2 with minimal overhead.
1316                 AddFunctionOpcode(cSqr);
1317                 abs_int_exponent >>= 1;
1318             }
1319             CompilePowi(abs_int_exponent);
1320             if(int_exponent < 0) mData->mByteCode.push_back(cInv);
1321             ++mStackPtr; // Needed because cPow adding will assume this.
1322             return true;
1323         }
1324         if(sqrt_count >= 4) break;
1325         changed_immed += changed_immed;
1326     }
1327
1328     // When we don't know whether x >= 0, we still know that
1329     // x^y can be safely converted into exp(y * log(x))
1330     // when y is _not_ integer, because we know that x >= 0.
1331     // Otherwise either expression will give a NaN.
1332     if(/*!isInteger(original_immed) ||*/
1333        IsNeverNegativeValueOpcode(mData->mByteCode[mData->mByteCode.size()-2]))
1334     {
1335         mData->mImmed.pop_back();
1336         mData->mByteCode.pop_back();
1337         //--mStackPtr; - accounted for by the procedure that generates cPow
1338         AddFunctionOpcode(cLog);
1339         AddImmedOpcode(original_immed);
1340         //incStackPtr(); - this and the next are redundant because...
1341         AddFunctionOpcode(cMul);
1342         //--mStackPtr;    - ...because the cImmed was popped earlier.
1343         AddFunctionOpcode(cExp);
1344         return true;
1345     }
1346     return false;
1347 }
1348
1349 //#include "fpoptimizer/opcodename.hh"
1350 // ^ needed only if FP_TRACE_BYTECODE_OPTIMIZATION() is used
1351
1352 template<typename Value_t>
1353 inline void FunctionParserBase<Value_t>::AddFunctionOpcode(unsigned opcode)
1354 {
1355 #define FP_FLOAT_VERSION 1
1356 #include "fp_opcode_add.inc"
1357 #undef FP_FLOAT_VERSION
1358 }
1359
1360 #ifdef FP_SUPPORT_LONG_INT_TYPE
1361 template<>
1362 inline void FunctionParserBase<long>::AddFunctionOpcode(unsigned opcode)
1363 {
1364     typedef long Value_t;
1365 #define FP_FLOAT_VERSION 0
1366 #include "fp_opcode_add.inc"
1367 #undef FP_FLOAT_VERSION
1368 }
1369 #endif
1370
1371 #ifdef FP_SUPPORT_GMP_INT_TYPE
1372 template<>
1373 inline void FunctionParserBase<GmpInt>::AddFunctionOpcode(unsigned opcode)
1374 {
1375     typedef GmpInt Value_t;
1376 #define FP_FLOAT_VERSION 0
1377 #include "fp_opcode_add.inc"
1378 #undef FP_FLOAT_VERSION
1379 }
1380 #endif
1381
1382 template<typename Value_t>
1383 unsigned
1384 FunctionParserBase<Value_t>::ParseIdentifier(const char* function)
1385 {
1386     return readIdentifier<Value_t>(function);
1387 }
1388
1389 template<typename Value_t>
1390 std::pair<const char*, Value_t>
1391 FunctionParserBase<Value_t>::ParseLiteral(const char* function)
1392 {
1393     char* endptr;
1394 #if 0 /* Profile the hex literal parser */
1395     if(function[0]=='0' && function[1]=='x')
1396     {
1397         // Parse hexadecimal literal if fp_parseLiteral didn't already
1398         Value_t val = parseHexLiteral<Value_t>(function+2, &endptr);
1399         if(endptr == function+2)
1400             return std::pair<const char*,Value_t> (function, Value_t());
1401         return std::pair<const char*, Value_t> (endptr, val);
1402     }
1403 #endif
1404     Value_t val = fp_parseLiteral<Value_t>(function, &endptr);
1405
1406     if(endptr == function+1 && function[0] == '0' && function[1] == 'x')
1407     {
1408         // Parse hexadecimal literal if fp_parseLiteral didn't already
1409         val = parseHexLiteral<Value_t>(function+2, &endptr);
1410         if(endptr == function+2)
1411             return std::pair<const char*,Value_t> (function, Value_t());
1412     }
1413     else if(endptr == function)
1414         return std::pair<const char*,Value_t> (function, Value_t());
1415
1416     return std::pair<const char*,Value_t> (endptr, val);
1417 }
1418
1419 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
1420 template<>
1421 std::pair<const char*, MpfrFloat>
1422 FunctionParserBase<MpfrFloat>::ParseLiteral(const char* function)
1423 {
1424     char* endPtr;
1425     const MpfrFloat val = MpfrFloat::parseString(function, &endPtr);
1426     if(endPtr == function)
1427         return std::pair<const char*,MpfrFloat> (function, MpfrFloat());
1428     return std::pair<const char*,MpfrFloat> (endPtr, val);
1429 }
1430 #endif
1431
1432 #ifdef FP_SUPPORT_GMP_INT_TYPE
1433 template<>
1434 std::pair<const char*, GmpInt>
1435 FunctionParserBase<GmpInt>::ParseLiteral(const char* function)
1436 {
1437     char* endPtr;
1438     const GmpInt val = GmpInt::parseString(function, &endPtr);
1439     if(endPtr == function)
1440         return std::pair<const char*,GmpInt> (function, GmpInt());
1441     return std::pair<const char*,GmpInt> (endPtr, val);
1442 }
1443 #endif
1444
1445
1446 template<typename Value_t>
1447 inline const char*
1448 FunctionParserBase<Value_t>::CompileLiteral(const char* function)
1449 {
1450     std::pair<const char*, Value_t> result = ParseLiteral(function);
1451
1452     if(result.first == function)
1453         return SetErrorType(SYNTAX_ERROR, result.first);
1454
1455     AddImmedOpcode(result.second);
1456     incStackPtr();
1457     SkipSpace(result.first);
1458     return result.first;
1459 }
1460
1461 template<typename Value_t>
1462 const char* FunctionParserBase<Value_t>::CompileIf(const char* function)
1463 {
1464     if(*function != '(') return SetErrorType(EXPECT_PARENTH_FUNC, function);
1465
1466     function = CompileExpression(function+1);
1467     if(!function) return 0;
1468     if(*function != ',')
1469         return SetErrorType(noCommaError<Value_t>(*function), function);
1470
1471     OPCODE opcode = cIf;
1472     if(mData->mByteCode.back() == cNotNot) mData->mByteCode.pop_back();
1473     if(IsNeverNegativeValueOpcode(mData->mByteCode.back()))
1474     {
1475         // If we know that the condition to be tested is always
1476         // a positive value (such as when produced by "x<y"),
1477         // we can use the faster opcode to evaluate it.
1478         // cIf tests whether fabs(cond) >= 0.5,
1479         // cAbsIf simply tests whether cond >= 0.5.
1480         opcode = cAbsIf;
1481     }
1482
1483     mData->mByteCode.push_back(opcode);
1484     const unsigned curByteCodeSize = unsigned(mData->mByteCode.size());
1485     PushOpcodeParam<false>(0); // Jump index; to be set later
1486     PushOpcodeParam<true> (0); // Immed jump index; to be set later
1487
1488     --mStackPtr;
1489
1490     function = CompileExpression(function + 1);
1491     if(!function) return 0;
1492     if(*function != ',')
1493         return SetErrorType(noCommaError<Value_t>(*function), function);
1494
1495     mData->mByteCode.push_back(cJump);
1496     const unsigned curByteCodeSize2 = unsigned(mData->mByteCode.size());
1497     const unsigned curImmedSize2 = unsigned(mData->mImmed.size());
1498     PushOpcodeParam<false>(0); // Jump index; to be set later
1499     PushOpcodeParam<true> (0); // Immed jump index; to be set later
1500
1501     --mStackPtr;
1502
1503     function = CompileExpression(function + 1);
1504     if(!function) return 0;
1505     if(*function != ')')
1506         return SetErrorType(noParenthError<Value_t>(*function), function);
1507
1508     PutOpcodeParamAt<true> ( mData->mByteCode.back(), unsigned(mData->mByteCode.size()-1) );
1509     // ^Necessary for guarding against if(x,1,2)+1 being changed
1510     //  into if(x,1,3) by fp_opcode_add.inc
1511
1512     // Set jump indices
1513     PutOpcodeParamAt<false>( curByteCodeSize2+1, curByteCodeSize );
1514     PutOpcodeParamAt<false>( curImmedSize2,      curByteCodeSize+1 );
1515     PutOpcodeParamAt<false>( unsigned(mData->mByteCode.size())-1, curByteCodeSize2);
1516     PutOpcodeParamAt<false>( unsigned(mData->mImmed.size()),      curByteCodeSize2+1);
1517
1518     ++function;
1519     SkipSpace(function);
1520     return function;
1521 }
1522
1523 template<typename Value_t>
1524 const char* FunctionParserBase<Value_t>::CompileFunctionParams
1525 (const char* function, unsigned requiredParams)
1526 {
1527     if(*function != '(') return SetErrorType(EXPECT_PARENTH_FUNC, function);
1528
1529     if(requiredParams > 0)
1530     {
1531         const char* function_end = CompileExpression(function+1);
1532         if(!function_end)
1533         {
1534             // If an error occurred, verify whether it was caused by ()
1535             ++function;
1536             SkipSpace(function);
1537             if(*function == ')')
1538                 return SetErrorType(ILL_PARAMS_AMOUNT, function);
1539             // Not caused by (), use the error message given by CompileExpression()
1540             return 0;
1541         }
1542         function = function_end;
1543
1544         for(unsigned i = 1; i < requiredParams; ++i)
1545         {
1546             if(*function != ',')
1547                 return SetErrorType(noCommaError<Value_t>(*function), function);
1548
1549             function = CompileExpression(function+1);
1550             if(!function) return 0;
1551         }
1552         // No need for incStackPtr() because each parse parameter calls it
1553         mStackPtr -= requiredParams-1;
1554     }
1555     else
1556     {
1557         incStackPtr(); // return value of function is pushed onto the stack
1558         ++function;
1559         SkipSpace(function);
1560     }
1561
1562     if(*function != ')')
1563         return SetErrorType(noParenthError<Value_t>(*function), function);
1564     ++function;
1565     SkipSpace(function);
1566     return function;
1567 }
1568
1569 template<typename Value_t>
1570 const char* FunctionParserBase<Value_t>::CompileElement(const char* function)
1571 {
1572     if(BeginsLiteral<Value_t>( (unsigned char) *function))
1573         return CompileLiteral(function);
1574
1575     unsigned nameLength = readIdentifier<Value_t>(function);
1576     if(nameLength == 0)
1577     {
1578         // No identifier found
1579         if(*function == '(') return CompileParenthesis(function);
1580         if(*function == ')') return SetErrorType(MISM_PARENTH, function);
1581         return SetErrorType(SYNTAX_ERROR, function);
1582     }
1583
1584     // Function, variable or constant
1585     if(nameLength & 0x80000000U) // Function
1586     {
1587         OPCODE func_opcode = OPCODE( (nameLength >> 16) & 0x7FFF );
1588         return CompileFunction(function + (nameLength & 0xFFFF), func_opcode);
1589     }
1590
1591     NamePtr name(function, nameLength);
1592     const char* endPtr = function + nameLength;
1593     SkipSpace(endPtr);
1594
1595     typename NamePtrsMap<Value_t>::iterator nameIter =
1596         mData->mNamePtrs.find(name);
1597     if(nameIter == mData->mNamePtrs.end())
1598     {
1599         // Check if it's an inline variable:
1600         for(typename Data::InlineVarNamesContainer::reverse_iterator iter =
1601                 mData->mInlineVarNames.rbegin();
1602             iter != mData->mInlineVarNames.rend();
1603             ++iter)
1604         {
1605             if(name == iter->mName)
1606             {
1607                 if( iter->mFetchIndex+1 == mStackPtr)
1608                 {
1609                     mData->mByteCode.push_back(cDup);
1610                 }
1611                 else
1612                 {
1613                     mData->mByteCode.push_back(cFetch);
1614                     PushOpcodeParam<true>(iter->mFetchIndex);
1615                 }
1616                 incStackPtr();
1617                 return endPtr;
1618             }
1619         }
1620
1621         return SetErrorType(UNKNOWN_IDENTIFIER, function);
1622     }
1623
1624     const NameData<Value_t>* nameData = &nameIter->second;
1625     switch(nameData->type)
1626     {
1627       case NameData<Value_t>::VARIABLE: // is variable
1628           if(unlikely(!mData->mByteCode.empty() &&
1629                       mData->mByteCode.back() == nameData->index))
1630               mData->mByteCode.push_back(cDup);
1631           else
1632               mData->mByteCode.push_back(nameData->index);
1633           incStackPtr();
1634           return endPtr;
1635
1636       case NameData<Value_t>::CONSTANT: // is constant
1637           AddImmedOpcode(nameData->value);
1638           incStackPtr();
1639           return endPtr;
1640
1641       case NameData<Value_t>::UNIT: // is unit (error if appears here)
1642           break;
1643
1644       case NameData<Value_t>::FUNC_PTR: // is C++ function
1645           function = CompileFunctionParams
1646               (endPtr, mData->mFuncPtrs[nameData->index].mParams);
1647           //if(!function) return 0;
1648           mData->mByteCode.push_back(cFCall);
1649           PushOpcodeParam<true>(nameData->index);
1650           return function;
1651
1652       case NameData<Value_t>::PARSER_PTR: // is FunctionParser
1653           function = CompileFunctionParams
1654               (endPtr, mData->mFuncParsers[nameData->index].mParams);
1655           //if(!function) return 0;
1656           mData->mByteCode.push_back(cPCall);
1657           PushOpcodeParam<true>(nameData->index);
1658           return function;
1659     }
1660
1661     // When it's an unit (or unrecognized type):
1662     return SetErrorType(SYNTAX_ERROR, function);
1663 }
1664
1665 template<typename Value_t>
1666 inline const char* FunctionParserBase<Value_t>::CompileFunction
1667 (const char* function, unsigned func_opcode)
1668 {
1669     SkipSpace(function);
1670     const FuncDefinition& funcDef = Functions[func_opcode];
1671
1672     if(func_opcode == cIf) // "if" is a special case
1673         return CompileIf(function);
1674
1675     unsigned requiredParams = funcDef.params;
1676 #ifndef FP_DISABLE_EVAL
1677     if(func_opcode == cEval)
1678         requiredParams = mData->mVariablesAmount;
1679 #endif
1680
1681     function = CompileFunctionParams(function, requiredParams);
1682     if(!function) return 0;
1683
1684     if(mUseDegreeConversion)
1685     {
1686         if(funcDef.flags & FuncDefinition::AngleIn)
1687             AddFunctionOpcode(cRad);
1688
1689         AddFunctionOpcode(func_opcode);
1690
1691         if(funcDef.flags & FuncDefinition::AngleOut)
1692             AddFunctionOpcode(cDeg);
1693     }
1694     else
1695     {
1696         AddFunctionOpcode(func_opcode);
1697     }
1698     return function;
1699 }
1700
1701 template<typename Value_t>
1702 inline const char*
1703 FunctionParserBase<Value_t>::CompileParenthesis(const char* function)
1704 {
1705     ++function; // Skip '('
1706
1707     SkipSpace(function);
1708     if(*function == ')') return SetErrorType(EMPTY_PARENTH, function);
1709     function = CompileExpression(function);
1710     if(!function) return 0;
1711
1712     if(*function != ')') return SetErrorType(MISSING_PARENTH, function);
1713     ++function; // Skip ')'
1714
1715     SkipSpace(function);
1716     return function;
1717 }
1718
1719 template<typename Value_t>
1720 const char*
1721 FunctionParserBase<Value_t>::CompilePossibleUnit(const char* function)
1722 {
1723     unsigned nameLength = readIdentifier<Value_t>(function);
1724     if(nameLength & 0x80000000U) return function; // built-in function name
1725     if(nameLength != 0)
1726     {
1727         NamePtr name(function, nameLength);
1728
1729         typename NamePtrsMap<Value_t>::iterator nameIter =
1730             mData->mNamePtrs.find(name);
1731         if(nameIter != mData->mNamePtrs.end())
1732         {
1733             const NameData<Value_t>* nameData = &nameIter->second;
1734             if(nameData->type == NameData<Value_t>::UNIT)
1735             {
1736                 AddImmedOpcode(nameData->value);
1737                 incStackPtr();
1738                 AddFunctionOpcode(cMul);
1739                 --mStackPtr;
1740
1741                 const char* endPtr = function + nameLength;
1742                 SkipSpace(endPtr);
1743                 return endPtr;
1744             }
1745         }
1746     }
1747
1748     return function;
1749 }
1750
1751 template<typename Value_t>
1752 inline const char*
1753 FunctionParserBase<Value_t>::CompilePow(const char* function)
1754 {
1755     function = CompileElement(function);
1756     if(!function) return 0;
1757     function = CompilePossibleUnit(function);
1758
1759     if(*function == '^')
1760     {
1761         ++function;
1762         SkipSpace(function);
1763
1764         unsigned op = cPow;
1765         if(mData->mByteCode.back() == cImmed)
1766         {
1767             if(mData->mImmed.back() == fp_const_e<Value_t>())
1768                 { op = cExp;  mData->mByteCode.pop_back();
1769                     mData->mImmed.pop_back(); --mStackPtr; }
1770             else if(mData->mImmed.back() == Value_t(2))
1771                 { op = cExp2; mData->mByteCode.pop_back();
1772                     mData->mImmed.pop_back(); --mStackPtr; }
1773         }
1774
1775         function = CompileUnaryMinus(function);
1776         if(!function) return 0;
1777
1778         // add opcode
1779         AddFunctionOpcode(op);
1780
1781         if(op == cPow) --mStackPtr;
1782     }
1783     return function;
1784 }
1785
1786 /* Currently the power operator is skipped for integral types because its
1787    usefulness with them is questionable, and in the case of GmpIng, for safety
1788    reasons.
1789    - With long int almost any power, except for very small ones, would
1790      overflow the result, so the usefulness of this is rather questionable.
1791    - With GmpInt the power operator could be easily abused to make the program
1792      run out of memory (think of a function like "10^10^10^10^1000000").
1793 */
1794 #ifdef FP_SUPPORT_LONG_INT_TYPE
1795 template<>
1796 inline const char*
1797 FunctionParserBase<long>::CompilePow(const char* function)
1798 {
1799     function = CompileElement(function);
1800     if(!function) return 0;
1801     return CompilePossibleUnit(function);
1802 }
1803 #endif
1804
1805 #ifdef FP_SUPPORT_GMP_INT_TYPE
1806 template<>
1807 inline const char*
1808 FunctionParserBase<GmpInt>::CompilePow(const char* function)
1809 {
1810     function = CompileElement(function);
1811     if(!function) return 0;
1812     return CompilePossibleUnit(function);
1813 }
1814 #endif
1815
1816 template<typename Value_t>
1817 inline const char*
1818 FunctionParserBase<Value_t>::CompileUnaryMinus(const char* function)
1819 {
1820     char op = *function;
1821     switch(op)
1822     {
1823         case '-':
1824         case '!':
1825             ++function;
1826             SkipSpace(function);
1827
1828             function = CompileUnaryMinus(function);
1829             if(!function) return 0;
1830
1831             AddFunctionOpcode(op=='-' ? cNeg : cNot);
1832
1833             return function;
1834         default: break;
1835     }
1836     return CompilePow(function);
1837 }
1838
1839 template<typename Value_t>
1840 inline const char*
1841 FunctionParserBase<Value_t>::CompileMult(const char* function)
1842 {
1843     function = CompileUnaryMinus(function);
1844     if(!function) return 0;
1845
1846     Value_t pending_immed(1);
1847     #define FP_FlushImmed(do_reset) \
1848         if(pending_immed != Value_t(1)) \
1849         { \
1850             unsigned op = cMul; \
1851             if(!IsIntType<Value_t>::result && mData->mByteCode.back() == cInv) \
1852             { \
1853                 /* (...) cInv 5 cMul -> (...) 5 cRDiv */ \
1854                 /*           ^               ^      | */ \
1855                 mData->mByteCode.pop_back(); \
1856                 op = cRDiv; \
1857             } \
1858             AddImmedOpcode(pending_immed); \
1859             incStackPtr(); \
1860             AddFunctionOpcode(op); \
1861             --mStackPtr; \
1862             if(do_reset) pending_immed = Value_t(1); \
1863         }
1864     while(true)
1865     {
1866         char c = *function;
1867         if(c == '%')
1868         {
1869             FP_FlushImmed(true);
1870             ++function;
1871             SkipSpace(function);
1872             function = CompileUnaryMinus(function);
1873             if(!function) return 0;
1874             AddFunctionOpcode(cMod);
1875             --mStackPtr;
1876             continue;
1877         }
1878         if(c != '*' && c != '/') break;
1879
1880         bool safe_cumulation = (c == '*' || !IsIntType<Value_t>::result);
1881         if(!safe_cumulation)
1882         {
1883             FP_FlushImmed(true);
1884         }
1885
1886         ++function;
1887         SkipSpace(function);
1888         if(mData->mByteCode.back() == cImmed
1889         && (safe_cumulation
1890          || mData->mImmed.back() == Value_t(1)))
1891         {
1892             // 5 (...) cMul --> (...)      ||| 5 cMul
1893             // 5 (...) cDiv --> (...) cInv ||| 5 cMul
1894             //  ^          |              ^
1895             pending_immed *= mData->mImmed.back();
1896             mData->mImmed.pop_back();
1897             mData->mByteCode.pop_back();
1898             --mStackPtr;
1899             function = CompileUnaryMinus(function);
1900             if(!function) return 0;
1901             if(c == '/')
1902                 AddFunctionOpcode(cInv);
1903             continue;
1904         }
1905         if(safe_cumulation
1906         && mData->mByteCode.back() == cMul
1907         && mData->mByteCode[mData->mByteCode.size()-2] == cImmed)
1908         {
1909             // (:::) 5 cMul (...) cMul -> (:::) (...) cMul  ||| 5 cMul
1910             // (:::) 5 cMul (...) cDiv -> (:::) (...) cDiv  ||| 5 cMul
1911             //             ^                   ^
1912             pending_immed *= mData->mImmed.back();
1913             mData->mImmed.pop_back();
1914             mData->mByteCode.pop_back();
1915             mData->mByteCode.pop_back();
1916         }
1917         // cDiv is not tested here because the bytecode
1918         // optimizer will convert this kind of cDivs into cMuls.
1919         bool lhs_inverted = false;
1920         if(!IsIntType<Value_t>::result && c == '*'
1921         && mData->mByteCode.back() == cInv)
1922         {
1923             // (:::) cInv (...) cMul -> (:::) (...) cRDiv
1924             // (:::) cInv (...) cDiv -> (:::) (...) cMul cInv
1925             //           ^                   ^            |
1926             mData->mByteCode.pop_back();
1927             lhs_inverted = true;
1928         }
1929         function = CompileUnaryMinus(function);
1930         if(!function) return 0;
1931         if(safe_cumulation
1932         && mData->mByteCode.back() == cMul
1933         && mData->mByteCode[mData->mByteCode.size()-2] == cImmed)
1934         {
1935             // (:::) (...) 5 cMul cMul -> (:::) (...) cMul  |||  5 Mul
1936             // (:::) (...) 5 cMul cDiv -> (:::) (...) cDiv  ||| /5 Mul
1937             //                   ^                        ^
1938             if(c == '*')
1939                 pending_immed *= mData->mImmed.back();
1940             else
1941                 pending_immed /= mData->mImmed.back();
1942             mData->mImmed.pop_back();
1943             mData->mByteCode.pop_back();
1944             mData->mByteCode.pop_back();
1945         }
1946         else
1947         if(safe_cumulation
1948         && mData->mByteCode.back() == cRDiv
1949         && mData->mByteCode[mData->mByteCode.size()-2] == cImmed)
1950         {
1951             // (:::) (...) 5 cRDiv cMul -> (:::) (...) cDiv  |||  5 cMul
1952             // (:::) (...) 5 cRDiv cDiv -> (:::) (...) cMul  ||| /5 cMul
1953             //                    ^                   ^
1954             if(c == '*')
1955                 { c = '/'; pending_immed *= mData->mImmed.back(); }
1956             else
1957                 { c = '*'; pending_immed /= mData->mImmed.back(); }
1958             mData->mImmed.pop_back();
1959             mData->mByteCode.pop_back();
1960             mData->mByteCode.pop_back();
1961         }
1962         if(!lhs_inverted) // if (/x/y) was changed to /(x*y), add missing cInv
1963         {
1964             AddFunctionOpcode(c == '*' ? cMul : cDiv);
1965             --mStackPtr;
1966         }
1967         else if(c == '*') // (/x)*y -> rdiv(x,y)
1968         {
1969             AddFunctionOpcode(cRDiv);
1970             --mStackPtr;
1971         }
1972         else // (/x)/y -> /(x*y)
1973         {
1974             AddFunctionOpcode(cMul);
1975             --mStackPtr;
1976             AddFunctionOpcode(cInv);
1977         }
1978     }
1979     FP_FlushImmed(false);
1980     #undef FP_FlushImmed
1981     return function;
1982 }
1983
1984 template<typename Value_t>
1985 inline const char*
1986 FunctionParserBase<Value_t>::CompileAddition(const char* function)
1987 {
1988     function = CompileMult(function);
1989     if(!function) return 0;
1990
1991     Value_t pending_immed(0);
1992     #define FP_FlushImmed(do_reset) \
1993         if(pending_immed != Value_t(0)) \
1994         { \
1995             unsigned op = cAdd; \
1996             if(mData->mByteCode.back() == cNeg) \
1997             { \
1998                 /* (...) cNeg 5 cAdd -> (...) 5 cRSub */ \
1999                 /*           ^               ^      | */ \
2000                 mData->mByteCode.pop_back(); \
2001                 op = cRSub; \
2002             } \
2003             AddImmedOpcode(pending_immed); \
2004             incStackPtr(); \
2005             AddFunctionOpcode(op); \
2006             --mStackPtr; \
2007             if(do_reset) pending_immed = Value_t(0); \
2008         }
2009     while(true)
2010     {
2011         char c = *function;
2012         if(c != '+' && c != '-') break;
2013         ++function;
2014         SkipSpace(function);
2015         if(mData->mByteCode.back() == cImmed)
2016         {
2017             // 5 (...) cAdd --> (...)      ||| 5 cAdd
2018             // 5 (...) cSub --> (...) cNeg ||| 5 cAdd
2019             //  ^          |              ^
2020             pending_immed += mData->mImmed.back();
2021             mData->mImmed.pop_back();
2022             mData->mByteCode.pop_back();
2023             --mStackPtr;
2024             function = CompileMult(function);
2025             if(!function) return 0;
2026             if(c == '-')
2027                 AddFunctionOpcode(cNeg);
2028             continue;
2029         }
2030         if(mData->mByteCode.back() == cAdd
2031         && mData->mByteCode[mData->mByteCode.size()-2] == cImmed)
2032         {
2033             // (:::) 5 cAdd (...) cAdd -> (:::) (...) cAdd  ||| 5 cAdd
2034             // (:::) 5 cAdd (...) cSub -> (:::) (...) cSub  ||| 5 cAdd
2035             //             ^                   ^
2036             pending_immed += mData->mImmed.back();
2037             mData->mImmed.pop_back();
2038             mData->mByteCode.pop_back();
2039             mData->mByteCode.pop_back();
2040         }
2041         // cSub is not tested here because the bytecode
2042         // optimizer will convert this kind of cSubs into cAdds.
2043         bool lhs_negated = false;
2044         if(mData->mByteCode.back() == cNeg)
2045         {
2046             // (:::) cNeg (...) cAdd -> (:::) (...) cRSub
2047             // (:::) cNeg (...) cSub -> (:::) (...) cAdd cNeg
2048             //           ^                   ^            |
2049             mData->mByteCode.pop_back();
2050             lhs_negated = true;
2051         }
2052         function = CompileMult(function);
2053         if(!function) return 0;
2054         if(mData->mByteCode.back() == cAdd
2055         && mData->mByteCode[mData->mByteCode.size()-2] == cImmed)
2056         {
2057             // (:::) (...) 5 cAdd cAdd -> (:::) (...) cAdd  |||  5 Add
2058             // (:::) (...) 5 cAdd cSub -> (:::) (...) cSub  ||| -5 Add
2059             //                   ^                        ^
2060             if(c == '+')
2061                 pending_immed += mData->mImmed.back();
2062             else
2063                 pending_immed -= mData->mImmed.back();
2064             mData->mImmed.pop_back();
2065             mData->mByteCode.pop_back();
2066             mData->mByteCode.pop_back();
2067         }
2068         else
2069         if(mData->mByteCode.back() == cRSub
2070         && mData->mByteCode[mData->mByteCode.size()-2] == cImmed)
2071         {
2072             // (:::) (...) 5 cRSub cAdd -> (:::) (...) cSub  |||  5 cAdd
2073             // (:::) (...) 5 cRSub cSub -> (:::) (...) cAdd  ||| -5 cAdd
2074             //                    ^                   ^
2075             if(c == '+')
2076                 { c = '-'; pending_immed += mData->mImmed.back(); }
2077             else
2078                 { c = '+'; pending_immed -= mData->mImmed.back(); }
2079             mData->mImmed.pop_back();
2080             mData->mByteCode.pop_back();
2081             mData->mByteCode.pop_back();
2082         }
2083         if(!lhs_negated) // if (-x-y) was changed to -(x+y), add missing cNeg
2084         {
2085             AddFunctionOpcode(c == '+' ? cAdd : cSub);
2086             --mStackPtr;
2087         }
2088         else if(c == '+') // (-x)+y -> rsub(x,y)
2089         {
2090             AddFunctionOpcode(cRSub);
2091             --mStackPtr;
2092         }
2093         else // (-x)-y -> -(x+y)
2094         {
2095             AddFunctionOpcode(cAdd);
2096             --mStackPtr;
2097             AddFunctionOpcode(cNeg);
2098         }
2099     }
2100     FP_FlushImmed(false);
2101     #undef FP_FlushImmed
2102     return function;
2103 }
2104
2105 template<typename Value_t>
2106 inline const char*
2107 FunctionParserBase<Value_t>::CompileComparison(const char* function)
2108 {
2109     unsigned op=0;
2110     while(true)
2111     {
2112         function = CompileAddition(function);
2113         if(!function) return 0;
2114
2115         if(op)
2116         {
2117             AddFunctionOpcode(op);
2118             --mStackPtr;
2119         }
2120         switch(*function)
2121         {
2122           case '=':
2123               ++function; op = cEqual; break;
2124           case '!':
2125               if(function[1] == '=')
2126               { function += 2; op = cNEqual; break; }
2127               // If '=' does not follow '!', a syntax error will
2128               // be generated at the outermost parsing level
2129               return function;
2130           case '<':
2131               if(function[1] == '=')
2132               { function += 2; op = cLessOrEq; break; }
2133               ++function; op = cLess; break;
2134           case '>':
2135               if(function[1] == '=')
2136               { function += 2; op = cGreaterOrEq; break; }
2137               ++function; op = cGreater; break;
2138           default: return function;
2139         }
2140         SkipSpace(function);
2141     }
2142     return function;
2143 }
2144
2145 template<typename Value_t>
2146 inline const char* FunctionParserBase<Value_t>::CompileAnd(const char* function)
2147 {
2148     size_t param0end=0;
2149     while(true)
2150     {
2151         function = CompileComparison(function);
2152         if(!function) return 0;
2153
2154         if(param0end)
2155         {
2156             if(mData->mByteCode.back() == cNotNot) mData->mByteCode.pop_back();
2157
2158             AddFunctionOpcode(cAnd);
2159             --mStackPtr;
2160         }
2161         if(*function != '&') break;
2162         ++function;
2163         SkipSpace(function);
2164         param0end = mData->mByteCode.size();
2165     }
2166     return function;
2167 }
2168
2169 template<typename Value_t>
2170 const char* FunctionParserBase<Value_t>::CompileExpression(const char* function)
2171 {
2172     size_t param0end=0;
2173     while(true)
2174     {
2175         SkipSpace(function);
2176         function = CompileAnd(function);
2177         if(!function) return 0;
2178
2179         if(param0end)
2180         {
2181             if(mData->mByteCode.back() == cNotNot) mData->mByteCode.pop_back();
2182
2183             AddFunctionOpcode(cOr);
2184             --mStackPtr;
2185         }
2186         if(*function != '|') break;
2187         ++function;
2188         param0end = mData->mByteCode.size();
2189     }
2190     return function;
2191 }
2192
2193 template<typename Value_t>
2194 const char* FunctionParserBase<Value_t>::Compile(const char* function)
2195 {
2196     while(true)
2197     {
2198         // Check if an identifier appears as first token:
2199         SkipSpace(function);
2200         unsigned nameLength = readIdentifier<Value_t>(function);
2201         if(nameLength > 0 && !(nameLength & 0x80000000U))
2202         {
2203             typename Data::InlineVariable inlineVar =
2204                 { NamePtr(function, nameLength), 0 };
2205
2206             // Check if it's an unknown identifier:
2207             typename NamePtrsMap<Value_t>::iterator nameIter =
2208                 mData->mNamePtrs.find(inlineVar.mName);
2209             if(nameIter == mData->mNamePtrs.end())
2210             {
2211                 const char* function2 = function + nameLength;
2212                 SkipSpace(function2);
2213
2214                 // Check if ":=" follows the unknown identifier:
2215                 if(function2[0] == ':' && function2[1] == '=')
2216                 {
2217                     // Parse the expression that follows and create the
2218                     // inline variable:
2219                     function2 = CompileExpression(function2 + 2);
2220                     if(!function2) return 0;
2221                     if(*function2 != ';') return function2;
2222
2223                     inlineVar.mFetchIndex = mStackPtr - 1;
2224                     mData->mInlineVarNames.push_back(inlineVar);
2225
2226                     // Continue with the expression after the ';':
2227                     function = function2 + 1;
2228                     continue;
2229                 }
2230             }
2231         }
2232         break;
2233     }
2234
2235     return CompileExpression(function);
2236 }
2237
2238 template<typename Value_t> template<bool PutFlag>
2239 inline void FunctionParserBase<Value_t>::PushOpcodeParam
2240     (unsigned value)
2241 {
2242     mData->mByteCode.push_back(value | (PutFlag ? 0x80000000U : 0u));
2243     if(PutFlag) mHasByteCodeFlags = true;
2244 }
2245
2246 template<typename Value_t> template<bool PutFlag>
2247 inline void FunctionParserBase<Value_t>::PutOpcodeParamAt
2248     (unsigned value, unsigned offset)
2249 {
2250     mData->mByteCode[offset] = value | (PutFlag ? 0x80000000U : 0u);
2251     if(PutFlag) mHasByteCodeFlags = true;
2252 }
2253
2254 //===========================================================================
2255 // Function evaluation
2256 //===========================================================================
2257 template<typename Value_t>
2258 Value_t FunctionParserBase<Value_t>::Eval(const Value_t* Vars)
2259 {
2260     if(mParseErrorType != FP_NO_ERROR) return Value_t(0);
2261
2262     const unsigned* const byteCode = &(mData->mByteCode[0]);
2263     const Value_t* const immed = mData->mImmed.empty() ? 0 : &(mData->mImmed[0]);
2264     const unsigned byteCodeSize = unsigned(mData->mByteCode.size());
2265     unsigned IP, DP=0;
2266     int SP=-1;
2267
2268 #ifdef FP_USE_THREAD_SAFE_EVAL
2269     /* If Eval() may be called by multiple threads simultaneously,
2270      * then Eval() must allocate its own stack.
2271      */
2272 #ifdef FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA
2273     /* alloca() allocates room from the hardware stack.
2274      * It is automatically freed when the function returns.
2275      */
2276     Value_t* const Stack = (Value_t*)alloca(mData->mStackSize*sizeof(Value_t));
2277 #else
2278     /* Allocate from the heap. Ensure that it is freed
2279      * automatically no matter which exit path is taken.
2280      */
2281     struct AutoDealloc
2282     {
2283         Value_t* ptr;
2284         ~AutoDealloc() { delete[] ptr; }
2285     } AutoDeallocStack = { new Value_t[mData->mStackSize] };
2286     Value_t*& Stack = AutoDeallocStack.ptr;
2287 #endif
2288 #else
2289     /* No thread safety, so use a global stack. */
2290     std::vector<Value_t>& Stack = mData->mStack;
2291 #endif
2292
2293     for(IP=0; IP<byteCodeSize; ++IP)
2294     {
2295         switch(byteCode[IP])
2296         {
2297 // Functions:
2298           case   cAbs: Stack[SP] = fp_abs(Stack[SP]); break;
2299
2300           case  cAcos:
2301 #           ifndef FP_NO_EVALUATION_CHECKS
2302               if(Stack[SP] < Value_t(-1) || Stack[SP] > Value_t(1))
2303               { mEvalErrorType=4; return Value_t(0); }
2304 #           endif
2305               Stack[SP] = fp_acos(Stack[SP]); break;
2306
2307           case cAcosh:
2308 #           ifndef FP_NO_EVALUATION_CHECKS
2309               if(Stack[SP] < Value_t(1))
2310               { mEvalErrorType=4; return Value_t(0); }
2311 #           endif
2312               Stack[SP] = fp_acosh(Stack[SP]); break;
2313
2314           case  cAsin:
2315 #           ifndef FP_NO_EVALUATION_CHECKS
2316               if(Stack[SP] < Value_t(-1) || Stack[SP] > Value_t(1))
2317               { mEvalErrorType=4; return Value_t(0); }
2318 #           endif
2319               Stack[SP] = fp_asin(Stack[SP]); break;
2320
2321           case cAsinh: Stack[SP] = fp_asinh(Stack[SP]); break;
2322
2323           case  cAtan: Stack[SP] = fp_atan(Stack[SP]); break;
2324
2325           case cAtan2: Stack[SP-1] = fp_atan2(Stack[SP-1], Stack[SP]);
2326                        --SP; break;
2327
2328           case cAtanh:
2329 #           ifndef FP_NO_EVALUATION_CHECKS
2330               if(Stack[SP] <= Value_t(-1) || Stack[SP] >= Value_t(1))
2331               { mEvalErrorType=4; return Value_t(0); }
2332 #           endif
2333               Stack[SP] = fp_atanh(Stack[SP]); break;
2334
2335           case  cCbrt: Stack[SP] = fp_cbrt(Stack[SP]); break;
2336
2337           case  cCeil: Stack[SP] = fp_ceil(Stack[SP]); break;
2338
2339           case   cCos: Stack[SP] = fp_cos(Stack[SP]); break;
2340
2341           case  cCosh: Stack[SP] = fp_cosh(Stack[SP]); break;
2342
2343           case   cCot:
2344               {
2345                   const Value_t t = fp_tan(Stack[SP]);
2346 #               ifndef FP_NO_EVALUATION_CHECKS
2347                   if(t == Value_t(0)) { mEvalErrorType=1; return Value_t(0); }
2348 #               endif
2349                   Stack[SP] = Value_t(1)/t; break;
2350               }
2351
2352           case   cCsc:
2353               {
2354                   const Value_t s = fp_sin(Stack[SP]);
2355 #               ifndef FP_NO_EVALUATION_CHECKS
2356                   if(s == 0) { mEvalErrorType=1; return Value_t(0); }
2357 #               endif
2358                   Stack[SP] = Value_t(1)/s; break;
2359               }
2360
2361
2362 #       ifndef FP_DISABLE_EVAL
2363           case  cEval:
2364               {
2365                   const unsigned varAmount = mData->mVariablesAmount;
2366                   Value_t retVal = Value_t(0);
2367                   if(mEvalRecursionLevel == FP_EVAL_MAX_REC_LEVEL)
2368                   {
2369                       mEvalErrorType = 5;
2370                   }
2371                   else
2372                   {
2373                       ++mEvalRecursionLevel;
2374 #                   ifndef FP_USE_THREAD_SAFE_EVAL
2375                       /* Eval() will use mData->mStack for its storage.
2376                        * Swap the current stack with an empty one.
2377                        * This is the not-thread-safe method.
2378                        */
2379                       std::vector<Value_t> tmpStack(Stack.size());
2380                       mData->mStack.swap(tmpStack);
2381                       retVal = Eval(&tmpStack[SP - varAmount + 1]);
2382                       mData->mStack.swap(tmpStack);
2383 #                   else
2384                       /* Thread safety mode. We don't need to
2385                        * worry about stack reusing here, because
2386                        * each instance of Eval() will allocate
2387                        * their own stack.
2388                        */
2389                       retVal = Eval(&Stack[SP - varAmount + 1]);
2390 #                   endif
2391                       --mEvalRecursionLevel;
2392                   }
2393                   SP -= varAmount-1;
2394                   Stack[SP] = retVal;
2395                   break;
2396               }
2397 #       endif
2398
2399           case   cExp: Stack[SP] = fp_exp(Stack[SP]); break;
2400
2401           case   cExp2: Stack[SP] = fp_exp2(Stack[SP]); break;
2402
2403           case cFloor: Stack[SP] = fp_floor(Stack[SP]); break;
2404
2405           case cHypot:
2406               Stack[SP-1] = fp_hypot(Stack[SP-1], Stack[SP]);
2407               --SP; break;
2408
2409           case    cIf:
2410                   if(fp_truth(Stack[SP--]))
2411                       IP += 2;
2412                   else
2413                   {
2414                       const unsigned* buf = &byteCode[IP+1];
2415                       IP = buf[0];
2416                       DP = buf[1];
2417                   }
2418                   break;
2419
2420           case   cInt: Stack[SP] = fp_int(Stack[SP]); break;
2421
2422           case   cLog:
2423 #           ifndef FP_NO_EVALUATION_CHECKS
2424               if(!(Stack[SP] > Value_t(0)))
2425               { mEvalErrorType=3; return Value_t(0); }
2426 #           endif
2427               Stack[SP] = fp_log(Stack[SP]); break;
2428
2429           case cLog10:
2430 #           ifndef FP_NO_EVALUATION_CHECKS
2431               if(!(Stack[SP] > Value_t(0)))
2432               { mEvalErrorType=3; return Value_t(0); }
2433 #           endif
2434               Stack[SP] = fp_log10(Stack[SP]);
2435               break;
2436
2437           case  cLog2:
2438 #           ifndef FP_NO_EVALUATION_CHECKS
2439               if(!(Stack[SP] > Value_t(0)))
2440               { mEvalErrorType=3; return Value_t(0); }
2441 #           endif
2442               Stack[SP] = fp_log2(Stack[SP]);
2443               break;
2444
2445           case   cMax: Stack[SP-1] = fp_max(Stack[SP-1], Stack[SP]);
2446                        --SP; break;
2447
2448           case   cMin: Stack[SP-1] = fp_min(Stack[SP-1], Stack[SP]);
2449                        --SP; break;
2450
2451           case   cPow:
2452 #           ifndef FP_NO_EVALUATION_CHECKS
2453               // x:Negative ^ y:NonInteger is failure,
2454               // except when the reciprocal of y forms an integer
2455               /*if(Stack[SP-1] < Value_t(0) &&
2456                  !isInteger(Stack[SP]) &&
2457                  !isInteger(1.0 / Stack[SP]))
2458               { mEvalErrorType=3; return Value_t(0); }*/
2459               // x:0 ^ y:negative is failure
2460               if(Stack[SP-1] == Value_t(0) &&
2461                  Stack[SP] < Value_t(0))
2462               { mEvalErrorType=3; return Value_t(0); }
2463 #           endif
2464               Stack[SP-1] = fp_pow(Stack[SP-1], Stack[SP]);
2465               --SP; break;
2466
2467           case  cTrunc: Stack[SP] = fp_trunc(Stack[SP]); break;
2468
2469           case   cSec:
2470               {
2471                   const Value_t c = fp_cos(Stack[SP]);
2472 #               ifndef FP_NO_EVALUATION_CHECKS
2473                   if(c == Value_t(0)) { mEvalErrorType=1; return Value_t(0); }
2474 #               endif
2475                   Stack[SP] = Value_t(1)/c; break;
2476               }
2477
2478           case   cSin: Stack[SP] = fp_sin(Stack[SP]); break;
2479
2480           case  cSinh: Stack[SP] = fp_sinh(Stack[SP]); break;
2481
2482           case  cSqrt:
2483 #           ifndef FP_NO_EVALUATION_CHECKS
2484               if(Stack[SP] < Value_t(0)) { mEvalErrorType=2; return Value_t(0); }
2485 #           endif
2486               Stack[SP] = fp_sqrt(Stack[SP]); break;
2487
2488           case   cTan: Stack[SP] = fp_tan(Stack[SP]); break;
2489
2490           case  cTanh: Stack[SP] = fp_tanh(Stack[SP]); break;
2491
2492
2493 // Misc:
2494           case cImmed: Stack[++SP] = immed[DP++]; break;
2495
2496           case  cJump:
2497               {
2498                   const unsigned* buf = &byteCode[IP+1];
2499                   IP = buf[0];
2500                   DP = buf[1];
2501                   break;
2502               }
2503
2504 // Operators:
2505           case   cNeg: Stack[SP] = -Stack[SP]; break;
2506           case   cAdd: Stack[SP-1] += Stack[SP]; --SP; break;
2507           case   cSub: Stack[SP-1] -= Stack[SP]; --SP; break;
2508           case   cMul: Stack[SP-1] *= Stack[SP]; --SP; break;
2509
2510           case   cDiv:
2511 #           ifndef FP_NO_EVALUATION_CHECKS
2512               if(Stack[SP] == Value_t(0))
2513               { mEvalErrorType=1; return Value_t(0); }
2514 #           else
2515               if(IsIntType<Value_t>::result && Stack[SP] == Value_t(0))
2516               { mEvalErrorType=1; return Value_t(0); }
2517 #           endif
2518               Stack[SP-1] /= Stack[SP]; --SP; break;
2519
2520           case   cMod:
2521               if(Stack[SP] == Value_t(0))
2522               { mEvalErrorType=1; return Value_t(0); }
2523               Stack[SP-1] = fp_mod(Stack[SP-1], Stack[SP]);
2524               --SP; break;
2525
2526           case cEqual:
2527               Stack[SP-1] = fp_equal(Stack[SP-1], Stack[SP]);
2528               --SP; break;
2529
2530           case cNEqual:
2531               Stack[SP-1] = fp_nequal(Stack[SP-1], Stack[SP]);
2532               --SP; break;
2533
2534           case  cLess:
2535               Stack[SP-1] = fp_less(Stack[SP-1], Stack[SP]);
2536               --SP; break;
2537
2538           case  cLessOrEq:
2539               Stack[SP-1] = fp_lessOrEq(Stack[SP-1], Stack[SP]);
2540               --SP; break;
2541
2542           case cGreater:
2543               Stack[SP-1] = fp_less(Stack[SP], Stack[SP-1]);
2544               --SP; break;
2545
2546           case cGreaterOrEq:
2547               Stack[SP-1] = fp_lessOrEq(Stack[SP], Stack[SP-1]);
2548               --SP; break;
2549
2550           case   cNot: Stack[SP] = fp_not(Stack[SP]); break;
2551
2552           case cNotNot: Stack[SP] = fp_notNot(Stack[SP]); break;
2553
2554           case   cAnd:
2555               Stack[SP-1] = fp_and(Stack[SP-1], Stack[SP]);
2556               --SP; break;
2557
2558           case    cOr:
2559               Stack[SP-1] = fp_or(Stack[SP-1], Stack[SP]);
2560               --SP; break;
2561
2562 // Degrees-radians conversion:
2563           case   cDeg: Stack[SP] = RadiansToDegrees(Stack[SP]); break;
2564           case   cRad: Stack[SP] = DegreesToRadians(Stack[SP]); break;
2565
2566 // User-defined function calls:
2567           case cFCall:
2568               {
2569                   unsigned index = byteCode[++IP];
2570                   unsigned params = mData->mFuncPtrs[index].mParams;
2571                   Value_t retVal =
2572                       mData->mFuncPtrs[index].mFuncPtr(&Stack[SP-params+1]);
2573                   SP -= int(params)-1;
2574                   Stack[SP] = retVal;
2575                   break;
2576               }
2577
2578           case cPCall:
2579               {
2580                   unsigned index = byteCode[++IP];
2581                   unsigned params = mData->mFuncParsers[index].mParams;
2582                   Value_t retVal =
2583                       mData->mFuncParsers[index].mParserPtr->Eval
2584                       (&Stack[SP-params+1]);
2585                   SP -= int(params)-1;
2586                   Stack[SP] = retVal;
2587                   const int error =
2588                       mData->mFuncParsers[index].mParserPtr->EvalError();
2589                   if(error)
2590                   {
2591                       mEvalErrorType = error;
2592                       return 0;
2593                   }
2594                   break;
2595               }
2596
2597
2598           case   cFetch:
2599               {
2600                   unsigned stackOffs = byteCode[++IP];
2601                   Stack[SP+1] = Stack[stackOffs]; ++SP;
2602                   break;
2603               }
2604
2605 #ifdef FP_SUPPORT_OPTIMIZER
2606           case   cPopNMov:
2607               {
2608                   unsigned stackOffs_target = byteCode[++IP];
2609                   unsigned stackOffs_source = byteCode[++IP];
2610                   Stack[stackOffs_target] = Stack[stackOffs_source];
2611                   SP = stackOffs_target;
2612                   break;
2613               }
2614
2615           case  cLog2by:
2616 #           ifndef FP_NO_EVALUATION_CHECKS
2617               if(Stack[SP-1] <= Value_t(0))
2618               { mEvalErrorType=3; return Value_t(0); }
2619 #           endif
2620               Stack[SP-1] = fp_log2(Stack[SP-1]) * Stack[SP];
2621               --SP;
2622               break;
2623
2624           case cNop: break;
2625 #endif // FP_SUPPORT_OPTIMIZER
2626
2627           case cSinCos:
2628               fp_sinCos(Stack[SP], Stack[SP+1], Stack[SP]);
2629               ++SP;
2630               break;
2631
2632           case cAbsNot:
2633               Stack[SP] = fp_absNot(Stack[SP]); break;
2634           case cAbsNotNot:
2635               Stack[SP] = fp_absNotNot(Stack[SP]); break;
2636           case cAbsAnd:
2637               Stack[SP-1] = fp_absAnd(Stack[SP-1], Stack[SP]);
2638               --SP; break;
2639           case cAbsOr:
2640               Stack[SP-1] = fp_absOr(Stack[SP-1], Stack[SP]);
2641               --SP; break;
2642           case cAbsIf:
2643               if(fp_absTruth(Stack[SP--]))
2644                   IP += 2;
2645               else
2646               {
2647                   const unsigned* buf = &byteCode[IP+1];
2648                   IP = buf[0];
2649                   DP = buf[1];
2650               }
2651               break;
2652
2653           case   cDup: Stack[SP+1] = Stack[SP]; ++SP; break;
2654
2655           case   cInv:
2656 #           ifndef FP_NO_EVALUATION_CHECKS
2657               if(Stack[SP] == Value_t(0))
2658               { mEvalErrorType=1; return Value_t(0); }
2659 #           else
2660               if(IsIntType<Value_t>::result && Stack[SP] == Value_t(0))
2661               { mEvalErrorType=1; return Value_t(0); }
2662 #           endif
2663               Stack[SP] = Value_t(1)/Stack[SP];
2664               break;
2665
2666           case   cSqr:
2667               Stack[SP] = Stack[SP]*Stack[SP];
2668               break;
2669
2670           case   cRDiv:
2671 #           ifndef FP_NO_EVALUATION_CHECKS
2672               if(Stack[SP-1] == Value_t(0))
2673               { mEvalErrorType=1; return Value_t(0); }
2674 #           else
2675               if(IsIntType<Value_t>::result && Stack[SP-1] == Value_t(0))
2676               { mEvalErrorType=1; return Value_t(0); }
2677 #           endif
2678               Stack[SP-1] = Stack[SP] / Stack[SP-1]; --SP; break;
2679
2680           case   cRSub: Stack[SP-1] = Stack[SP] - Stack[SP-1]; --SP; break;
2681
2682           case   cRSqrt:
2683 #           ifndef FP_NO_EVALUATION_CHECKS
2684               if(Stack[SP] == Value_t(0))
2685               { mEvalErrorType=1; return Value_t(0); }
2686 #           endif
2687               Stack[SP] = Value_t(1) / fp_sqrt(Stack[SP]); break;
2688
2689
2690 // Variables:
2691           default:
2692               Stack[++SP] = Vars[byteCode[IP]-VarBegin];
2693         }
2694     }
2695
2696     mEvalErrorType=0;
2697     return Stack[SP];
2698 }
2699
2700
2701 //===========================================================================
2702 // Variable deduction
2703 //===========================================================================
2704 namespace
2705 {
2706     template<typename Value_t>
2707     int deduceVariables(FunctionParserBase<Value_t>& fParser,
2708                         const char* funcStr,
2709                         std::string& destVarString,
2710                         int* amountOfVariablesFound,
2711                         std::vector<std::string>* destVarNames,
2712                         bool useDegrees)
2713     {
2714         typedef std::set<std::string> StrSet;
2715         StrSet varNames;
2716
2717         int oldIndex = -1;
2718
2719         while(true)
2720         {
2721             destVarString.clear();
2722             for(StrSet::iterator iter = varNames.begin();
2723                 iter != varNames.end();
2724                 ++iter)
2725             {
2726                 if(iter != varNames.begin()) destVarString += ",";
2727                 destVarString += *iter;
2728             }
2729
2730             const int index =
2731                 fParser.Parse(funcStr, destVarString, useDegrees);
2732             if(index < 0) break;
2733             if(index == oldIndex) return index;
2734
2735             unsigned nameLength = readIdentifier<Value_t>(funcStr + index);
2736             if(nameLength & 0x80000000U) return index;
2737             if(nameLength == 0) return index;
2738
2739             varNames.insert(std::string(funcStr + index, nameLength));
2740             oldIndex = index;
2741         }
2742
2743         if(amountOfVariablesFound)
2744             *amountOfVariablesFound = int(varNames.size());
2745
2746         if(destVarNames)
2747             destVarNames->assign(varNames.begin(), varNames.end());
2748
2749         return -1;
2750     }
2751 }
2752
2753 template<typename Value_t>
2754 int FunctionParserBase<Value_t>::ParseAndDeduceVariables
2755 (const std::string& function,
2756  int* amountOfVariablesFound,
2757  bool useDegrees)
2758 {
2759     std::string varString;
2760     return deduceVariables(*this, function.c_str(), varString,
2761                            amountOfVariablesFound, 0, useDegrees);
2762 }
2763
2764 template<typename Value_t>
2765 int FunctionParserBase<Value_t>::ParseAndDeduceVariables
2766 (const std::string& function,
2767  std::string& resultVarString,
2768  int* amountOfVariablesFound,
2769  bool useDegrees)
2770 {
2771     std::string varString;
2772     const int index =
2773         deduceVariables(*this, function.c_str(), varString,
2774                         amountOfVariablesFound, 0, useDegrees);
2775     if(index < 0) resultVarString = varString;
2776     return index;
2777 }
2778
2779 template<typename Value_t>
2780 int FunctionParserBase<Value_t>::ParseAndDeduceVariables
2781 (const std::string& function,
2782  std::vector<std::string>& resultVars,
2783  bool useDegrees)
2784 {
2785     std::string varString;
2786     std::vector<std::string> vars;
2787     const int index =
2788         deduceVariables(*this, function.c_str(), varString,
2789                         0, &vars, useDegrees);
2790     if(index < 0) resultVars.swap(vars);
2791     return index;
2792 }
2793
2794
2795 #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING
2796 //===========================================================================
2797 // Bytecode injection
2798 //===========================================================================
2799 template<typename Value_t>
2800 void FunctionParserBase<Value_t>::InjectRawByteCode
2801 (const unsigned* bytecode, unsigned bytecodeAmount,
2802  const Value_t* immed, unsigned immedAmount, unsigned stackSize)
2803 {
2804     CopyOnWrite();
2805
2806     mData->mByteCode.assign(bytecode, bytecode + bytecodeAmount);
2807     mData->mImmed.assign(immed, immed + immedAmount);
2808     mData->mStackSize = stackSize;
2809
2810 #ifndef FP_USE_THREAD_SAFE_EVAL
2811     mData->mStack.resize(stackSize);
2812 #endif
2813 }
2814
2815 //===========================================================================
2816 // Debug output
2817 //===========================================================================
2818 #include <iomanip>
2819 #include <sstream>
2820 namespace
2821 {
2822     inline void printHex(std::ostream& dest, unsigned n)
2823     {
2824         std::ios::fmtflags flags = dest.flags();
2825         dest.width(4); dest.fill('0'); std::hex(dest); //uppercase(dest);
2826         dest << n;
2827         dest.flags(flags);
2828     }
2829
2830     void padLine(std::ostringstream& dest, unsigned destLength)
2831     {
2832         for(size_t currentLength = dest.str().length();
2833             currentLength < destLength;
2834             ++currentLength)
2835         {
2836             dest << ' ';
2837         }
2838     }
2839
2840     template<typename Value_t>
2841     std::string findName(const NamePtrsMap<Value_t>& nameMap,
2842                          unsigned index,
2843                          typename NameData<Value_t>::DataType type)
2844     {
2845         for(typename NamePtrsMap<Value_t>::const_iterator
2846                 iter = nameMap.begin();
2847             iter != nameMap.end();
2848             ++iter)
2849         {
2850             if(iter->second.type == type && iter->second.index == index)
2851                 return std::string(iter->first.name,
2852                                    iter->first.name + iter->first.nameLength);
2853         }
2854         return "?";
2855     }
2856
2857     const struct PowiMuliType
2858     {
2859         unsigned opcode_square;
2860         unsigned opcode_cumulate;
2861         unsigned opcode_invert;
2862         unsigned opcode_half;
2863         unsigned opcode_invhalf;
2864     } iseq_powi = {cSqr,cMul,cInv,cSqrt,cRSqrt},
2865       iseq_muli = {~unsigned(0), cAdd,cNeg, ~unsigned(0),~unsigned(0) };
2866
2867     template<typename Value_t>
2868     Value_t ParsePowiMuli(
2869         const PowiMuliType& opcodes,
2870         const std::vector<unsigned>& ByteCode, unsigned& IP,
2871         unsigned limit,
2872         size_t factor_stack_base,
2873         std::vector<Value_t>& stack,
2874         bool IgnoreExcess)
2875     {
2876         Value_t result = Value_t(1);
2877         while(IP < limit)
2878         {
2879             if(ByteCode[IP] == opcodes.opcode_square)
2880             {
2881                 if(!isInteger(result)) break;
2882                 result *= Value_t(2);
2883                 ++IP;
2884                 continue;
2885             }
2886             if(ByteCode[IP] == opcodes.opcode_invert)
2887             {
2888                 if(result < Value_t(0)) break;
2889                 result = -result;
2890                 ++IP;
2891                 continue;
2892             }
2893             if(ByteCode[IP] == opcodes.opcode_half)
2894             {
2895                 if(result > Value_t(0) && isEvenInteger(result))
2896                     break;
2897                 if(isInteger(result * Value_t(0.5))) break;
2898                 result *= Value_t(0.5);
2899                 ++IP;
2900                 continue;
2901             }
2902             if(ByteCode[IP] == opcodes.opcode_invhalf)
2903             {
2904                 if(result > Value_t(0) && isEvenInteger(result))
2905                     break;
2906                 if(isInteger(result * Value_t(-0.5))) break;
2907                 result *= Value_t(-0.5);
2908                 ++IP;
2909                 continue;
2910             }
2911
2912             unsigned dup_fetch_pos = IP;
2913             Value_t lhs = Value_t(1);
2914
2915             if(ByteCode[IP] == cFetch)
2916             {
2917                 unsigned index = ByteCode[++IP];
2918                 if(index < factor_stack_base
2919                 || size_t(index-factor_stack_base) >= stack.size())
2920                 {
2921                     // It wasn't a powi-fetch after all
2922                     IP = dup_fetch_pos;
2923                     break;
2924                 }
2925                 lhs = stack[index - factor_stack_base];
2926                 // Note: ^This assumes that cFetch of recentmost
2927                 //        is always converted into cDup.
2928                 goto dup_or_fetch;
2929             }
2930
2931             if(ByteCode[IP] == cDup)
2932             {
2933                 lhs = result;
2934                 goto dup_or_fetch;
2935
2936             dup_or_fetch:
2937                 stack.push_back(result);
2938                 ++IP;
2939                 Value_t subexponent = ParsePowiMuli
2940                     (opcodes,
2941                      ByteCode, IP, limit,
2942                      factor_stack_base, stack,
2943                      IgnoreExcess);
2944                 if(IP >= limit && IgnoreExcess)
2945                     return lhs*subexponent;
2946                 if(IP >= limit || ByteCode[IP] != opcodes.opcode_cumulate)
2947                 {
2948                     // It wasn't a powi-dup after all
2949                     IP = dup_fetch_pos;
2950                     break;
2951                 }
2952                 ++IP; // skip opcode_cumulate
2953                 stack.pop_back();
2954                 result += lhs*subexponent;
2955                 continue;
2956             }
2957             break;
2958         }
2959         return result;
2960     }
2961
2962     template<typename Value_t>
2963     Value_t ParsePowiSequence(const std::vector<unsigned>& ByteCode,
2964                               unsigned& IP, unsigned limit,
2965                               size_t factor_stack_base,
2966                               bool IgnoreExcess = false)
2967     {
2968         std::vector<Value_t> stack;
2969         stack.push_back(Value_t(1));
2970         return ParsePowiMuli(iseq_powi, ByteCode, IP, limit,
2971                              factor_stack_base, stack,
2972                              IgnoreExcess);
2973     }
2974
2975     template<typename Value_t>
2976     Value_t ParseMuliSequence(const std::vector<unsigned>& ByteCode,
2977                               unsigned& IP, unsigned limit,
2978                               size_t factor_stack_base,
2979                               bool IgnoreExcess = false)
2980     {
2981         std::vector<Value_t> stack;
2982         stack.push_back(Value_t(1));
2983         return ParsePowiMuli(iseq_muli, ByteCode, IP, limit,
2984                              factor_stack_base, stack,
2985                              IgnoreExcess);
2986     }
2987
2988     struct IfInfo
2989     {
2990         std::pair<int,std::string> condition;
2991         std::pair<int,std::string> thenbranch;
2992         unsigned endif_location;
2993
2994         IfInfo() : condition(), thenbranch(), endif_location() { }
2995     };
2996 }
2997
2998 template<typename Value_t>
2999 void FunctionParserBase<Value_t>::PrintByteCode(std::ostream& dest,
3000                                                 bool showExpression) const
3001 {
3002     dest << "Size of stack: " << mData->mStackSize << "\n";
3003
3004     std::ostringstream outputBuffer;
3005     std::ostream& output = (showExpression ? outputBuffer : dest);
3006
3007     const std::vector<unsigned>& ByteCode = mData->mByteCode;
3008     const std::vector<Value_t>& Immed = mData->mImmed;
3009
3010     std::vector<std::pair<int,std::string> > stack;
3011     std::vector<IfInfo> if_stack;
3012
3013     for(unsigned IP = 0, DP = 0; IP <= ByteCode.size(); ++IP)
3014     {
3015     after_powi_or_muli:;
3016         std::string n;
3017         bool out_params = false;
3018         unsigned params = 2, produces = 1, opcode = 0;
3019
3020         if(showExpression && !if_stack.empty() &&
3021           (   // Normal If termination rule:
3022               if_stack.back().endif_location == IP
3023               // This rule matches when cJumps are threaded:
3024            || (IP < ByteCode.size() && ByteCode[IP] == cJump
3025                && !if_stack.back().thenbranch.second.empty())
3026           ))
3027         {
3028             printHex(output, IP);
3029             if(if_stack.back().endif_location == IP)
3030                 output << ": ----- (phi)";
3031             else
3032                 output << ": ----- (phi+)";
3033
3034             stack.resize(stack.size()+2);
3035             std::swap(stack[stack.size()-3], stack[stack.size()-1]);
3036             std::swap(if_stack.back().condition,  stack[stack.size()-3]);
3037             std::swap(if_stack.back().thenbranch, stack[stack.size()-2]);
3038             opcode = cIf;
3039             params = 3;
3040             --IP;
3041             if_stack.pop_back();
3042         }
3043         else
3044         {
3045             if(IP >= ByteCode.size()) break;
3046             opcode = ByteCode[IP];
3047
3048             if(showExpression && (
3049                 opcode == cSqr || opcode == cDup
3050              || opcode == cInv
3051              || opcode == cSqrt || opcode == cRSqrt
3052              || opcode == cFetch
3053             ))
3054             {
3055                 unsigned changed_ip = IP;
3056                 Value_t exponent =
3057                     ParsePowiSequence<Value_t>
3058                     (ByteCode, changed_ip,
3059                      if_stack.empty()
3060                      ? (unsigned)ByteCode.size()
3061                      : if_stack.back().endif_location,
3062                      stack.size()-1);
3063                 std::string        operation_prefix;
3064                 std::ostringstream operation_value;
3065                 int prio = 0;
3066                 if(exponent == 1.0)
3067                 {
3068                     if(opcode != cDup) goto not_powi_or_muli;
3069                     Value_t factor =
3070                         ParseMuliSequence<Value_t>
3071                         (ByteCode, changed_ip,
3072                          if_stack.empty()
3073                          ? (unsigned)ByteCode.size()
3074                          : if_stack.back().endif_location,
3075                          stack.size()-1);
3076                     if(factor == Value_t(1) || factor == Value_t(-1))
3077                         goto not_powi_or_muli;
3078                     operation_prefix = "*";
3079                     operation_value << factor;
3080                     prio = 3;
3081                 }
3082                 else
3083                 {
3084                     prio = 2;
3085                     operation_prefix = "^";
3086                     operation_value << exponent;
3087                 }
3088
3089                 //unsigned explanation_before = changed_ip-2;
3090                 unsigned explanation_before = changed_ip-1;
3091
3092                 const char* explanation_prefix = "_";
3093                 for(const unsigned first_ip = IP; IP < changed_ip; ++IP)
3094                 {
3095                     printHex(output, IP);
3096                     output << ": ";
3097
3098                     const char* sep = "|";
3099                     if(first_ip+1 == changed_ip)
3100                     { sep = "="; explanation_prefix = " "; }
3101                     else if(IP   == first_ip) sep = "\\";
3102                     else if(IP+1 == changed_ip) sep = "/";
3103                     else explanation_prefix = "=";
3104
3105                     switch(ByteCode[IP])
3106                     {
3107                         case cInv: output << "inv"; break;
3108                         case cNeg: output << "neg"; break;
3109                         case cDup: output << "dup"; break;
3110                         case cSqr: output << "sqr"; break;
3111                         case cMul: output << "mul"; break;
3112                         case cAdd: output << "add"; break;
3113                         case cCbrt: output << "cbrt"; break;
3114                         case cSqrt: output << "sqrt"; break;
3115                         case cRSqrt: output << "rsqrt"; break;
3116                         case cFetch:
3117                         {
3118                             unsigned index = ByteCode[++IP];
3119                             output << "cFetch(" << index << ")";
3120                             break;
3121                         }
3122                         default: break;
3123                     }
3124                     padLine(outputBuffer, 20);
3125                     output << sep;
3126                     if(IP >= explanation_before)
3127                     {
3128                         explanation_before = (unsigned)ByteCode.size();
3129                         output << explanation_prefix
3130                                << '[' << (stack.size()-1) << ']';
3131                         std::string last = stack.back().second;
3132                         if(stack.back().first >= prio)
3133                             last = "(" + last + ")";
3134                         output << last;
3135                         output << operation_prefix;
3136                         output << operation_value.str();
3137                     }
3138                     else
3139                     {
3140                         unsigned p = first_ip;
3141                         Value_t exp = operation_prefix=="^" ?
3142                             ParsePowiSequence<Value_t>
3143                             (ByteCode, p, IP+1, stack.size()-1, true) :
3144                             ParseMuliSequence<Value_t>
3145                             (ByteCode, p, IP+1, stack.size()-1, true);
3146                         std::string last = stack.back().second;
3147                         if(stack.back().first >= prio)
3148                             last = "(" + last + ")";
3149                         output << " ..." << last;
3150                         output << operation_prefix;
3151                         output << exp;
3152                     }
3153                     dest << outputBuffer.str() << std::endl;
3154                     outputBuffer.str("");
3155                 }
3156
3157                 std::string& last = stack.back().second;
3158                 if(stack.back().first >= prio)
3159                     last = "(" + last + ")";
3160                 last += operation_prefix;
3161                 last += operation_value.str();
3162                 stack.back().first = prio;
3163
3164                 goto after_powi_or_muli;
3165             }
3166         not_powi_or_muli:;
3167             printHex(output, IP);
3168             output << ": ";
3169
3170             switch(opcode)
3171             {
3172               case cIf:
3173               {
3174                   unsigned label = ByteCode[IP+1]+1;
3175                   output << "jz ";
3176                   printHex(output, label);
3177                   params = 1;
3178                   produces = 0;
3179                   IP += 2;
3180
3181                   if_stack.resize(if_stack.size() + 1);
3182                   std::swap( if_stack.back().condition, stack.back() );
3183                   if_stack.back().endif_location = (unsigned) ByteCode.size();
3184                   stack.pop_back();
3185                   break;
3186               }
3187               case cAbsIf:
3188               {
3189                   unsigned dp    = ByteCode[IP+2];
3190                   unsigned label = ByteCode[IP+1]+1;
3191                   output << "jz_abs " << dp << ",";
3192                   printHex(output, label);
3193                   params = 1;
3194                   produces = 0;
3195                   IP += 2;
3196
3197                   if_stack.resize(if_stack.size() + 1);
3198                   std::swap( if_stack.back().condition, stack.back() );
3199                   if_stack.back().endif_location = (unsigned) ByteCode.size();
3200                   stack.pop_back();
3201                   break;
3202               }
3203
3204               case cJump:
3205               {
3206                   unsigned dp    = ByteCode[IP+2];
3207                   unsigned label = ByteCode[IP+1]+1;
3208
3209                   if(!if_stack.empty() && !stack.empty())
3210                   {
3211                       std::swap(if_stack.back().thenbranch, stack.back());
3212                       if_stack.back().endif_location = label;
3213                       stack.pop_back();
3214                   }
3215
3216                   output << "jump " << dp << ",";
3217                   printHex(output, label);
3218                   params = 0;
3219                   produces = 0;
3220                   IP += 2;
3221                   break;
3222               }
3223               case cImmed:
3224               {
3225                   if(showExpression)
3226                   {
3227                       std::ostringstream buf;
3228                       buf.precision(8);
3229                       buf << Immed[DP];
3230                       stack.push_back( std::make_pair(0, buf.str()) );
3231                   }
3232                   output.precision(8);
3233                   output << "push " << Immed[DP];
3234                   ++DP;
3235                   produces = 0;
3236                   break;
3237               }
3238
3239               case cFCall:
3240                   {
3241                       const unsigned index = ByteCode[++IP];
3242                       params = mData->mFuncPtrs[index].mParams;
3243                       static std::string name;
3244                       name = "f:" + findName(mData->mNamePtrs, index,
3245                                              NameData<Value_t>::FUNC_PTR);
3246                       n = name.c_str();
3247                       out_params = true;
3248                       break;
3249                   }
3250
3251               case cPCall:
3252                   {
3253                       const unsigned index = ByteCode[++IP];
3254                       params = mData->mFuncParsers[index].mParams;
3255                       static std::string name;
3256                       name = "p:" + findName(mData->mNamePtrs, index,
3257                                              NameData<Value_t>::PARSER_PTR);
3258                       n = name.c_str();
3259                       out_params = true;
3260                       break;
3261                   }
3262
3263               default:
3264                   if(OPCODE(opcode) < VarBegin)
3265                   {
3266                       switch(opcode)
3267                       {
3268                         case cNeg: n = "neg"; params = 1; break;
3269                         case cAdd: n = "add"; break;
3270                         case cSub: n = "sub"; break;
3271                         case cMul: n = "mul"; break;
3272                         case cDiv: n = "div"; break;
3273                         case cMod: n = "mod"; break;
3274                         case cPow: n = "pow"; break;
3275                         case cEqual: n = "eq"; break;
3276                         case cNEqual: n = "neq"; break;
3277                         case cLess: n = "lt"; break;
3278                         case cLessOrEq: n = "le"; break;
3279                         case cGreater: n = "gt"; break;
3280                         case cGreaterOrEq: n = "ge"; break;
3281                         case cAnd: n = "and"; break;
3282                         case cOr: n = "or"; break;
3283                         case cNot: n = "not"; params = 1; break;
3284                         case cNotNot: n = "notnot"; params = 1; break;
3285                         case cDeg: n = "deg"; params = 1; break;
3286                         case cRad: n = "rad"; params = 1; break;
3287
3288     #ifndef FP_DISABLE_EVAL
3289                         case cEval: n = "eval"; params = mData->mVariablesAmount;
3290     #endif
3291
3292                         case cFetch:
3293                         {
3294                             unsigned index = ByteCode[++IP];
3295                             if(showExpression && index < stack.size())
3296                                 stack.push_back(stack[index]);
3297                             output << "cFetch(" << index << ")";
3298                             produces = 0;
3299                             break;
3300                         }
3301     #ifdef FP_SUPPORT_OPTIMIZER
3302                         case cLog2by: n = "log2by"; params = 2; out_params = 1; break;
3303                         case cPopNMov:
3304                         {
3305                             size_t a = ByteCode[++IP];
3306                             size_t b = ByteCode[++IP];
3307                             if(showExpression && b < stack.size())
3308                             {
3309                                 std::pair<int, std::string> stacktop(0, "?");
3310                                 if(b < stack.size()) stacktop = stack[b];
3311                                 stack.resize(a);
3312                                 stack.push_back(stacktop);
3313                             }
3314                             output << "cPopNMov(" << a << ", " << b << ")";
3315                             produces = 0;
3316                             break;
3317                         }
3318                         case cNop:
3319                             output << "nop"; params = 0; produces = 0;
3320                             break;
3321     #endif
3322                         case cSinCos:
3323                         {
3324                             if(showExpression)
3325                             {
3326                                 std::pair<int, std::string> sin = stack.back();
3327                                 std::pair<int, std::string> cos(
3328                                     0, "cos(" + sin.second + ")");
3329                                 sin.first = 0;
3330                                 sin.second = "sin(" + sin.second + ")";
3331                                 stack.back() = sin;
3332                                 stack.push_back(cos);
3333                             }
3334                             output << "sincos";
3335                             produces = 0;
3336                             break;
3337                         }
3338                         case cAbsAnd: n = "abs_and"; break;
3339                         case cAbsOr:  n = "abs_or"; break;
3340                         case cAbsNot: n = "abs_not"; params = 1; break;
3341                         case cAbsNotNot: n = "abs_notnot"; params = 1; break;
3342                         case cDup:
3343                         {
3344                             if(showExpression)
3345                                 stack.push_back(stack.back());
3346                             output << "dup";
3347                             produces = 0;
3348                             break;
3349                         }
3350                         case cInv: n = "inv"; params = 1; break;
3351                         case cSqr: n = "sqr"; params = 1; break;
3352                         case cRDiv: n = "rdiv"; break;
3353                         case cRSub: n = "rsub"; break;
3354                         case cRSqrt: n = "rsqrt"; params = 1; break;
3355
3356                         default:
3357                             n = Functions[opcode-cAbs].name;
3358                             params = Functions[opcode-cAbs].params;
3359                             out_params = params != 1;
3360                       }
3361                   }
3362                   else
3363                   {
3364                       if(showExpression)
3365                       {
3366                           stack.push_back(std::make_pair(0,
3367                               (findName(mData->mNamePtrs, opcode,
3368                                         NameData<Value_t>::VARIABLE))));
3369                       }
3370                       output << "push Var" << opcode-VarBegin;
3371                       produces = 0;
3372                   }
3373             }
3374         }
3375         if(produces) output << n;
3376         if(out_params) output << " (" << params << ")";
3377         if(showExpression)
3378         {
3379             padLine(outputBuffer, 20);
3380
3381             if(produces > 0)
3382             {
3383                 std::ostringstream buf;
3384                 const char *paramsep = ",", *suff = "";
3385                 int prio = 0; bool commutative = false;
3386                 switch(opcode)
3387                 {
3388                   case cIf: buf << "if("; suff = ")";
3389                       break;
3390                   case cAbsIf: buf << "if("; suff = ")";
3391                       break;
3392                   case cOr:  prio = 6; paramsep = "|"; commutative = true;
3393                       break;
3394                   case cAnd: prio = 5; paramsep = "&"; commutative = true;
3395                       break;
3396                   case cAdd: prio = 4; paramsep = "+"; commutative = true;
3397                       break;
3398                   case cSub: prio = 4; paramsep = "-";
3399                       break;
3400                   case cMul: prio = 3; paramsep = "*"; commutative = true;
3401                       break;
3402                   case cDiv: prio = 3; paramsep = "/";
3403                       break;
3404                   case cPow: prio = 2; paramsep = "^";
3405                       break;
3406                   case cAbsOr:  prio = 6; paramsep = "|"; commutative = true;
3407                       break;
3408                   case cAbsAnd: prio = 5; paramsep = "&"; commutative = true;
3409                       break;
3410                   case cSqr: prio = 2; suff = "^2";
3411                       break;
3412                   case cNeg: buf << "(-("; suff = "))";
3413                       break;
3414                   case cNot: buf << "(!("; suff = "))";
3415                       break;
3416                   default: buf << n << '('; suff = ")";
3417                 }
3418
3419                 const char* sep = "";
3420                 for(unsigned a=0; a<params; ++a)
3421                 {
3422                     buf << sep;
3423                     if(stack.size() + a < params)
3424                         buf << "?";
3425                     else
3426                     {
3427                         const std::pair<int,std::string>& prev =
3428                             stack[stack.size() - params + a];
3429                         if(prio > 0 && (prev.first > prio ||
3430                                         (prev.first==prio && !commutative)))
3431                             buf << '(' << prev.second << ')';
3432                         else
3433                             buf << prev.second;
3434                     }
3435                     sep = paramsep;
3436                 }
3437                 if(stack.size() >= params)
3438                     stack.resize(stack.size() - params);
3439                 else
3440                     stack.clear();
3441                 buf << suff;
3442                 stack.push_back(std::make_pair(prio, buf.str()));
3443                 //if(n.size() <= 4 && !out_params) padLine(outputBuffer, 20);
3444             }
3445             //padLine(outputBuffer, 20);
3446             output << "= ";
3447             if(((opcode == cIf || opcode == cAbsIf) && params != 3)
3448               || opcode == cJump
3449     #ifdef FP_SUPPORT_OPTIMIZER
3450               || opcode == cNop
3451     #endif
3452                 )
3453                 output << "(void)";
3454             else if(stack.empty())
3455                 output << "[?] ?";
3456             else
3457                 output << '[' << (stack.size()-1) << ']'
3458                        << stack.back().second;
3459         }
3460
3461         if(showExpression)
3462         {
3463             dest << outputBuffer.str() << std::endl;
3464             outputBuffer.str("");
3465         }
3466         else
3467             output << std::endl;
3468     }
3469     dest << std::flush;
3470 }
3471 #endif
3472
3473
3474 #ifndef FP_SUPPORT_OPTIMIZER
3475 template<typename Value_t>
3476 void FunctionParserBase<Value_t>::Optimize()
3477 {
3478     // Do nothing if no optimizations are supported.
3479 }
3480 #endif
3481
3482 FUNCTIONPARSER_INSTANTIATE_TYPES