1 /***************************************************************************\
2 |* Function Parser for C++ v4.3 *|
3 |*-------------------------------------------------------------------------*|
4 |* Copyright: Juha Nieminen, Joel Yliluoma *|
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 \***************************************************************************/
11 #include "fpconfig.hh"
24 using namespace FUNCTIONPARSERTYPES;
26 #ifdef FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA
27 #ifndef FP_USE_THREAD_SAFE_EVAL
28 #define FP_USE_THREAD_SAFE_EVAL
33 # define likely(x) __builtin_expect(!!(x), 1)
34 # define unlikely(x) __builtin_expect(!!(x), 0)
36 # define likely(x) (x)
37 # define unlikely(x) (x)
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).
47 bool FUNCTIONPARSERTYPES::IsLogicalOpcode(unsigned op)
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:
64 bool FUNCTIONPARSERTYPES::IsComparisonOpcode(unsigned op)
68 case cEqual: case cNEqual:
69 case cLess: case cLessOrEq:
70 case cGreater: case cGreaterOrEq:
77 unsigned FUNCTIONPARSERTYPES::OppositeComparisonOpcode(unsigned op)
81 case cLess: return cGreater;
82 case cGreater: return cLess;
83 case cLessOrEq: return cGreaterOrEq;
84 case cGreaterOrEq: return cLessOrEq;
89 bool FUNCTIONPARSERTYPES::IsNeverNegativeValueOpcode(unsigned op)
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:
103 case cAcos: case cCosh:
110 bool FUNCTIONPARSERTYPES::IsAlwaysIntegerOpcode(unsigned op)
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:
128 bool FUNCTIONPARSERTYPES::IsUnaryOpcode(unsigned op)
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:
139 return (op < FUNC_AMOUNT && Functions[op].params == 1);
142 bool FUNCTIONPARSERTYPES::IsBinaryOpcode(unsigned op)
146 case cAdd: case cSub: case cRSub:
147 case cMul: case cDiv: case cRDiv:
149 case cEqual: case cNEqual: case cLess:
150 case cLessOrEq: case cGreater: case cGreaterOrEq:
151 case cAnd: case cAbsAnd:
152 case cOr: case cAbsOr:
155 return (op < FUNC_AMOUNT && Functions[op].params == 2);
158 bool FUNCTIONPARSERTYPES::HasInvalidRangesOpcode(unsigned op)
160 #ifndef FP_NO_EVALUATION_CHECKS
161 // Returns true, if the given opcode has a range of
162 // input values that gives an error.
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
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
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.
204 template<typename ValueT>
205 inline ValueT fp_pow_with_exp_log(const ValueT& x, const ValueT& y)
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);
213 template<typename ValueT>
214 inline ValueT fp_powi(ValueT x, unsigned long y)
216 // Fast binary exponentiation algorithm
217 // See http://en.wikipedia.org/wiki/Exponentiation_by_squaring
218 // Requirements: y is non-negative integer.
222 if(y & 1) { result *= x; y -= 1; }
223 else { x *= x; y /= 2; }
229 template<typename ValueT>
230 ValueT FUNCTIONPARSERTYPES::fp_pow(const ValueT& x, const ValueT& y)
232 if(x == ValueT(1)) return ValueT(1);
233 // y is now zero or positive
236 // Use fast binary exponentiation algorithm
238 return fp_powi(x, makeLongInteger(y));
240 return ValueT(1) / fp_powi(x, -makeLongInteger(y));
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.
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.
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.
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);
282 if(!isInteger(y*ValueT(-16)))
283 return -fp_pow_with_exp_log(ValueT(-1) / x, -y);
284 // ^ See comment above.
286 // Remaining case: 0.0 ^ negative number
288 // This is reached when:
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);
296 //=========================================================================
297 // Elementary (atom) parsing functions
298 //=========================================================================
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.
306 unsigned readIdentifierForFloatType(const char* input)
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.
320 #include "fp_identifier_parser.inc"
324 inline unsigned readIdentifierForIntType(const char* input)
326 const unsigned value = readIdentifierForFloatType(input);
327 if((value & 0x80000000U) != 0 &&
328 !Functions[(value >> 16) & 0x7FFF].okForInt())
329 return value & 0xFFFF;
333 template<typename Value_t>
334 inline unsigned readIdentifier(const char* input)
336 return IsIntType<Value_t>::result
337 ? readIdentifierForIntType(input)
338 : readIdentifierForFloatType(input);
341 // Returns true if the entire string is a valid identifier
342 template<typename Value_t>
343 bool containsOnlyValidIdentifierChars(const std::string& name)
345 if(name.empty()) return false;
346 return readIdentifier<Value_t>(name.c_str()) == (unsigned) name.size();
350 // -----------------------------------------------------------------------
351 // Wrappers for strto... functions
352 // -----------------------------------------------------------------------
353 template<typename Value_t>
354 inline Value_t fp_parseLiteral(const char* str, char** endptr)
356 return strtod(str, endptr);
359 #ifdef FP_SUPPORT_FLOAT_TYPE
361 inline float fp_parseLiteral<float>(const char* str, char** endptr)
363 return strtof(str, endptr);
367 #ifdef FP_SUPPORT_LONG_DOUBLE_TYPE
369 inline long double fp_parseLiteral<long double>(const char* str,
372 return strtold(str, endptr);
376 #ifdef FP_SUPPORT_LONG_INT_TYPE
378 inline long fp_parseLiteral<long>(const char* str, char** endptr)
380 return strtol(str, endptr, 10);
385 // -----------------------------------------------------------------------
386 // Hexadecimal floating point literal parsing
387 // -----------------------------------------------------------------------
388 inline int testXdigit(unsigned c)
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
395 template<typename elem_t, unsigned n_limbs, unsigned limb_bits>
396 inline void addXdigit(elem_t* buffer, unsigned nibble)
398 for(unsigned p=0; p<n_limbs; ++p)
400 unsigned carry = unsigned( buffer[p] >> (elem_t)(limb_bits-4) );
401 buffer[p] = (buffer[p] << 4) | nibble;
406 template<typename Value_t>
407 Value_t parseHexLiteral(const char* str, char** endptr)
409 const unsigned bits_per_char = 8;
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);
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 };
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
427 int xdigit = testXdigit(*str);
428 if(xdigit < 0) break;
429 addXdigit<elem_t,n_limbs,limb_bits> (mantissa_buffer, xdigit);
432 n_mantissa_bits += 4;
433 if(n_mantissa_bits >= ExtraMantissaBits)
435 // Exhausted the precision. Parse the rest (until exponent)
436 // normally but ignore the actual digits.
437 for(; testXdigit(*str) >= 0; ++str)
439 // Read but ignore decimals
441 for(++str; testXdigit(*str) >= 0; ++str)
450 int xdigit = testXdigit(*str);
451 if(xdigit < 0) break;
452 addXdigit<elem_t,n_limbs,limb_bits> (mantissa_buffer, xdigit);
456 n_mantissa_bits += 4;
457 if(n_mantissa_bits >= ExtraMantissaBits)
459 // Exhausted the precision. Skip the rest
460 // of the decimals, until the exponent.
461 while(testXdigit(*str) >= 0)
469 if(*str == 'p' || *str == 'P')
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)
475 exponent += (int)p_exponent;
480 if(endptr) *endptr = (char*) str;
482 Value_t result = ldexp(Value_t(mantissa_buffer[0]), exponent);
483 for(unsigned p=1; p<n_limbs; ++p)
485 exponent += limb_bits;
486 result += ldexp(Value_t(mantissa_buffer[p]), exponent);
491 #ifdef FP_SUPPORT_LONG_INT_TYPE
493 long parseHexLiteral<long>(const char* str, char** endptr)
495 return strtol(str, endptr, 16);
500 //=========================================================================
502 //=========================================================================
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,
514 typename NamePtrsMap<Value_t>::iterator nameIter =
515 namePtrs.lower_bound(newName.first);
517 if(nameIter != namePtrs.end() && newName.first == nameIter->first)
519 // redefining a var is not allowed.
520 if(isVar) return false;
522 // redefining other tokens is allowed, if the type stays the same.
523 if(nameIter->second.type != newName.second.type)
527 nameIter->second = newName.second;
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;
541 namePtrs.insert(nameIter, newName);
547 //=========================================================================
548 // Data struct implementation
549 //=========================================================================
550 template<typename Value_t>
551 FunctionParserBase<Value_t>::Data::Data():
552 mReferenceCounter(1),
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),
563 mFuncPtrs(rhs.mFuncPtrs),
564 mFuncParsers(rhs.mFuncParsers),
565 mByteCode(rhs.mByteCode),
567 #ifndef FP_USE_THREAD_SAFE_EVAL
568 mStack(rhs.mStackSize),
570 mStackSize(rhs.mStackSize)
572 for(typename NamePtrsMap<Value_t>::const_iterator i = rhs.mNamePtrs.begin();
573 i != rhs.mNamePtrs.end();
576 if(i->second.type == NameData<Value_t>::VARIABLE)
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),
584 mNamePtrs.insert(mNamePtrs.end(), tmp);
588 std::pair<NamePtr, NameData<Value_t> > tmp
589 (NamePtr(new char[i->first.nameLength], i->first.nameLength),
591 memcpy(const_cast<char*>(tmp.first.name), i->first.name,
592 tmp.first.nameLength);
593 mNamePtrs.insert(mNamePtrs.end(), tmp);
598 template<typename Value_t>
599 FunctionParserBase<Value_t>::Data::~Data()
601 for(typename NamePtrsMap<Value_t>::iterator i = mNamePtrs.begin();
602 i != mNamePtrs.end();
605 if(i->second.type != NameData<Value_t>::VARIABLE)
606 delete[] i->first.name;
611 //=========================================================================
612 // FunctionParser constructors, destructor and assignment
613 //=========================================================================
614 template<typename Value_t>
615 FunctionParserBase<Value_t>::FunctionParserBase():
617 mParseErrorType(NO_FUNCTION_PARSED_YET), mEvalErrorType(0),
619 mUseDegreeConversion(false),
620 mEvalRecursionLevel(0),
621 mStackPtr(0), mErrorLocation(0)
625 template<typename Value_t>
626 FunctionParserBase<Value_t>::~FunctionParserBase()
628 if(--(mData->mReferenceCounter) == 0)
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),
638 mUseDegreeConversion(cpy.mUseDegreeConversion),
639 mEvalRecursionLevel(0),
640 mStackPtr(0), mErrorLocation(0)
642 ++(mData->mReferenceCounter);
645 template<typename Value_t>
646 FunctionParserBase<Value_t>&
647 FunctionParserBase<Value_t>::operator=(const FunctionParserBase& cpy)
649 if(mData != cpy.mData)
651 if(--(mData->mReferenceCounter) == 0) delete mData;
653 mDelimiterChar = cpy.mDelimiterChar;
654 mParseErrorType = cpy.mParseErrorType;
655 mEvalErrorType = cpy.mEvalErrorType;
657 mUseDegreeConversion = cpy.mUseDegreeConversion;
658 mEvalRecursionLevel = cpy.mEvalRecursionLevel;
660 ++(mData->mReferenceCounter);
667 template<typename Value_t>
668 void FunctionParserBase<Value_t>::setDelimiterChar(char c)
674 //---------------------------------------------------------------------------
675 // Copy-on-write method
676 //---------------------------------------------------------------------------
677 template<typename Value_t>
678 void FunctionParserBase<Value_t>::CopyOnWrite()
680 if(mData->mReferenceCounter > 1)
682 Data* oldData = mData;
683 mData = new Data(*oldData);
684 --(oldData->mReferenceCounter);
685 mData->mReferenceCounter = 1;
689 template<typename Value_t>
690 void FunctionParserBase<Value_t>::ForceDeepCopy()
696 //=========================================================================
697 // User-defined identifier addition functions
698 //=========================================================================
699 template<typename Value_t>
700 bool FunctionParserBase<Value_t>::AddConstant(const std::string& name,
703 if(!containsOnlyValidIdentifierChars<Value_t>(name)) return false;
706 std::pair<NamePtr, NameData<Value_t> > newName
707 (NamePtr(name.data(), unsigned(name.size())),
708 NameData<Value_t>(NameData<Value_t>::CONSTANT, value));
710 return addNewNameData(mData->mNamePtrs, newName, false);
713 template<typename Value_t>
714 bool FunctionParserBase<Value_t>::AddUnit(const std::string& name,
717 if(!containsOnlyValidIdentifierChars<Value_t>(name)) return false;
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);
726 template<typename Value_t>
727 bool FunctionParserBase<Value_t>::AddFunction
728 (const std::string& name, FunctionPtr ptr, unsigned paramsAmount)
730 if(!containsOnlyValidIdentifierChars<Value_t>(name)) return false;
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())));
738 const bool success = addNewNameData(mData->mNamePtrs, newName, false);
741 mData->mFuncPtrs.push_back(typename Data::FuncPtrData());
742 mData->mFuncPtrs.back().mFuncPtr = ptr;
743 mData->mFuncPtrs.back().mParams = paramsAmount;
748 template<typename Value_t>
749 bool FunctionParserBase<Value_t>::CheckRecursiveLinking
750 (const FunctionParserBase* fp) const
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))
759 template<typename Value_t>
760 bool FunctionParserBase<Value_t>::AddFunction(const std::string& name,
761 FunctionParserBase& fp)
763 if(!containsOnlyValidIdentifierChars<Value_t>(name) ||
764 CheckRecursiveLinking(&fp))
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())));
773 const bool success = addNewNameData(mData->mNamePtrs, newName, false);
776 mData->mFuncParsers.push_back(typename Data::FuncPtrData());
777 mData->mFuncParsers.back().mParserPtr = &fp;
778 mData->mFuncParsers.back().mParams = fp.mData->mVariablesAmount;
783 template<typename Value_t>
784 bool FunctionParserBase<Value_t>::RemoveIdentifier(const std::string& name)
788 NamePtr namePtr(name.data(), unsigned(name.size()));
790 typename NamePtrsMap<Value_t>::iterator
791 nameIter = mData->mNamePtrs.find(namePtr);
793 if(nameIter != mData->mNamePtrs.end())
795 if(nameIter->second.type == NameData<Value_t>::VARIABLE)
797 // Illegal attempt to delete variables
800 delete[] nameIter->first.name;
801 mData->mNamePtrs.erase(nameIter);
808 //=========================================================================
810 //=========================================================================
813 // Error messages returned by ErrorMsg():
814 const char* const ParseErrorMessage[]=
817 "Mismatched parenthesis", // 1
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)",
834 template<typename Value_t>
835 inline typename FunctionParserBase<Value_t>::ParseErrorType
839 FunctionParserBase<Value_t>::ILL_PARAMS_AMOUNT :
840 FunctionParserBase<Value_t>::SYNTAX_ERROR;
843 template<typename Value_t>
844 inline typename FunctionParserBase<Value_t>::ParseErrorType
845 noParenthError(char c)
848 FunctionParserBase<Value_t>::ILL_PARAMS_AMOUNT :
849 FunctionParserBase<Value_t>::MISSING_PARENTH;
852 template<unsigned offset>
853 struct IntLiteralMask
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 '.'.
864 template<typename Value_t, unsigned offset>
868 ( 1UL << ('.'-offset)) |
869 IntLiteralMask<offset>::mask };
871 #ifdef FP_SUPPORT_LONG_INT_TYPE
872 template<unsigned offset>
873 struct LiteralMask<long, offset>: public IntLiteralMask<offset>
877 #ifdef FP_SUPPORT_GMP_INT_TYPE
878 template<unsigned offset>
879 struct LiteralMask<GmpInt, offset>: public IntLiteralMask<offset>
884 template<unsigned offset>
885 struct SimpleSpaceMask
888 (1UL << ('\r'-offset)) |
889 (1UL << ('\n'-offset)) |
890 (1UL << ('\v'-offset)) |
891 (1UL << ('\t'-offset)) |
892 (1UL << (' ' -offset)) };
895 template<typename Value_t>
896 inline bool BeginsLiteral(unsigned byte)
898 const unsigned n = sizeof(unsigned long)>=8 ? 0 : '.';
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;
906 template<typename CharPtr>
907 inline void SkipSpace(CharPtr& function)
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)
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.
947 const unsigned n = sizeof(unsigned long)>=8 ? 0 : '\t';
948 typedef signed char schar;
949 unsigned byte = (unsigned char)*function;
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))
958 unsigned long shifted = 1UL << byte;
959 const unsigned long mask = SimpleSpaceMask<n>::mask;
961 { ++function; continue; } // \r, \n, \t, \v and space
964 if(likely(byte < 0xC2-n)) break;
966 if(byte == 0xC2-n && function[1] == char(0xA0))
967 { function += 2; continue; } // U+00A0
969 function[1] == char(0x80) && function[2] == char(0x80))
970 { function += 3; continue; } // U+3000
973 if(function[1] == char(0x81))
975 if(function[2] != char(0x9F)) break;
976 function += 3; // U+205F
979 if(function[1] == char(0x80))
980 if(function[2] == char(0xAF) || // U+202F
981 schar(function[2]) <= schar(0x8B) // U+2000..U+200B
990 } // SkipSpace(CharPtr& function)
993 // ---------------------------------------------------------------------------
994 // Return parse error message
995 // ---------------------------------------------------------------------------
996 template<typename Value_t>
997 const char* FunctionParserBase<Value_t>::ErrorMsg() const
999 return ParseErrorMessage[mParseErrorType];
1003 // ---------------------------------------------------------------------------
1005 // ---------------------------------------------------------------------------
1006 template<typename Value_t>
1007 bool FunctionParserBase<Value_t>::ParseVariables
1008 (const std::string& inputVarString)
1010 if(mData->mVariablesString == inputVarString) return true;
1012 /* Delete existing variables from mNamePtrs */
1013 for(typename NamePtrsMap<Value_t>::iterator i =
1014 mData->mNamePtrs.begin();
1015 i != mData->mNamePtrs.end(); )
1017 if(i->second.type == NameData<Value_t>::VARIABLE)
1019 typename NamePtrsMap<Value_t>::iterator j (i);
1021 mData->mNamePtrs.erase(j);
1025 mData->mVariablesString = inputVarString;
1027 const std::string& vars = mData->mVariablesString;
1028 const unsigned len = unsigned(vars.size());
1030 unsigned varNumber = VarBegin;
1032 const char* beginPtr = vars.c_str();
1033 const char* finalPtr = beginPtr + len;
1034 while(beginPtr < finalPtr)
1036 SkipSpace(beginPtr);
1037 unsigned nameLength = readIdentifier<Value_t>(beginPtr);
1038 if(nameLength == 0 || (nameLength & 0x80000000U)) return false;
1039 const char* endPtr = beginPtr + nameLength;
1041 if(endPtr != finalPtr && *endPtr != ',') return false;
1043 std::pair<NamePtr, NameData<Value_t> > newName
1044 (NamePtr(beginPtr, nameLength),
1045 NameData<Value_t>(NameData<Value_t>::VARIABLE, varNumber++));
1047 if(!addNewNameData(mData->mNamePtrs, newName, true))
1052 beginPtr = endPtr + 1;
1055 mData->mVariablesAmount = varNumber - VarBegin;
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,
1069 if(!ParseVariables(Vars))
1071 mParseErrorType = INVALID_VARS;
1072 return int(strlen(Function));
1075 return ParseFunction(Function, useDegrees);
1078 template<typename Value_t>
1079 int FunctionParserBase<Value_t>::Parse(const std::string& Function,
1080 const std::string& Vars,
1085 if(!ParseVariables(Vars))
1087 mParseErrorType = INVALID_VARS;
1088 return int(Function.size());
1091 return ParseFunction(Function.c_str(), useDegrees);
1095 // ---------------------------------------------------------------------------
1096 // Main parsing function
1097 // ---------------------------------------------------------------------------
1098 template<typename Value_t>
1099 int FunctionParserBase<Value_t>::ParseFunction(const char* function,
1102 mUseDegreeConversion = useDegrees;
1103 mParseErrorType = FP_NO_ERROR;
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;
1110 mHasByteCodeFlags = false;
1112 const char* ptr = Compile(function);
1113 mData->mInlineVarNames.clear();
1115 if(mHasByteCodeFlags)
1117 for(unsigned i = unsigned(mData->mByteCode.size()); i-- > 0; )
1118 mData->mByteCode[i] &= ~0x80000000U;
1121 if(mParseErrorType != FP_NO_ERROR) return int(mErrorLocation - function);
1123 assert(ptr); // Should never be null at this point. It's a bug otherwise.
1126 if(mDelimiterChar == 0 || *ptr != mDelimiterChar)
1127 mParseErrorType = EXPECT_OPERATOR;
1128 return int(ptr - function);
1131 #ifndef FP_USE_THREAD_SAFE_EVAL
1132 mData->mStack.resize(mData->mStackSize);
1139 //=========================================================================
1140 // Parsing and bytecode compiling functions
1141 //=========================================================================
1142 template<typename Value_t>
1143 inline const char* FunctionParserBase<Value_t>::SetErrorType(ParseErrorType t,
1146 mParseErrorType = t;
1147 mErrorLocation = pos;
1151 template<typename Value_t>
1152 inline void FunctionParserBase<Value_t>::incStackPtr()
1154 if(++mStackPtr > mData->mStackSize) ++(mData->mStackSize);
1159 const unsigned char powi_factor_table[128] =
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 */
1171 inline int get_powi_factor(long abs_int_exponent)
1173 if(abs_int_exponent >= int(sizeof(powi_factor_table))) return 0;
1174 return powi_factor_table[abs_int_exponent];
1178 int EstimatePowiComplexity(int abs_int_exponent)
1181 while(abs_int_exponent > 1)
1183 int factor = get_powi_factor(abs_int_exponent);
1186 cost += EstimatePowiComplexity(factor);
1187 abs_int_exponent /= factor;
1190 if(!(abs_int_exponent & 1))
1192 abs_int_exponent /= 2;
1197 cost += 4; // dup+mul
1198 abs_int_exponent -= 1;
1205 bool IsEligibleIntPowiExponent(long int_exponent)
1207 if(int_exponent == 0) return false;
1208 long abs_int_exponent = int_exponent;
1212 if(abs_int_exponent < 0)
1215 abs_int_exponent = -abs_int_exponent;
1218 cost += EstimatePowiComplexity(abs_int_exponent);
1220 return cost < (10*3 + 4*4);
1222 if(abs_int_exponent < 0) abs_int_exponent = -abs_int_exponent;
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));
1232 const double EpsilonOrZero = FP_EPSILON;
1234 const double EpsilonOrZero = 0.0;
1239 template<typename Value_t>
1240 inline void FunctionParserBase<Value_t>::AddImmedOpcode(Value_t value)
1242 mData->mImmed.push_back(value);
1243 mData->mByteCode.push_back(cImmed);
1246 template<typename Value_t>
1247 inline void FunctionParserBase<Value_t>::CompilePowi(long abs_int_exponent)
1250 while(abs_int_exponent > 1)
1252 long factor = get_powi_factor(abs_int_exponent);
1255 CompilePowi(factor);
1256 abs_int_exponent /= factor;
1259 if(!(abs_int_exponent & 1))
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.
1268 mData->mByteCode.push_back(cDup);
1270 abs_int_exponent -= 1;
1276 mData->mByteCode.resize(mData->mByteCode.size()+num_muls, cMul);
1277 mStackPtr -= num_muls;
1281 template<typename Value_t>
1282 inline bool FunctionParserBase<Value_t>::TryCompilePowi(Value_t original_immed)
1284 Value_t changed_immed = original_immed;
1285 for(int sqrt_count=0; /**/; ++sqrt_count)
1287 long int_exponent = makeLongInteger(changed_immed);
1288 if(isLongInteger(changed_immed) &&
1289 IsEligibleIntPowiExponent(int_exponent))
1291 long abs_int_exponent = int_exponent;
1292 if(abs_int_exponent < 0)
1293 abs_int_exponent = -abs_int_exponent;
1295 mData->mImmed.pop_back(); mData->mByteCode.pop_back();
1297 // ^Though the above is accounted for by the procedure
1298 // that generates cPow, we need it for correct cFetch
1299 // indexes in CompilePowi().
1301 while(sqrt_count > 0)
1304 if(sqrt_count == 1 && int_exponent < 0)
1307 int_exponent = -int_exponent;
1309 mData->mByteCode.push_back(opcode);
1312 if((abs_int_exponent & 1) == 0)
1314 // This special rule fixes the optimization
1315 // shortcoming of (-x)^2 with minimal overhead.
1316 AddFunctionOpcode(cSqr);
1317 abs_int_exponent >>= 1;
1319 CompilePowi(abs_int_exponent);
1320 if(int_exponent < 0) mData->mByteCode.push_back(cInv);
1321 ++mStackPtr; // Needed because cPow adding will assume this.
1324 if(sqrt_count >= 4) break;
1325 changed_immed += changed_immed;
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]))
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);
1349 //#include "fpoptimizer/opcodename.hh"
1350 // ^ needed only if FP_TRACE_BYTECODE_OPTIMIZATION() is used
1352 template<typename Value_t>
1353 inline void FunctionParserBase<Value_t>::AddFunctionOpcode(unsigned opcode)
1355 #define FP_FLOAT_VERSION 1
1356 #include "fp_opcode_add.inc"
1357 #undef FP_FLOAT_VERSION
1360 #ifdef FP_SUPPORT_LONG_INT_TYPE
1362 inline void FunctionParserBase<long>::AddFunctionOpcode(unsigned opcode)
1364 typedef long Value_t;
1365 #define FP_FLOAT_VERSION 0
1366 #include "fp_opcode_add.inc"
1367 #undef FP_FLOAT_VERSION
1371 #ifdef FP_SUPPORT_GMP_INT_TYPE
1373 inline void FunctionParserBase<GmpInt>::AddFunctionOpcode(unsigned opcode)
1375 typedef GmpInt Value_t;
1376 #define FP_FLOAT_VERSION 0
1377 #include "fp_opcode_add.inc"
1378 #undef FP_FLOAT_VERSION
1382 template<typename Value_t>
1384 FunctionParserBase<Value_t>::ParseIdentifier(const char* function)
1386 return readIdentifier<Value_t>(function);
1389 template<typename Value_t>
1390 std::pair<const char*, Value_t>
1391 FunctionParserBase<Value_t>::ParseLiteral(const char* function)
1394 #if 0 /* Profile the hex literal parser */
1395 if(function[0]=='0' && function[1]=='x')
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);
1404 Value_t val = fp_parseLiteral<Value_t>(function, &endptr);
1406 if(endptr == function+1 && function[0] == '0' && function[1] == 'x')
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());
1413 else if(endptr == function)
1414 return std::pair<const char*,Value_t> (function, Value_t());
1416 return std::pair<const char*,Value_t> (endptr, val);
1419 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
1421 std::pair<const char*, MpfrFloat>
1422 FunctionParserBase<MpfrFloat>::ParseLiteral(const char* function)
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);
1432 #ifdef FP_SUPPORT_GMP_INT_TYPE
1434 std::pair<const char*, GmpInt>
1435 FunctionParserBase<GmpInt>::ParseLiteral(const char* function)
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);
1446 template<typename Value_t>
1448 FunctionParserBase<Value_t>::CompileLiteral(const char* function)
1450 std::pair<const char*, Value_t> result = ParseLiteral(function);
1452 if(result.first == function)
1453 return SetErrorType(SYNTAX_ERROR, result.first);
1455 AddImmedOpcode(result.second);
1457 SkipSpace(result.first);
1458 return result.first;
1461 template<typename Value_t>
1462 const char* FunctionParserBase<Value_t>::CompileIf(const char* function)
1464 if(*function != '(') return SetErrorType(EXPECT_PARENTH_FUNC, function);
1466 function = CompileExpression(function+1);
1467 if(!function) return 0;
1468 if(*function != ',')
1469 return SetErrorType(noCommaError<Value_t>(*function), function);
1471 OPCODE opcode = cIf;
1472 if(mData->mByteCode.back() == cNotNot) mData->mByteCode.pop_back();
1473 if(IsNeverNegativeValueOpcode(mData->mByteCode.back()))
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.
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
1490 function = CompileExpression(function + 1);
1491 if(!function) return 0;
1492 if(*function != ',')
1493 return SetErrorType(noCommaError<Value_t>(*function), function);
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
1503 function = CompileExpression(function + 1);
1504 if(!function) return 0;
1505 if(*function != ')')
1506 return SetErrorType(noParenthError<Value_t>(*function), function);
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
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);
1519 SkipSpace(function);
1523 template<typename Value_t>
1524 const char* FunctionParserBase<Value_t>::CompileFunctionParams
1525 (const char* function, unsigned requiredParams)
1527 if(*function != '(') return SetErrorType(EXPECT_PARENTH_FUNC, function);
1529 if(requiredParams > 0)
1531 const char* function_end = CompileExpression(function+1);
1534 // If an error occurred, verify whether it was caused by ()
1536 SkipSpace(function);
1537 if(*function == ')')
1538 return SetErrorType(ILL_PARAMS_AMOUNT, function);
1539 // Not caused by (), use the error message given by CompileExpression()
1542 function = function_end;
1544 for(unsigned i = 1; i < requiredParams; ++i)
1546 if(*function != ',')
1547 return SetErrorType(noCommaError<Value_t>(*function), function);
1549 function = CompileExpression(function+1);
1550 if(!function) return 0;
1552 // No need for incStackPtr() because each parse parameter calls it
1553 mStackPtr -= requiredParams-1;
1557 incStackPtr(); // return value of function is pushed onto the stack
1559 SkipSpace(function);
1562 if(*function != ')')
1563 return SetErrorType(noParenthError<Value_t>(*function), function);
1565 SkipSpace(function);
1569 template<typename Value_t>
1570 const char* FunctionParserBase<Value_t>::CompileElement(const char* function)
1572 if(BeginsLiteral<Value_t>( (unsigned char) *function))
1573 return CompileLiteral(function);
1575 unsigned nameLength = readIdentifier<Value_t>(function);
1578 // No identifier found
1579 if(*function == '(') return CompileParenthesis(function);
1580 if(*function == ')') return SetErrorType(MISM_PARENTH, function);
1581 return SetErrorType(SYNTAX_ERROR, function);
1584 // Function, variable or constant
1585 if(nameLength & 0x80000000U) // Function
1587 OPCODE func_opcode = OPCODE( (nameLength >> 16) & 0x7FFF );
1588 return CompileFunction(function + (nameLength & 0xFFFF), func_opcode);
1591 NamePtr name(function, nameLength);
1592 const char* endPtr = function + nameLength;
1595 typename NamePtrsMap<Value_t>::iterator nameIter =
1596 mData->mNamePtrs.find(name);
1597 if(nameIter == mData->mNamePtrs.end())
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();
1605 if(name == iter->mName)
1607 if( iter->mFetchIndex+1 == mStackPtr)
1609 mData->mByteCode.push_back(cDup);
1613 mData->mByteCode.push_back(cFetch);
1614 PushOpcodeParam<true>(iter->mFetchIndex);
1621 return SetErrorType(UNKNOWN_IDENTIFIER, function);
1624 const NameData<Value_t>* nameData = &nameIter->second;
1625 switch(nameData->type)
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);
1632 mData->mByteCode.push_back(nameData->index);
1636 case NameData<Value_t>::CONSTANT: // is constant
1637 AddImmedOpcode(nameData->value);
1641 case NameData<Value_t>::UNIT: // is unit (error if appears here)
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);
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);
1661 // When it's an unit (or unrecognized type):
1662 return SetErrorType(SYNTAX_ERROR, function);
1665 template<typename Value_t>
1666 inline const char* FunctionParserBase<Value_t>::CompileFunction
1667 (const char* function, unsigned func_opcode)
1669 SkipSpace(function);
1670 const FuncDefinition& funcDef = Functions[func_opcode];
1672 if(func_opcode == cIf) // "if" is a special case
1673 return CompileIf(function);
1675 unsigned requiredParams = funcDef.params;
1676 #ifndef FP_DISABLE_EVAL
1677 if(func_opcode == cEval)
1678 requiredParams = mData->mVariablesAmount;
1681 function = CompileFunctionParams(function, requiredParams);
1682 if(!function) return 0;
1684 if(mUseDegreeConversion)
1686 if(funcDef.flags & FuncDefinition::AngleIn)
1687 AddFunctionOpcode(cRad);
1689 AddFunctionOpcode(func_opcode);
1691 if(funcDef.flags & FuncDefinition::AngleOut)
1692 AddFunctionOpcode(cDeg);
1696 AddFunctionOpcode(func_opcode);
1701 template<typename Value_t>
1703 FunctionParserBase<Value_t>::CompileParenthesis(const char* function)
1705 ++function; // Skip '('
1707 SkipSpace(function);
1708 if(*function == ')') return SetErrorType(EMPTY_PARENTH, function);
1709 function = CompileExpression(function);
1710 if(!function) return 0;
1712 if(*function != ')') return SetErrorType(MISSING_PARENTH, function);
1713 ++function; // Skip ')'
1715 SkipSpace(function);
1719 template<typename Value_t>
1721 FunctionParserBase<Value_t>::CompilePossibleUnit(const char* function)
1723 unsigned nameLength = readIdentifier<Value_t>(function);
1724 if(nameLength & 0x80000000U) return function; // built-in function name
1727 NamePtr name(function, nameLength);
1729 typename NamePtrsMap<Value_t>::iterator nameIter =
1730 mData->mNamePtrs.find(name);
1731 if(nameIter != mData->mNamePtrs.end())
1733 const NameData<Value_t>* nameData = &nameIter->second;
1734 if(nameData->type == NameData<Value_t>::UNIT)
1736 AddImmedOpcode(nameData->value);
1738 AddFunctionOpcode(cMul);
1741 const char* endPtr = function + nameLength;
1751 template<typename Value_t>
1753 FunctionParserBase<Value_t>::CompilePow(const char* function)
1755 function = CompileElement(function);
1756 if(!function) return 0;
1757 function = CompilePossibleUnit(function);
1759 if(*function == '^')
1762 SkipSpace(function);
1765 if(mData->mByteCode.back() == cImmed)
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; }
1775 function = CompileUnaryMinus(function);
1776 if(!function) return 0;
1779 AddFunctionOpcode(op);
1781 if(op == cPow) --mStackPtr;
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
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").
1794 #ifdef FP_SUPPORT_LONG_INT_TYPE
1797 FunctionParserBase<long>::CompilePow(const char* function)
1799 function = CompileElement(function);
1800 if(!function) return 0;
1801 return CompilePossibleUnit(function);
1805 #ifdef FP_SUPPORT_GMP_INT_TYPE
1808 FunctionParserBase<GmpInt>::CompilePow(const char* function)
1810 function = CompileElement(function);
1811 if(!function) return 0;
1812 return CompilePossibleUnit(function);
1816 template<typename Value_t>
1818 FunctionParserBase<Value_t>::CompileUnaryMinus(const char* function)
1820 char op = *function;
1826 SkipSpace(function);
1828 function = CompileUnaryMinus(function);
1829 if(!function) return 0;
1831 AddFunctionOpcode(op=='-' ? cNeg : cNot);
1836 return CompilePow(function);
1839 template<typename Value_t>
1841 FunctionParserBase<Value_t>::CompileMult(const char* function)
1843 function = CompileUnaryMinus(function);
1844 if(!function) return 0;
1846 Value_t pending_immed(1);
1847 #define FP_FlushImmed(do_reset) \
1848 if(pending_immed != Value_t(1)) \
1850 unsigned op = cMul; \
1851 if(!IsIntType<Value_t>::result && mData->mByteCode.back() == cInv) \
1853 /* (...) cInv 5 cMul -> (...) 5 cRDiv */ \
1855 mData->mByteCode.pop_back(); \
1858 AddImmedOpcode(pending_immed); \
1860 AddFunctionOpcode(op); \
1862 if(do_reset) pending_immed = Value_t(1); \
1869 FP_FlushImmed(true);
1871 SkipSpace(function);
1872 function = CompileUnaryMinus(function);
1873 if(!function) return 0;
1874 AddFunctionOpcode(cMod);
1878 if(c != '*' && c != '/') break;
1880 bool safe_cumulation = (c == '*' || !IsIntType<Value_t>::result);
1881 if(!safe_cumulation)
1883 FP_FlushImmed(true);
1887 SkipSpace(function);
1888 if(mData->mByteCode.back() == cImmed
1890 || mData->mImmed.back() == Value_t(1)))
1892 // 5 (...) cMul --> (...) ||| 5 cMul
1893 // 5 (...) cDiv --> (...) cInv ||| 5 cMul
1895 pending_immed *= mData->mImmed.back();
1896 mData->mImmed.pop_back();
1897 mData->mByteCode.pop_back();
1899 function = CompileUnaryMinus(function);
1900 if(!function) return 0;
1902 AddFunctionOpcode(cInv);
1906 && mData->mByteCode.back() == cMul
1907 && mData->mByteCode[mData->mByteCode.size()-2] == cImmed)
1909 // (:::) 5 cMul (...) cMul -> (:::) (...) cMul ||| 5 cMul
1910 // (:::) 5 cMul (...) cDiv -> (:::) (...) cDiv ||| 5 cMul
1912 pending_immed *= mData->mImmed.back();
1913 mData->mImmed.pop_back();
1914 mData->mByteCode.pop_back();
1915 mData->mByteCode.pop_back();
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)
1923 // (:::) cInv (...) cMul -> (:::) (...) cRDiv
1924 // (:::) cInv (...) cDiv -> (:::) (...) cMul cInv
1926 mData->mByteCode.pop_back();
1927 lhs_inverted = true;
1929 function = CompileUnaryMinus(function);
1930 if(!function) return 0;
1932 && mData->mByteCode.back() == cMul
1933 && mData->mByteCode[mData->mByteCode.size()-2] == cImmed)
1935 // (:::) (...) 5 cMul cMul -> (:::) (...) cMul ||| 5 Mul
1936 // (:::) (...) 5 cMul cDiv -> (:::) (...) cDiv ||| /5 Mul
1939 pending_immed *= mData->mImmed.back();
1941 pending_immed /= mData->mImmed.back();
1942 mData->mImmed.pop_back();
1943 mData->mByteCode.pop_back();
1944 mData->mByteCode.pop_back();
1948 && mData->mByteCode.back() == cRDiv
1949 && mData->mByteCode[mData->mByteCode.size()-2] == cImmed)
1951 // (:::) (...) 5 cRDiv cMul -> (:::) (...) cDiv ||| 5 cMul
1952 // (:::) (...) 5 cRDiv cDiv -> (:::) (...) cMul ||| /5 cMul
1955 { c = '/'; pending_immed *= mData->mImmed.back(); }
1957 { c = '*'; pending_immed /= mData->mImmed.back(); }
1958 mData->mImmed.pop_back();
1959 mData->mByteCode.pop_back();
1960 mData->mByteCode.pop_back();
1962 if(!lhs_inverted) // if (/x/y) was changed to /(x*y), add missing cInv
1964 AddFunctionOpcode(c == '*' ? cMul : cDiv);
1967 else if(c == '*') // (/x)*y -> rdiv(x,y)
1969 AddFunctionOpcode(cRDiv);
1972 else // (/x)/y -> /(x*y)
1974 AddFunctionOpcode(cMul);
1976 AddFunctionOpcode(cInv);
1979 FP_FlushImmed(false);
1980 #undef FP_FlushImmed
1984 template<typename Value_t>
1986 FunctionParserBase<Value_t>::CompileAddition(const char* function)
1988 function = CompileMult(function);
1989 if(!function) return 0;
1991 Value_t pending_immed(0);
1992 #define FP_FlushImmed(do_reset) \
1993 if(pending_immed != Value_t(0)) \
1995 unsigned op = cAdd; \
1996 if(mData->mByteCode.back() == cNeg) \
1998 /* (...) cNeg 5 cAdd -> (...) 5 cRSub */ \
2000 mData->mByteCode.pop_back(); \
2003 AddImmedOpcode(pending_immed); \
2005 AddFunctionOpcode(op); \
2007 if(do_reset) pending_immed = Value_t(0); \
2012 if(c != '+' && c != '-') break;
2014 SkipSpace(function);
2015 if(mData->mByteCode.back() == cImmed)
2017 // 5 (...) cAdd --> (...) ||| 5 cAdd
2018 // 5 (...) cSub --> (...) cNeg ||| 5 cAdd
2020 pending_immed += mData->mImmed.back();
2021 mData->mImmed.pop_back();
2022 mData->mByteCode.pop_back();
2024 function = CompileMult(function);
2025 if(!function) return 0;
2027 AddFunctionOpcode(cNeg);
2030 if(mData->mByteCode.back() == cAdd
2031 && mData->mByteCode[mData->mByteCode.size()-2] == cImmed)
2033 // (:::) 5 cAdd (...) cAdd -> (:::) (...) cAdd ||| 5 cAdd
2034 // (:::) 5 cAdd (...) cSub -> (:::) (...) cSub ||| 5 cAdd
2036 pending_immed += mData->mImmed.back();
2037 mData->mImmed.pop_back();
2038 mData->mByteCode.pop_back();
2039 mData->mByteCode.pop_back();
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)
2046 // (:::) cNeg (...) cAdd -> (:::) (...) cRSub
2047 // (:::) cNeg (...) cSub -> (:::) (...) cAdd cNeg
2049 mData->mByteCode.pop_back();
2052 function = CompileMult(function);
2053 if(!function) return 0;
2054 if(mData->mByteCode.back() == cAdd
2055 && mData->mByteCode[mData->mByteCode.size()-2] == cImmed)
2057 // (:::) (...) 5 cAdd cAdd -> (:::) (...) cAdd ||| 5 Add
2058 // (:::) (...) 5 cAdd cSub -> (:::) (...) cSub ||| -5 Add
2061 pending_immed += mData->mImmed.back();
2063 pending_immed -= mData->mImmed.back();
2064 mData->mImmed.pop_back();
2065 mData->mByteCode.pop_back();
2066 mData->mByteCode.pop_back();
2069 if(mData->mByteCode.back() == cRSub
2070 && mData->mByteCode[mData->mByteCode.size()-2] == cImmed)
2072 // (:::) (...) 5 cRSub cAdd -> (:::) (...) cSub ||| 5 cAdd
2073 // (:::) (...) 5 cRSub cSub -> (:::) (...) cAdd ||| -5 cAdd
2076 { c = '-'; pending_immed += mData->mImmed.back(); }
2078 { c = '+'; pending_immed -= mData->mImmed.back(); }
2079 mData->mImmed.pop_back();
2080 mData->mByteCode.pop_back();
2081 mData->mByteCode.pop_back();
2083 if(!lhs_negated) // if (-x-y) was changed to -(x+y), add missing cNeg
2085 AddFunctionOpcode(c == '+' ? cAdd : cSub);
2088 else if(c == '+') // (-x)+y -> rsub(x,y)
2090 AddFunctionOpcode(cRSub);
2093 else // (-x)-y -> -(x+y)
2095 AddFunctionOpcode(cAdd);
2097 AddFunctionOpcode(cNeg);
2100 FP_FlushImmed(false);
2101 #undef FP_FlushImmed
2105 template<typename Value_t>
2107 FunctionParserBase<Value_t>::CompileComparison(const char* function)
2112 function = CompileAddition(function);
2113 if(!function) return 0;
2117 AddFunctionOpcode(op);
2123 ++function; op = cEqual; break;
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
2131 if(function[1] == '=')
2132 { function += 2; op = cLessOrEq; break; }
2133 ++function; op = cLess; break;
2135 if(function[1] == '=')
2136 { function += 2; op = cGreaterOrEq; break; }
2137 ++function; op = cGreater; break;
2138 default: return function;
2140 SkipSpace(function);
2145 template<typename Value_t>
2146 inline const char* FunctionParserBase<Value_t>::CompileAnd(const char* function)
2151 function = CompileComparison(function);
2152 if(!function) return 0;
2156 if(mData->mByteCode.back() == cNotNot) mData->mByteCode.pop_back();
2158 AddFunctionOpcode(cAnd);
2161 if(*function != '&') break;
2163 SkipSpace(function);
2164 param0end = mData->mByteCode.size();
2169 template<typename Value_t>
2170 const char* FunctionParserBase<Value_t>::CompileExpression(const char* function)
2175 SkipSpace(function);
2176 function = CompileAnd(function);
2177 if(!function) return 0;
2181 if(mData->mByteCode.back() == cNotNot) mData->mByteCode.pop_back();
2183 AddFunctionOpcode(cOr);
2186 if(*function != '|') break;
2188 param0end = mData->mByteCode.size();
2193 template<typename Value_t>
2194 const char* FunctionParserBase<Value_t>::Compile(const char* function)
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))
2203 typename Data::InlineVariable inlineVar =
2204 { NamePtr(function, nameLength), 0 };
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())
2211 const char* function2 = function + nameLength;
2212 SkipSpace(function2);
2214 // Check if ":=" follows the unknown identifier:
2215 if(function2[0] == ':' && function2[1] == '=')
2217 // Parse the expression that follows and create the
2219 function2 = CompileExpression(function2 + 2);
2220 if(!function2) return 0;
2221 if(*function2 != ';') return function2;
2223 inlineVar.mFetchIndex = mStackPtr - 1;
2224 mData->mInlineVarNames.push_back(inlineVar);
2226 // Continue with the expression after the ';':
2227 function = function2 + 1;
2235 return CompileExpression(function);
2238 template<typename Value_t> template<bool PutFlag>
2239 inline void FunctionParserBase<Value_t>::PushOpcodeParam
2242 mData->mByteCode.push_back(value | (PutFlag ? 0x80000000U : 0u));
2243 if(PutFlag) mHasByteCodeFlags = true;
2246 template<typename Value_t> template<bool PutFlag>
2247 inline void FunctionParserBase<Value_t>::PutOpcodeParamAt
2248 (unsigned value, unsigned offset)
2250 mData->mByteCode[offset] = value | (PutFlag ? 0x80000000U : 0u);
2251 if(PutFlag) mHasByteCodeFlags = true;
2254 //===========================================================================
2255 // Function evaluation
2256 //===========================================================================
2257 template<typename Value_t>
2258 Value_t FunctionParserBase<Value_t>::Eval(const Value_t* Vars)
2260 if(mParseErrorType != FP_NO_ERROR) return Value_t(0);
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());
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.
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.
2276 Value_t* const Stack = (Value_t*)alloca(mData->mStackSize*sizeof(Value_t));
2278 /* Allocate from the heap. Ensure that it is freed
2279 * automatically no matter which exit path is taken.
2284 ~AutoDealloc() { delete[] ptr; }
2285 } AutoDeallocStack = { new Value_t[mData->mStackSize] };
2286 Value_t*& Stack = AutoDeallocStack.ptr;
2289 /* No thread safety, so use a global stack. */
2290 std::vector<Value_t>& Stack = mData->mStack;
2293 for(IP=0; IP<byteCodeSize; ++IP)
2295 switch(byteCode[IP])
2298 case cAbs: Stack[SP] = fp_abs(Stack[SP]); break;
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); }
2305 Stack[SP] = fp_acos(Stack[SP]); break;
2308 # ifndef FP_NO_EVALUATION_CHECKS
2309 if(Stack[SP] < Value_t(1))
2310 { mEvalErrorType=4; return Value_t(0); }
2312 Stack[SP] = fp_acosh(Stack[SP]); break;
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); }
2319 Stack[SP] = fp_asin(Stack[SP]); break;
2321 case cAsinh: Stack[SP] = fp_asinh(Stack[SP]); break;
2323 case cAtan: Stack[SP] = fp_atan(Stack[SP]); break;
2325 case cAtan2: Stack[SP-1] = fp_atan2(Stack[SP-1], Stack[SP]);
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); }
2333 Stack[SP] = fp_atanh(Stack[SP]); break;
2335 case cCbrt: Stack[SP] = fp_cbrt(Stack[SP]); break;
2337 case cCeil: Stack[SP] = fp_ceil(Stack[SP]); break;
2339 case cCos: Stack[SP] = fp_cos(Stack[SP]); break;
2341 case cCosh: Stack[SP] = fp_cosh(Stack[SP]); break;
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); }
2349 Stack[SP] = Value_t(1)/t; break;
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); }
2358 Stack[SP] = Value_t(1)/s; break;
2362 # ifndef FP_DISABLE_EVAL
2365 const unsigned varAmount = mData->mVariablesAmount;
2366 Value_t retVal = Value_t(0);
2367 if(mEvalRecursionLevel == FP_EVAL_MAX_REC_LEVEL)
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.
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);
2384 /* Thread safety mode. We don't need to
2385 * worry about stack reusing here, because
2386 * each instance of Eval() will allocate
2389 retVal = Eval(&Stack[SP - varAmount + 1]);
2391 --mEvalRecursionLevel;
2399 case cExp: Stack[SP] = fp_exp(Stack[SP]); break;
2401 case cExp2: Stack[SP] = fp_exp2(Stack[SP]); break;
2403 case cFloor: Stack[SP] = fp_floor(Stack[SP]); break;
2406 Stack[SP-1] = fp_hypot(Stack[SP-1], Stack[SP]);
2410 if(fp_truth(Stack[SP--]))
2414 const unsigned* buf = &byteCode[IP+1];
2420 case cInt: Stack[SP] = fp_int(Stack[SP]); break;
2423 # ifndef FP_NO_EVALUATION_CHECKS
2424 if(!(Stack[SP] > Value_t(0)))
2425 { mEvalErrorType=3; return Value_t(0); }
2427 Stack[SP] = fp_log(Stack[SP]); break;
2430 # ifndef FP_NO_EVALUATION_CHECKS
2431 if(!(Stack[SP] > Value_t(0)))
2432 { mEvalErrorType=3; return Value_t(0); }
2434 Stack[SP] = fp_log10(Stack[SP]);
2438 # ifndef FP_NO_EVALUATION_CHECKS
2439 if(!(Stack[SP] > Value_t(0)))
2440 { mEvalErrorType=3; return Value_t(0); }
2442 Stack[SP] = fp_log2(Stack[SP]);
2445 case cMax: Stack[SP-1] = fp_max(Stack[SP-1], Stack[SP]);
2448 case cMin: Stack[SP-1] = fp_min(Stack[SP-1], Stack[SP]);
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); }
2464 Stack[SP-1] = fp_pow(Stack[SP-1], Stack[SP]);
2467 case cTrunc: Stack[SP] = fp_trunc(Stack[SP]); break;
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); }
2475 Stack[SP] = Value_t(1)/c; break;
2478 case cSin: Stack[SP] = fp_sin(Stack[SP]); break;
2480 case cSinh: Stack[SP] = fp_sinh(Stack[SP]); break;
2483 # ifndef FP_NO_EVALUATION_CHECKS
2484 if(Stack[SP] < Value_t(0)) { mEvalErrorType=2; return Value_t(0); }
2486 Stack[SP] = fp_sqrt(Stack[SP]); break;
2488 case cTan: Stack[SP] = fp_tan(Stack[SP]); break;
2490 case cTanh: Stack[SP] = fp_tanh(Stack[SP]); break;
2494 case cImmed: Stack[++SP] = immed[DP++]; break;
2498 const unsigned* buf = &byteCode[IP+1];
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;
2511 # ifndef FP_NO_EVALUATION_CHECKS
2512 if(Stack[SP] == Value_t(0))
2513 { mEvalErrorType=1; return Value_t(0); }
2515 if(IsIntType<Value_t>::result && Stack[SP] == Value_t(0))
2516 { mEvalErrorType=1; return Value_t(0); }
2518 Stack[SP-1] /= Stack[SP]; --SP; break;
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]);
2527 Stack[SP-1] = fp_equal(Stack[SP-1], Stack[SP]);
2531 Stack[SP-1] = fp_nequal(Stack[SP-1], Stack[SP]);
2535 Stack[SP-1] = fp_less(Stack[SP-1], Stack[SP]);
2539 Stack[SP-1] = fp_lessOrEq(Stack[SP-1], Stack[SP]);
2543 Stack[SP-1] = fp_less(Stack[SP], Stack[SP-1]);
2547 Stack[SP-1] = fp_lessOrEq(Stack[SP], Stack[SP-1]);
2550 case cNot: Stack[SP] = fp_not(Stack[SP]); break;
2552 case cNotNot: Stack[SP] = fp_notNot(Stack[SP]); break;
2555 Stack[SP-1] = fp_and(Stack[SP-1], Stack[SP]);
2559 Stack[SP-1] = fp_or(Stack[SP-1], Stack[SP]);
2562 // Degrees-radians conversion:
2563 case cDeg: Stack[SP] = RadiansToDegrees(Stack[SP]); break;
2564 case cRad: Stack[SP] = DegreesToRadians(Stack[SP]); break;
2566 // User-defined function calls:
2569 unsigned index = byteCode[++IP];
2570 unsigned params = mData->mFuncPtrs[index].mParams;
2572 mData->mFuncPtrs[index].mFuncPtr(&Stack[SP-params+1]);
2573 SP -= int(params)-1;
2580 unsigned index = byteCode[++IP];
2581 unsigned params = mData->mFuncParsers[index].mParams;
2583 mData->mFuncParsers[index].mParserPtr->Eval
2584 (&Stack[SP-params+1]);
2585 SP -= int(params)-1;
2588 mData->mFuncParsers[index].mParserPtr->EvalError();
2591 mEvalErrorType = error;
2600 unsigned stackOffs = byteCode[++IP];
2601 Stack[SP+1] = Stack[stackOffs]; ++SP;
2605 #ifdef FP_SUPPORT_OPTIMIZER
2608 unsigned stackOffs_target = byteCode[++IP];
2609 unsigned stackOffs_source = byteCode[++IP];
2610 Stack[stackOffs_target] = Stack[stackOffs_source];
2611 SP = stackOffs_target;
2616 # ifndef FP_NO_EVALUATION_CHECKS
2617 if(Stack[SP-1] <= Value_t(0))
2618 { mEvalErrorType=3; return Value_t(0); }
2620 Stack[SP-1] = fp_log2(Stack[SP-1]) * Stack[SP];
2625 #endif // FP_SUPPORT_OPTIMIZER
2628 fp_sinCos(Stack[SP], Stack[SP+1], Stack[SP]);
2633 Stack[SP] = fp_absNot(Stack[SP]); break;
2635 Stack[SP] = fp_absNotNot(Stack[SP]); break;
2637 Stack[SP-1] = fp_absAnd(Stack[SP-1], Stack[SP]);
2640 Stack[SP-1] = fp_absOr(Stack[SP-1], Stack[SP]);
2643 if(fp_absTruth(Stack[SP--]))
2647 const unsigned* buf = &byteCode[IP+1];
2653 case cDup: Stack[SP+1] = Stack[SP]; ++SP; break;
2656 # ifndef FP_NO_EVALUATION_CHECKS
2657 if(Stack[SP] == Value_t(0))
2658 { mEvalErrorType=1; return Value_t(0); }
2660 if(IsIntType<Value_t>::result && Stack[SP] == Value_t(0))
2661 { mEvalErrorType=1; return Value_t(0); }
2663 Stack[SP] = Value_t(1)/Stack[SP];
2667 Stack[SP] = Stack[SP]*Stack[SP];
2671 # ifndef FP_NO_EVALUATION_CHECKS
2672 if(Stack[SP-1] == Value_t(0))
2673 { mEvalErrorType=1; return Value_t(0); }
2675 if(IsIntType<Value_t>::result && Stack[SP-1] == Value_t(0))
2676 { mEvalErrorType=1; return Value_t(0); }
2678 Stack[SP-1] = Stack[SP] / Stack[SP-1]; --SP; break;
2680 case cRSub: Stack[SP-1] = Stack[SP] - Stack[SP-1]; --SP; break;
2683 # ifndef FP_NO_EVALUATION_CHECKS
2684 if(Stack[SP] == Value_t(0))
2685 { mEvalErrorType=1; return Value_t(0); }
2687 Stack[SP] = Value_t(1) / fp_sqrt(Stack[SP]); break;
2692 Stack[++SP] = Vars[byteCode[IP]-VarBegin];
2701 //===========================================================================
2702 // Variable deduction
2703 //===========================================================================
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,
2714 typedef std::set<std::string> StrSet;
2721 destVarString.clear();
2722 for(StrSet::iterator iter = varNames.begin();
2723 iter != varNames.end();
2726 if(iter != varNames.begin()) destVarString += ",";
2727 destVarString += *iter;
2731 fParser.Parse(funcStr, destVarString, useDegrees);
2732 if(index < 0) break;
2733 if(index == oldIndex) return index;
2735 unsigned nameLength = readIdentifier<Value_t>(funcStr + index);
2736 if(nameLength & 0x80000000U) return index;
2737 if(nameLength == 0) return index;
2739 varNames.insert(std::string(funcStr + index, nameLength));
2743 if(amountOfVariablesFound)
2744 *amountOfVariablesFound = int(varNames.size());
2747 destVarNames->assign(varNames.begin(), varNames.end());
2753 template<typename Value_t>
2754 int FunctionParserBase<Value_t>::ParseAndDeduceVariables
2755 (const std::string& function,
2756 int* amountOfVariablesFound,
2759 std::string varString;
2760 return deduceVariables(*this, function.c_str(), varString,
2761 amountOfVariablesFound, 0, useDegrees);
2764 template<typename Value_t>
2765 int FunctionParserBase<Value_t>::ParseAndDeduceVariables
2766 (const std::string& function,
2767 std::string& resultVarString,
2768 int* amountOfVariablesFound,
2771 std::string varString;
2773 deduceVariables(*this, function.c_str(), varString,
2774 amountOfVariablesFound, 0, useDegrees);
2775 if(index < 0) resultVarString = varString;
2779 template<typename Value_t>
2780 int FunctionParserBase<Value_t>::ParseAndDeduceVariables
2781 (const std::string& function,
2782 std::vector<std::string>& resultVars,
2785 std::string varString;
2786 std::vector<std::string> vars;
2788 deduceVariables(*this, function.c_str(), varString,
2789 0, &vars, useDegrees);
2790 if(index < 0) resultVars.swap(vars);
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)
2806 mData->mByteCode.assign(bytecode, bytecode + bytecodeAmount);
2807 mData->mImmed.assign(immed, immed + immedAmount);
2808 mData->mStackSize = stackSize;
2810 #ifndef FP_USE_THREAD_SAFE_EVAL
2811 mData->mStack.resize(stackSize);
2815 //===========================================================================
2817 //===========================================================================
2822 inline void printHex(std::ostream& dest, unsigned n)
2824 std::ios::fmtflags flags = dest.flags();
2825 dest.width(4); dest.fill('0'); std::hex(dest); //uppercase(dest);
2830 void padLine(std::ostringstream& dest, unsigned destLength)
2832 for(size_t currentLength = dest.str().length();
2833 currentLength < destLength;
2840 template<typename Value_t>
2841 std::string findName(const NamePtrsMap<Value_t>& nameMap,
2843 typename NameData<Value_t>::DataType type)
2845 for(typename NamePtrsMap<Value_t>::const_iterator
2846 iter = nameMap.begin();
2847 iter != nameMap.end();
2850 if(iter->second.type == type && iter->second.index == index)
2851 return std::string(iter->first.name,
2852 iter->first.name + iter->first.nameLength);
2857 const struct PowiMuliType
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) };
2867 template<typename Value_t>
2868 Value_t ParsePowiMuli(
2869 const PowiMuliType& opcodes,
2870 const std::vector<unsigned>& ByteCode, unsigned& IP,
2872 size_t factor_stack_base,
2873 std::vector<Value_t>& stack,
2876 Value_t result = Value_t(1);
2879 if(ByteCode[IP] == opcodes.opcode_square)
2881 if(!isInteger(result)) break;
2882 result *= Value_t(2);
2886 if(ByteCode[IP] == opcodes.opcode_invert)
2888 if(result < Value_t(0)) break;
2893 if(ByteCode[IP] == opcodes.opcode_half)
2895 if(result > Value_t(0) && isEvenInteger(result))
2897 if(isInteger(result * Value_t(0.5))) break;
2898 result *= Value_t(0.5);
2902 if(ByteCode[IP] == opcodes.opcode_invhalf)
2904 if(result > Value_t(0) && isEvenInteger(result))
2906 if(isInteger(result * Value_t(-0.5))) break;
2907 result *= Value_t(-0.5);
2912 unsigned dup_fetch_pos = IP;
2913 Value_t lhs = Value_t(1);
2915 if(ByteCode[IP] == cFetch)
2917 unsigned index = ByteCode[++IP];
2918 if(index < factor_stack_base
2919 || size_t(index-factor_stack_base) >= stack.size())
2921 // It wasn't a powi-fetch after all
2925 lhs = stack[index - factor_stack_base];
2926 // Note: ^This assumes that cFetch of recentmost
2927 // is always converted into cDup.
2931 if(ByteCode[IP] == cDup)
2937 stack.push_back(result);
2939 Value_t subexponent = ParsePowiMuli
2941 ByteCode, IP, limit,
2942 factor_stack_base, stack,
2944 if(IP >= limit && IgnoreExcess)
2945 return lhs*subexponent;
2946 if(IP >= limit || ByteCode[IP] != opcodes.opcode_cumulate)
2948 // It wasn't a powi-dup after all
2952 ++IP; // skip opcode_cumulate
2954 result += lhs*subexponent;
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)
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,
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)
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,
2990 std::pair<int,std::string> condition;
2991 std::pair<int,std::string> thenbranch;
2992 unsigned endif_location;
2994 IfInfo() : condition(), thenbranch(), endif_location() { }
2998 template<typename Value_t>
2999 void FunctionParserBase<Value_t>::PrintByteCode(std::ostream& dest,
3000 bool showExpression) const
3002 dest << "Size of stack: " << mData->mStackSize << "\n";
3004 std::ostringstream outputBuffer;
3005 std::ostream& output = (showExpression ? outputBuffer : dest);
3007 const std::vector<unsigned>& ByteCode = mData->mByteCode;
3008 const std::vector<Value_t>& Immed = mData->mImmed;
3010 std::vector<std::pair<int,std::string> > stack;
3011 std::vector<IfInfo> if_stack;
3013 for(unsigned IP = 0, DP = 0; IP <= ByteCode.size(); ++IP)
3015 after_powi_or_muli:;
3017 bool out_params = false;
3018 unsigned params = 2, produces = 1, opcode = 0;
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())
3028 printHex(output, IP);
3029 if(if_stack.back().endif_location == IP)
3030 output << ": ----- (phi)";
3032 output << ": ----- (phi+)";
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]);
3041 if_stack.pop_back();
3045 if(IP >= ByteCode.size()) break;
3046 opcode = ByteCode[IP];
3048 if(showExpression && (
3049 opcode == cSqr || opcode == cDup
3051 || opcode == cSqrt || opcode == cRSqrt
3055 unsigned changed_ip = IP;
3057 ParsePowiSequence<Value_t>
3058 (ByteCode, changed_ip,
3060 ? (unsigned)ByteCode.size()
3061 : if_stack.back().endif_location,
3063 std::string operation_prefix;
3064 std::ostringstream operation_value;
3068 if(opcode != cDup) goto not_powi_or_muli;
3070 ParseMuliSequence<Value_t>
3071 (ByteCode, changed_ip,
3073 ? (unsigned)ByteCode.size()
3074 : if_stack.back().endif_location,
3076 if(factor == Value_t(1) || factor == Value_t(-1))
3077 goto not_powi_or_muli;
3078 operation_prefix = "*";
3079 operation_value << factor;
3085 operation_prefix = "^";
3086 operation_value << exponent;
3089 //unsigned explanation_before = changed_ip-2;
3090 unsigned explanation_before = changed_ip-1;
3092 const char* explanation_prefix = "_";
3093 for(const unsigned first_ip = IP; IP < changed_ip; ++IP)
3095 printHex(output, IP);
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 = "=";
3105 switch(ByteCode[IP])
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;
3118 unsigned index = ByteCode[++IP];
3119 output << "cFetch(" << index << ")";
3124 padLine(outputBuffer, 20);
3126 if(IP >= explanation_before)
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 + ")";
3135 output << operation_prefix;
3136 output << operation_value.str();
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;
3153 dest << outputBuffer.str() << std::endl;
3154 outputBuffer.str("");
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;
3164 goto after_powi_or_muli;
3167 printHex(output, IP);
3174 unsigned label = ByteCode[IP+1]+1;
3176 printHex(output, label);
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();
3189 unsigned dp = ByteCode[IP+2];
3190 unsigned label = ByteCode[IP+1]+1;
3191 output << "jz_abs " << dp << ",";
3192 printHex(output, label);
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();
3206 unsigned dp = ByteCode[IP+2];
3207 unsigned label = ByteCode[IP+1]+1;
3209 if(!if_stack.empty() && !stack.empty())
3211 std::swap(if_stack.back().thenbranch, stack.back());
3212 if_stack.back().endif_location = label;
3216 output << "jump " << dp << ",";
3217 printHex(output, label);
3227 std::ostringstream buf;
3230 stack.push_back( std::make_pair(0, buf.str()) );
3232 output.precision(8);
3233 output << "push " << Immed[DP];
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);
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);
3264 if(OPCODE(opcode) < VarBegin)
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;
3288 #ifndef FP_DISABLE_EVAL
3289 case cEval: n = "eval"; params = mData->mVariablesAmount;
3294 unsigned index = ByteCode[++IP];
3295 if(showExpression && index < stack.size())
3296 stack.push_back(stack[index]);
3297 output << "cFetch(" << index << ")";
3301 #ifdef FP_SUPPORT_OPTIMIZER
3302 case cLog2by: n = "log2by"; params = 2; out_params = 1; break;
3305 size_t a = ByteCode[++IP];
3306 size_t b = ByteCode[++IP];
3307 if(showExpression && b < stack.size())
3309 std::pair<int, std::string> stacktop(0, "?");
3310 if(b < stack.size()) stacktop = stack[b];
3312 stack.push_back(stacktop);
3314 output << "cPopNMov(" << a << ", " << b << ")";
3319 output << "nop"; params = 0; produces = 0;
3326 std::pair<int, std::string> sin = stack.back();
3327 std::pair<int, std::string> cos(
3328 0, "cos(" + sin.second + ")");
3330 sin.second = "sin(" + sin.second + ")";
3332 stack.push_back(cos);
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;
3345 stack.push_back(stack.back());
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;
3357 n = Functions[opcode-cAbs].name;
3358 params = Functions[opcode-cAbs].params;
3359 out_params = params != 1;
3366 stack.push_back(std::make_pair(0,
3367 (findName(mData->mNamePtrs, opcode,
3368 NameData<Value_t>::VARIABLE))));
3370 output << "push Var" << opcode-VarBegin;
3375 if(produces) output << n;
3376 if(out_params) output << " (" << params << ")";
3379 padLine(outputBuffer, 20);
3383 std::ostringstream buf;
3384 const char *paramsep = ",", *suff = "";
3385 int prio = 0; bool commutative = false;
3388 case cIf: buf << "if("; suff = ")";
3390 case cAbsIf: buf << "if("; suff = ")";
3392 case cOr: prio = 6; paramsep = "|"; commutative = true;
3394 case cAnd: prio = 5; paramsep = "&"; commutative = true;
3396 case cAdd: prio = 4; paramsep = "+"; commutative = true;
3398 case cSub: prio = 4; paramsep = "-";
3400 case cMul: prio = 3; paramsep = "*"; commutative = true;
3402 case cDiv: prio = 3; paramsep = "/";
3404 case cPow: prio = 2; paramsep = "^";
3406 case cAbsOr: prio = 6; paramsep = "|"; commutative = true;
3408 case cAbsAnd: prio = 5; paramsep = "&"; commutative = true;
3410 case cSqr: prio = 2; suff = "^2";
3412 case cNeg: buf << "(-("; suff = "))";
3414 case cNot: buf << "(!("; suff = "))";
3416 default: buf << n << '('; suff = ")";
3419 const char* sep = "";
3420 for(unsigned a=0; a<params; ++a)
3423 if(stack.size() + a < params)
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 << ')';
3437 if(stack.size() >= params)
3438 stack.resize(stack.size() - params);
3442 stack.push_back(std::make_pair(prio, buf.str()));
3443 //if(n.size() <= 4 && !out_params) padLine(outputBuffer, 20);
3445 //padLine(outputBuffer, 20);
3447 if(((opcode == cIf || opcode == cAbsIf) && params != 3)
3449 #ifdef FP_SUPPORT_OPTIMIZER
3454 else if(stack.empty())
3457 output << '[' << (stack.size()-1) << ']'
3458 << stack.back().second;
3463 dest << outputBuffer.str() << std::endl;
3464 outputBuffer.str("");
3467 output << std::endl;
3474 #ifndef FP_SUPPORT_OPTIMIZER
3475 template<typename Value_t>
3476 void FunctionParserBase<Value_t>::Optimize()
3478 // Do nothing if no optimizations are supported.
3482 FUNCTIONPARSER_INSTANTIATE_TYPES