From aa7abb5c97c20b34f159886dfc523dd8198fef98 Mon Sep 17 00:00:00 2001 From: Ruben Undheim Date: Sun, 29 Jul 2018 19:05:33 +0000 Subject: New upstream version 0.0.34+ds.1 --- fparser/CMakeLists.txt | 29 - fparser/docs/fparser.html | 1863 ----- fparser/docs/gpl.txt | 674 -- fparser/docs/lgpl.txt | 165 - fparser/docs/style.css | 80 - fparser/examples/example.cc | 55 - fparser/examples/example2.cc | 85 - fparser/extrasrc/fp_identifier_parser.inc | 379 - fparser/extrasrc/fp_opcode_add.inc | 7696 ------------------ fparser/extrasrc/fpaux.hh | 1238 --- fparser/extrasrc/fptypes.hh | 288 - fparser/fparser.cc | 3800 --------- fparser/fparser.hh | 223 - fparser/fparser.pro | 35 - fparser/fparser_gmpint.hh | 15 - fparser/fparser_mpfr.hh | 15 - fparser/fpconfig.hh | 88 - fparser/fpoptimizer.cc | 11745 ---------------------------- fparser/mpfr/GmpInt.cc | 710 -- fparser/mpfr/GmpInt.hh | 148 - fparser/mpfr/MpfrFloat.cc | 976 --- fparser/mpfr/MpfrFloat.hh | 206 - 22 files changed, 30513 deletions(-) delete mode 100644 fparser/CMakeLists.txt delete mode 100644 fparser/docs/fparser.html delete mode 100644 fparser/docs/gpl.txt delete mode 100644 fparser/docs/lgpl.txt delete mode 100644 fparser/docs/style.css delete mode 100644 fparser/examples/example.cc delete mode 100644 fparser/examples/example2.cc delete mode 100644 fparser/extrasrc/fp_identifier_parser.inc delete mode 100644 fparser/extrasrc/fp_opcode_add.inc delete mode 100644 fparser/extrasrc/fpaux.hh delete mode 100644 fparser/extrasrc/fptypes.hh delete mode 100644 fparser/fparser.cc delete mode 100644 fparser/fparser.hh delete mode 100644 fparser/fparser.pro delete mode 100644 fparser/fparser_gmpint.hh delete mode 100644 fparser/fparser_mpfr.hh delete mode 100644 fparser/fpconfig.hh delete mode 100644 fparser/fpoptimizer.cc delete mode 100644 fparser/mpfr/GmpInt.cc delete mode 100644 fparser/mpfr/GmpInt.hh delete mode 100644 fparser/mpfr/MpfrFloat.cc delete mode 100644 fparser/mpfr/MpfrFloat.hh diff --git a/fparser/CMakeLists.txt b/fparser/CMakeLists.txt deleted file mode 100644 index 434218a..0000000 --- a/fparser/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ - -# define build type -SET( CMAKE_BUILD_TYPE Release ) - -PROJECT(fparser CXX) - -cmake_minimum_required(VERSION 2.8) - -# default -set(LIB_VERSION_MAJOR 4) -set(LIB_VERSION_MINOR 5) -set(LIB_VERSION_PATCH 1) -set(LIB_VERSION_STRING ${LIB_VERSION_MAJOR}.${LIB_VERSION_MINOR}.${LIB_VERSION_PATCH}) - -set(VERSION "v${LIB_VERSION_STRING}") - -#set(HEADERS fparser.hh fpconfig.hh fptypes.hh) -set(SOURCES fparser.cc fpoptimizer.cc) - -remove(CMAKE_CXX_FLAGS -Dfparser_EXPORTS) - -ADD_LIBRARY(fparser SHARED ${SOURCES}) - -set_target_properties(fparser PROPERTIES VERSION ${LIB_VERSION_STRING} SOVERSION ${LIB_VERSION_MAJOR}) - -INSTALL(TARGETS fparser DESTINATION lib${LIB_SUFFIX}) - -INSTALL(FILES fparser.hh DESTINATION include) - diff --git a/fparser/docs/fparser.html b/fparser/docs/fparser.html deleted file mode 100644 index ffc73f4..0000000 --- a/fparser/docs/fparser.html +++ /dev/null @@ -1,1863 +0,0 @@ - - - - - - Function Parser for C++ v4.5.1 : Documentation - - - -

Function Parser for C++ v4.5.1

- -

Authors: Juha Nieminen -(http://iki.fi/warp/), -Joel Yliluoma -(http://iki.fi/bisqwit/). - -

The usage license of this library is located at the end of this file. - -

Table of contents:

- - - - -

What's new

- -

What's new in v4.5.1 -

- -

What's new in v4.5 -

- - - - - -

Preface

- -

This C++ library offers a class which can be used to parse and evaluate a -mathematical function from a string (which might be eg. requested from the -user). The syntax of the function string is similar to mathematical expressions -written in C/C++ (the exact syntax is specified later in this document). -The function can then be evaluated with different values of variables. - -

For example, a function like "sin(sqrt(x*x+y*y))" can be -parsed from a string (either std::string or a C-style string) -and then evaluated with different values of x and y. -This library can be useful for evaluating user-inputted functions, or in -some cases interpreting mathematical expressions in a scripting language. - -

This library aims for maximum speed in both parsing and evaluation, while -keeping maximum portability. The library should compile and work with any -standard-conforming C++ compiler. - -

Different numerical types are supported: double, - float, long double, long int, - std::complex (of types double, - float and long double), - multiple-precision floating point numbers using the MPFR library, and - arbitrary precision integers using the GMP library. (Note that it's - not necessary for these two libraries to exist in the system in order - to use the Function Parser library with the other numerical types. Support - for these libraries is optionally compiled in using preprocessor settings.) - - - - -

Usage

- -

To use the FunctionParser class, you have to include -"fparser.hh" in your source code files which use the -FunctionParser class. - -

If you are going to use the MPFR version of the library, you need to -include "fparser_mpfr.hh". If you are going to use the GMP -version of the library, you need to include "fparser_gmpint.hh". -(Note that support for these special parser versions needs to be specified -with preprocessor macros. See the documentation -below for details.) - -

When compiling, you have to compile fparser.cc and -fpoptimizer.cc and link them to the main program. In many -developement environments it's enough to add those two files to your -current project (usually header files don't have to be added to the -project for the compilation to work). - -

If you are going to use the MPFR or the GMP versions of the library, -you also need to add mpfr/MpfrFloat.cc or -mpfr/GmpInt.cc files to your project, respectively. Otherwise -they should not be added to the project. - -

Note that part of the library source code is inside several -.inc files inside the extrasrc subdirectory -(these files contain auto-generated C++ code), provided in the library -package. These files are used by fparser.cc and don't need -to be added explicitly to the project in most IDEs (such as Visual Studio). -Basically, you don't need to do anything with these files, other than keep -them in the extrasrc subdirectory. - -

Simple usage example of the library: - -

-    FunctionParser fp;
-    fp.Parse("sqrt(x*x + y*y)", "x,y");
-    double variables[2] = { 1.5, 2.9 };
-    double result = fp.Eval(variables);
-
- - - -

Parser types

- -

Different versions of the function parser class are supported, using - different floating point or integral types for function evaluation. - -

All the classes other than the default one, FunctionParser, - need to be enabled at compile time by defining a preprocessor macro - (specified below) either in the fpconfig.hh file or your - compiler settings. (The reason for this is that every parser that is - included in the compilation process will make the compilation slower - and increase the size of the executable, so they are compiled only on - demand. Also, the GMP and MPFR versions of the parser require for those - libraries to be available, which is often not the case.) - -

Note that if you try to use the other class types without enabling them - with the correspondent preprocessor macro, you will get a linker error - (rather than a compiler error) because those classes will not have been - instantiated when the library was compiled. - -

Currently the Optimize() method works only for the - FunctionParser, FunctionParser_f and - FunctionParser_ld classes. For the other types it can be - called but it does nothing. - -

-

-

FunctionParser

-
-

This is the default class, which uses double as its - numerical type. This is the only class enabled by default. -

If you use some other type than this one, and you don't want this - version of the class compiled into the library, you can define the - preprocessor macro FP_DISABLE_DOUBLE_TYPE. -

- -

FunctionParser_f

-
-

This parser uses float as its numerical type. -

The FP_SUPPORT_FLOAT_TYPE preprocessor macro needs to be - defined for this class to be enabled. -

- -

FunctionParser_ld

-
-

This parser uses long double as its numerical type. -

The FP_SUPPORT_LONG_DOUBLE_TYPE preprocessor macro needs - to be defined for this class to be enabled. -

Note that the FP_USE_STRTOLD preprocessor macro should - also be defined when using this version of the parser if the compiler - supports the (C99) function strtold(). (See - documentation below.) -

- -

FunctionParser_li

-
-

This parser uses long int as its numerical type. -

The FP_SUPPORT_LONG_INT_TYPE preprocessor macro needs - to be defined for this class to be enabled. -

Note that this version of the class uses a reduced function syntax - with support only for functions which are feasible to be used with - integral types (namely abs(), eval(), - if(), min() and max(), besides - basic arithmetic operators, except for the power operator). -

- -

FunctionParser_cd, FunctionParser_cf, - FunctionParser_cld

-
-

These parsers use std::complex<double>, - std::complex<float> and - std::complex<long double> as their numerical type, - respectively. -

The preprocessor macros to enable them are - FP_SUPPORT_COMPLEX_DOUBLE_TYPE, - FP_SUPPORT_COMPLEX_FLOAT_TYPE and - FP_SUPPORT_COMPLEX_LONG_DOUBLE_TYPE. -

If FunctionParser_cld is used, the - FP_USE_STRTOLD macro should also be defined if the compiler - supports the strtold() function. -

- -

FunctionParser_mpfr

-
-

This parser uses MpfrFloat as its numerical type. -

The FP_SUPPORT_MPFR_FLOAT_TYPE preprocessor macro needs - to be defined for this class to be enabled. -

Note that to use this version of the parser, - "fparser_mpfr.hh" needs to be included. -

MpfrFloat is an auxiliary class which uses the MPFR - library for multiple-precision floating point numbers. The class - behaves largely like a floating point type, and is declared in the - mpfr/MpfrFloat.hh file (see that file for info about - the public interface of the class). -

If this class is enabled, mpfr/MpfrFloat.cc - needs to be compiled into the project, as well as the GMP and MPFR - libraries. (With the gcc compiler this means using the linker options - "-lgmp -lmpfr".) -

- -

FunctionParser_gmpint

-
-

This parser uses GmpInt as its numerical type. -

The FP_SUPPORT_GMP_INT_TYPE preprocessor macro needs - to be defined for this class to be enabled. -

Note that to use this version of the parser, - "fparser_gmpint.hh" needs to be included. -

GmpInt is an auxiliary class which uses the GMP - library for arbitrary-precision integer numbers. The class - behaves largely like an integer type, and is declared in the - mpfr/GmpInt.hh file (see that file for info about - the public interface of the class). -

If this class is enabled, mpfr/GmpInt.cc - needs to be compiled into the project, as well as the GMP library. -

This version of the class also uses a reduced version of the syntax, - like the long int version. -

Note: Since there's no upper limit to the size of GMP - integers, this version of the class should be used with care in - situations where malicious users might be able to exploit it to - make the program run out of memory. An example of this would be - a server-side application usable through the WWW. -

-
- -

Note that these different classes are completely independent and - instances of different classes cannot be given to each other using the - AddFunction() method. Only objects of the same type can - be given to that method. - -

The rest of the documentation assumes that FunctionParser - (which uses the double type) is used. The usage of the other - classes is identical except that double is replaced with the - correspondent type used by that class. (In other words, whenever the - rest of this documentation uses the type keyword 'double', - the correspondent type should be used instead, when using another version - of the class.) - - - -

Configuring the compilation

- -

There is a set of precompiler options in the fpconfig.hh file -which can be used for setting certain features on or off. All of these options -can also be specified from the outside, using precompiler settings (eg. the --D option in gcc), and thus it's not necessary to modify this -file. - -

-

FP_USE_STRTOLD : (Default off)

-

If FunctionParser_ld or FunctionParser_cld - are used, this preprocessor macro should be defined if the compiler - supports the (C99) function strtold(). If not, then numeric - literals will be parsed with double precision only, which in most - systems is less accurate than long double precision, which will cause - small rounding errors. (This setting has no effect on the other parser - types.) Note that strtold() will also be automatically used - if __cplusplus indicates that C++11 is in use. -

- -

FP_SUPPORT_CPLUSPLUS11_MATH_FUNCS : (Default off)

-

Use C++11 math functions where applicable. (These are ostensibly - faster than the equivalent formulas using C++98 math functions.) Note - that not all compilers support these functions (even if they otherwise - support C++11.) - -

FP_SUPPORT_OPTIMIZER : (Default on)

-

If you are not going to use the Optimize() method, you - can comment this line out to speed-up the compilation a bit, as - well as making the binary a bit smaller. (Optimize() can - still be called, but it will not do anything.) - -

You can also disable the optimizer by specifying the - FP_NO_SUPPORT_OPTIMIZER precompiler constant in your - compiler settings. -

- -

FP_USE_THREAD_SAFE_EVAL : (Default off)

-

Define this precompiler constant to make Eval() - thread-safe. Refer to the thread safety - section later in this document for more information. - Note that defining this may make Eval() slightly slower. -

Also note that the MPFR and GMP versions of the library cannot be - made thread-safe, and thus this setting has no effect on them. -

- -

FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA : (Default off)

-

This is like the previous, but makes Eval() use the - alloca() function (instead of std::vector). - This will make it faster, but the alloca() - function is not standard and thus not supported by all compilers. -

-
- - - - -

Copying and assignment

- -

The class implements a safe copy constructor and assignment operator. - -

It uses the copy-on-write technique for efficiency. This means that - when copying or assigning a FunctionParser instance, the internal data - (which in some cases can be quite lengthy) is not immediately copied - but only when the contents of the copy (or the original) are changed. - -

This means that copying/assigning is a very fast operation, and if - the copies are never modified then actual data copying never happens - either. - -

The Eval() and EvalError() methods of the -copy can be called without the internal data being copied. - -

Calling Parse(), Optimize() or the user-defined -constant/function adding methods will cause a deep-copy. - - - - -

Short descriptions of FunctionParser methods

- -
-int Parse(const std::string& Function, const std::string& Vars,
-          bool useDegrees = false);
-
-int Parse(const char* Function, const std::string& Vars,
-          bool useDegrees = false);
-
- -

Parses the given function and compiles it to internal format. - Return value is -1 if successful, else the index value to the location - of the error. - -


-
-void setDelimiterChar(char);
-
- -

Sets an ending delimiter character for the function string. (See the - long description for more details.) - -


-
-static double epsilon();
-static void setEpsilon(double);
-
- -

Setter and getter for the epsilon value used with comparison operators. - -


-
-const char* ErrorMsg(void) const;
-
- -

Returns an error message corresponding to the error in -Parse(), or an empty string if no such error occurred. - -


-
-ParseErrorType GetParseErrorType() const;
-
- -

Returns the type of parsing error which occurred. Possible return types - are described in the long description. - -


-
-double Eval(const double* Vars);
-
- -

Evaluates the function given to Parse(). - -


-
-int EvalError(void) const;
-
- -

Returns 0 if no error happened in the previous call to -Eval(), else an error code >0. - -


-
-void Optimize();
-
- -

Tries to optimize the bytecode for faster evaluation. - -


-
-bool AddConstant(const std::string& name, double value);
-
- -

Add a constant to the parser. Returns false if the name of -the constant is invalid, else true. - -


-
-bool AddUnit(const std::string& name, double value);
-
- -

Add a new unit to the parser. Returns false if the name of -the unit is invalid, else true. - -


-
-bool AddFunction(const std::string& name,
-                 double (*functionPtr)(const double*),
-                 unsigned paramsAmount);
-
- -

Add a user-defined function to the parser (as a function pointer). -Returns false if the name of the function is invalid, else -true. - -


-
-bool AddFunction(const std::string& name, FunctionParser&);
-
- -

Add a user-defined function to the parser (as a FunctionParser -instance). Returns false if the name of the function is invalid, -else true. - -


-
-bool RemoveIdentifier(const std::string& name);
-
- -

Removes the constant, unit or user-defined function with the specified -name from the parser. - -


-
-int ParseAndDeduceVariables(const std::string& function,
-                            int* amountOfVariablesFound = 0,
-                            bool useDegrees = false);
-int ParseAndDeduceVariables(const std::string& function,
-                            std::string& resultVarString,
-                            int* amountOfVariablesFound = 0,
-                            bool useDegrees = false);
-int ParseAndDeduceVariables(const std::string& function,
-                            std::vector<std::string>& resultVars,
-                            bool useDegrees = false);
-
- -

Like Parse(), but the variables in the function are deduced -automatically. The amount of found variables and the variable names themselves -are returned by the different versions of the function. - - - -

Long descriptions of FunctionParser methods

- -
- -
-int Parse(const std::string& Function, const std::string& Vars,
-          bool useDegrees = false);
-
-int Parse(const char* Function, const std::string& Vars,
-          bool useDegrees = false);
-
- -

Parses the given function (and compiles it to internal format). -Destroys previous function. Following calls to Eval() will evaluate -the given function. - -

The strings given as parameters are not needed anymore after parsing. - -

Parameters: - - - - - - - - - - - -
FunctionString containing the function to parse.
VarsString containing the variable names, separated by commas.
- Eg. "x,y", "VarX,VarY,VarZ,n" or - "x1,x2,x3,x4,__VAR__". -
useDegrees(Optional.) Whether to use degrees or radians in - trigonometric functions. (Default: radians)
- -

If a char* is given as the Function parameter, -it must be a null-terminated string. - -

Variables can have any size and they are case sensitive (ie. -"var", "VAR" and "Var" are -different variable names). Letters, digits, underscores and -UTF8-encoded characters can be used in variable names, but the name of -a variable can't begin with a digit. Each variable name can appear only -once in the 'Vars' string. Function names are not legal -variable names. - -

Using longer variable names causes no overhead whatsoever to the -Eval() method, so it's completely safe to use variable names -of any size. - -

The third, optional parameter specifies whether angles should be - interpreted as radians or degrees in trigonometrical functions. - If not specified, the default value is radians. - -

Return values: - -

- -

Example: parser.Parse("3*x+y", "x,y"); - - -


- -
-void setDelimiterChar(char);
-
- -

By default the parser expects the entire function string to be valid -(ie. the entire contents of the given std::string, or a C string -ending in the null character '\0'). - -

If a delimiter character is specified with this function, then if it's -encountered at the outermost parsing level by the Parse() -function, and the input function has been valid so far, Parse() -will return an index to this character inside the input string, but rather -than set an error code, FP_NO_ERROR will be set. - -

The idea is that this can be used to more easily parse functions which -are embedded inside larger strings, containing surrounding data, without -having to explicitly extract the function to a separate string. - -

For example, suppose you are writing an interpreter for a scripting - language, which can have commands like this: - -

let MyFunction(x,y) = { sin(x*x+y*y) } // A 2-dimensional function - -

Normally when parsing such a line you would have to extract the part -inside the curly brackets into a separate string and parse it that way. -With this feature what you can do instead is to set '}' as -the delimiter character and then simply give a pointer to the character -which comes after the '{'. If all goes well, the -Parse() function will return an index to the '}' -character (from the given starting point) and GetParseErrorType() -will return FP_NO_ERROR. You can use the return -value (if it's not -1) to jump forward in the string to the -delimiter character. - -

Note that a null character ('\0') or the end of the -std::string (if one was given) will still be a valid end of -the function string even if a delimiter character was specified. (In this -case Parse() will return -1 if there was no error, -as usual.) - -

Also note that the delimiter character cannot be any valid operator -or alphanumeric (including the underscore) character, nor the other -characters defined in the function syntax. It must be a character not -supported by the function parser (such as '}', -'"', ']', etc). - - -


- -
-static double epsilon();
-static void setEpsilon(double);
-
- -

Comparison operators (for the non-integral versions of the parser) use an -epsilon value to account for floating point calculation rounding errors. -This epsilon value can be set and read with these functions. (Note that the -specified value will be used by all instances of FunctionParser.) If not -specified, the default values are: - -

- - -
- -
-const char* ErrorMsg(void) const;
-
- -

Returns a pointer to an error message string corresponding to the error -caused by Parse() (you can use this to print the proper error -message to the user). If no such error has occurred, returns an empty string. - - -


- -
-ParseErrorType GetParseErrorType() const;
-
- -

Returns the type of parse error which occurred. - -

This method can be used to get the error type if ErrorMsg() -is not enough for printing the error message. In other words, this can be -used for printing customized error messages (eg. in another language). -If the default error messages suffice, then this method doesn't need -to be called. - -FunctionParser::ParseErrorType is an enumerated type inside -the class (ie. its values are accessed like -"FunctionParser::SYNTAX_ERROR"). - -

The possible values for FunctionParser::ParseErrorType are listed below, -along with their equivalent error message returned by the -ErrorMsg() method: - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FP_NO_ERRORIf no error occurred in the previous call to Parse().
SYNTAX_ERROR"Syntax error"
MISM_PARENTH"Mismatched parenthesis"
MISSING_PARENTH"Missing ')'"
EMPTY_PARENTH"Empty parentheses"
EXPECT_OPERATOR"Syntax error: Operator expected"
OUT_OF_MEMORY"Not enough memory"
UNEXPECTED_ERROR"An unexpected error occurred. Please make a full bug report to the - author"
INVALID_VARS"Syntax error in parameter 'Vars' given to FunctionParser::Parse()"
ILL_PARAMS_AMOUNT"Illegal number of parameters to function"
PREMATURE_EOS"Syntax error: Premature end of string"
EXPECT_PARENTH_FUNC"Syntax error: Expecting ( after function"
UNKNOWN_IDENTIFIER"Syntax error: Unknown identifier"
NO_FUNCTION_PARSED_YET"(No function has been parsed yet)"
- - -


- -
-double Eval(const double* Vars);
-
- -

Evaluates the function given to Parse(). -The array given as parameter must contain the same amount of values as -the amount of variables given to Parse(). Each value corresponds -to each variable, in the same order. - -

Return values: -

- -

Example: - -

double Vars[] = {1, -2.5};
-double result = parser.Eval(Vars); - - -


- -
-int EvalError(void) const;
-
- -

Used to test if the call to Eval() succeeded. - -

Return values: - -

If there was no error in the previous call to Eval(), -returns 0, else returns a positive value as follows: -

- - -
- -
-void Optimize();
-
- -

This method can be called after calling the Parse() method. -It will try to simplify the internal bytecode so that it will evaluate faster -(it tries to reduce the amount of opcodes in the bytecode). - -

For example, the bytecode for the function "5+x*y-25*4/8" will -be reduced to a bytecode equivalent to the function "x*y-7.5" (the -original 11 opcodes will be reduced to 5). Besides calculating constant -expressions (like in the example), it also performs other types of -simplifications with variable and function expressions. - -

This method is quite slow and the decision of whether to use it or -not should depend on the type of application. If a function is parsed -once and evaluated millions of times, then calling Optimize() -may speed-up noticeably. However, if there are tons of functions to parse -and each one is evaluated once or just a few times, then calling -Optimize() will only slow down the program. - -

Also, if the original function is expected to be optimal, then calling -Optimize() would be useless. - -

Note: Currently this method does not make any checks (like -Eval() does) and thus things like "1/0" will cause -undefined behaviour. (On the other hand, if such expression is given to the -parser, Eval() will always give an error code, no matter what -the parameters.) If caching this type of errors is important, a work-around -is to call Eval() once before calling Optimize() -and checking EvalError(). - -

If the destination application is not going to use this method, -the compiler constant FP_SUPPORT_OPTIMIZER can be undefined in -fpconfig.hh to make the library smaller (Optimize() -can still be called, but it will not do anything). - -

(If you are interested in seeing how this method optimizes the opcode, -you can call the PrintByteCode() method before and after the -call to Optimize() to see the difference.) - - -


- -
-bool AddConstant(const std::string& name, double value);
-
- -

This method can be used to add constants to the parser. Syntactically - constants are identical to variables (ie. they follow the same naming - rules and they can be used in the function string in the same way as - variables), but internally constants are directly replaced with their - value at parse time. - -

Constants used by a function must be added before calling -Parse() for that function. Constants are preserved between -Parse() calls in the current FunctionParser instance, so -they don't need to be added but once. (If you use the same constant in -several instances of FunctionParser, you will need to add it to all the -instances separately.) - -

Constants can be added at any time and the value of old constants can -be changed, but new additions and changes will only have effect the next -time Parse() is called. (That is, changing the value of a constant -after calling Parse() and before calling Eval() -will have no effect.) - -

The return value will be false if the 'name' of -the constant was illegal, else true. If the name was illegal, -the method does nothing. - -

Example: parser.AddConstant("pi", 3.1415926535897932); - -

Now for example parser.Parse("x*pi", "x"); will be identical -to the call parser.Parse("x*3.1415926535897932", "x"); - - -


- -
-bool AddUnit(const std::string& name, double value);
-
- -

In some applications it is desirable to have units of measurement. -A typical example is an application which creates a page layout to be -printed. When printing, distances are usually measured in points -(defined by the resolution of the printer). However, it is often more -useful for the user to be able to specify measurements in other units -such as centimeters or inches. - -

A unit is simply a value by which the preceding element is multiplied. -For example, if the printing has been set up to 300 DPI, one inch is -then 300 points (dots). Thus saying eg. "5in" is the same as saying -"5*300" or "1500" (assuming "in" has -been added as a unit with the value 300). - -

Note that units are slightly different from a multiplication in -that they have a higher precedence than any other operator (except -parentheses). Thus for example "5/2in" is parsed as -"5/(2*300)". -(If 5/2 inches is what one wants, it has to be written "(5/2)in".) - -

You can use the AddUnit() method to add a new unit. The -unit can then be used after any element in the function (and will work as -a multiplier for that element). An element is a float literal, a constant, -a variable, a function or any expression in parentheses. When the element -is not a float literal nor an expression in parentheses, there has to naturally -be at least one whitespace between the element and the unit (eg. -"x in"). To change the value of a unit, call -AddUnit() again with the same unit name and the new value. - -

Unit names share the same namespace as constants, functions and - variables, and thus should be distinct from those. - -

Example: parser.AddUnit("in", 300); - -

Now for example the function "5in" will be identical to -"(5*300)". Other usage examples include "x in", -"3in+2", "pow(x,2)in", "(x+2)in". - - -


- -
-bool AddFunction(const std::string& name,
-                 double (*functionPtr)(const double*),
-                 unsigned paramsAmount);
-
- -This method can be used to add new functions to the parser. For example, -if you would like to add a function "sqr(A)" which squares the -value of A, you can do it with this method (so that you don't -need to touch the source code of the parser). - -

The method takes three parameters: - -

- -

The return value will be false if the given name was invalid -(either it did not follow the variable naming conventions, or the name was -already reserved), else true. If the return value is -false, nothing is added. - -

Example: Suppose we have a C++ function like this: - -

double Square(const double* p)
-{
-    return p[0]*p[0];
-} - -

Now we can add this function to the parser like this: - -

parser.AddFunction("sqr", Square, 1);
-parser.Parse("2*sqr(x)", "x"); - -

An example of a useful function taking no parameters is a function - returning a random value. For example: - -

double Rand(const double*)
-{
-    return drand48();
} - -

parser.AddFunction("rand", Rand, 0); - -

Important note: If you use the Optimize() method, -it will assume that the user-given function has no side-effects, that is, -it always returns the same value for the same parameters. The optimizer will -optimize the function call away in some cases, making this assumption. -(The Rand() function given as example above is one such -problematic case.) - - -


- -
-bool AddFunction(const std::string& name, FunctionParser&);
-
- -

This method is almost identical to the previous AddFunction(), -but instead of taking a C++ function, it takes another FunctionParser -instance. - -

There are some important restrictions on making a FunctionParser instance - call another: - -

- -

Example: - -

FunctionParser f1, f2;
-

f1.Parse("x*x", "x");
-

f2.AddFunction("sqr", f1); - -

This version of the AddFunction() method can be useful to -eg. chain user-given functions. For example, ask the user for a function F1, - and then ask the user another function F2, but now the user can - call F1 in this second function if he wants (and so on with a third - function F3, where he can call F1 and F2, etc). - -


- -
-template<typename DerivedWrapper>
-bool AddFunctionWrapper(const std::string& name, const DerivedWrapper&,
-                        unsigned paramsAmount);
-
- -

See section on specialized function objects. - -


- -
-bool RemoveIdentifier(const std::string& name);
-
- -

If a constant, unit or user-defined function with the specified name -exists in the parser, it will be removed and the return value will be -true, else nothing will be done and the return value will be -false. - -

(Note: If you want to remove everything from an existing -FunctionParser instance, simply assign a fresh instance to it, ie. like -"parser = FunctionParser();") - -


- -
-int ParseAndDeduceVariables(const std::string& function,
-                            int* amountOfVariablesFound = 0,
-                            bool useDegrees = false);
-int ParseAndDeduceVariables(const std::string& function,
-                            std::string& resultVarString,
-                            int* amountOfVariablesFound = 0,
-                            bool useDegrees = false);
-int ParseAndDeduceVariables(const std::string& function,
-                            std::vector<std::string>& resultVars,
-                            bool useDegrees = false);
-
- -

These functions work in the same way as the Parse() function, -but the variables in the input function string are deduced automatically. The -parameters are: - -

- -

As with Parse(), the return value will be -1 if -the parsing succeeded, else an index to the location of the error. None of -the specified return values will be modified in case of error. - - - -

Specialized function objects

- -

The AddFunction() method can be used to add a new user-defined -function to the parser, its implementation being called through a C++ function -pointer. Sometimes this might not be enough, though. For example, one might -want to use boost::function or other similar specialized stateful -function objects instead of raw function pointers. This library provides a -mechanism to achieve this. - -

Creating and adding a specialized function object

- -

In order to create a specialized function object, create a class derived -from the FunctionParser::FunctionWrapper class. This class -declares a virtual function named callFunction that the derived -class must implement. For example: - -

-class MyFunctionWrapper:
-    public FunctionParser::FunctionWrapper
-{
- public:
-    virtual double callFunction(const double* values)
-    {
-        // Perform the actual function call here, like:
-        return someFunctionSomewhere(values);
-
-        // In principle the result could also be
-        // calculated here, like for example:
-        return values[0] * values[0];
-    }
-};
-
- -

You can then add an instance of this class to FunctionParser -using the AddFunctionWrapper() method, which works like -AddFunction(), but takes a wrapper object instead of a function -pointer as parameter. For example: - -

-MyFunctionWrapper wrapper;
-parser.AddFunctionWrapper("funcName", wrapper, 1);
-
- -

Note that FunctionParser will internally create a copy of -the wrapper object, managing the lifetime of this copy, and thus the object -given as parameter does not need to exist for as long as the -FunctionParser instance. Hence the above could also be written as: - -

-parser.AddFunctionWrapper("funcName", MyFunctionWrapper(), 1);
-
- -

Note that this also means that the wrapper class must have a working -copy constructor. - -

Also note that if the FunctionParser instance is copied, all -the copies will share the same function wrapper objects given to the original. - -

Retrieving specialized function objects

- -

As noted, the library will internally make a copy of the wrapper object, -and thus it will be separate from the one which was given as parameter to -AddFunctionWrapper(). In some cases it may be necessary to -retrieve this wrapper object (for example to read or change its state). -This can be done with the GetFunctionWrapper() method, which -takes the name of the function and returns a pointer to the wrapper object, -or null if no such object exists with that name. - -

Note that the returned pointer will be of type -FunctionParser::FunctionWrapper. In order to get a pointer to -the actual derived type, the calling code should perform a -dynamic_cast, for example like this: - -

-MyFunctionWrapper* wrapper =
-    dynamic_cast<MyFunctionWrapper*>
-    (parser.GetFunctionWrapper("funcName"));
-
-if(!wrapper) { /* oops, the retrieval failed */ }
-else ...
-
- -

(Using dynamic cast rather than a static cast adds safety because if you -accidentally try to downcast to the wrong type, the pointer will become null.) - -

The calling code is free to modify the object in any way it wants, but it -must not delete it (because FunctionParser itself handles this). - - - - -

FunctionParserBase

- -

All the different parser types are derived from a templated base class -named FunctionParserBase. In normal use it's not necessary to -directly refer to this base class in the calling code. However, if the calling -code also needs to be templated (with respect to the numerical type), then -using FunctionParserBase directly is the easiest way to achieve -this. - -

For example, if you want to make a function that handles more than one -type of parser, it can be done like this: - -

-template<typename Value_t>
-void someFunction(FunctionParserBase<Value_t>& parser)
-{
-    // do something with 'parser' here
-}
-
- -

Now it's convenient to call that function with more than one type of -parser, for example: - -

-FunctionParser realParser;
-FunctionParser_cd complexParser;
-
-someFunction(realParser);
-someFunction(complexParser);
-
- -

Another example is a class that inherits from FunctionParser -which also wants to support different numerical types. Such class can be -declared as: - -

-template<typename Value_t>
-class SpecializedParser: public FunctionParserBase<Value_t>
-{
-    ...
-};
-
- - - -

Syntax

- - -

Numeric literals

- -

A numeric literal is a fixed numerical value in the input function string - (either a floating point value or an integer value, depending on the parser - type). - -

An integer literal can consist solely of numerical digits (possibly with - a preceding unary minus). For example, "12345". - -

If the literal is preceded by the characters "0x", it - will be interpreted as a hexadecimal literal, where digits can also include - the letters from 'A' to 'F' (in either uppercase - or lowercase). For example, "0x89ABC" (which corresponds to the - value 563900). - -

A floating point literal (only supported by the floating point type parsers) - may additionally include a decimal point followed by the decimal part of the - value, such as for example "12.34", optionally followed by a - decimal exponent. - -

A decimal exponent consists of an 'E' or 'e', - followed by an optional plus or minus sign, followed by decimal digits, and - indicates multiplication by a power of 10. For example, "1.2e5" - (which is equivalent to the value 120000). - -

If a floating point literal is preceded by the characters "0x" - it will be interpreted in hexadecimal. A hexadecimal floating point - literal consists of a hexadecimal value, with an optional decimal point, - followed optionally by a binary exponent in base 10 (in other words, the - exponent is not in hexadecimal). - -

A binary exponent has the same format as a decimal exponent, except that - 'P' or 'p' is used. A binary exponent indicates - multiplication by a power of 2. For example, "0xA.Bp10" - (which is equivalent to the value 10944). - -

With the complex versions of the library, the imaginary part of a numeric - literal is written as a regular numeric literal with an 'i' - appended, for example "5i". Note that when also specifying - the real part of a complex literal, parentheses should be used to avoid - precedence problems. (For example, "(2+5i) * x" - is not the same thing as "2+5i * x". The latter - would be equivalent to "2 + (5i * x)".) - - -

Identifier names

- -

An identifier is the name of a function (internal or user-defined), - variable, constant or unit. New identifiers can be specified with the - functions described in the earlier subsections in this document. - -

The name of an identifier can use any alphanumeric characters, the - underscore character and any UTF8-encoded unicode character, excluding - those denoting whitespace. - The first character of the name cannot be a numeric digit, though. - -

All functions, variables, constants and units must use unique names. - It's not possible to add two different identifiers with the same name. - - - - -

The function string syntax

- -

The function string understood by the class is very similar (but not -completely identical in all aspects) to mathematical expressions in the -C/C++ languages. -Arithmetic float expressions can be created from float literals, variables -or functions using the following operators in this order of precedence: - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
()expressions in parentheses first
A unita unit multiplier (if one has been added)
A^Bexponentiation (A raised to the power B)
-Aunary minus
!Aunary logical not (result is 1 if int(A) is 0, else 0)
A*B A/B A%Bmultiplication, division and modulo
A+B A-Baddition and subtraction
A=B A<B A<=B
A!=B A>B A>=B
comparison between A and B (result is either 0 or 1)
A&Bresult is 1 if int(A) and int(B) differ from - 0, else 0.
- Note: Regardless of the values, both operands are always - evaluated. However, if the expression is optimized, it may - be changed such that only one of the operands is evaluated, - according to standard shortcut logical operation semantics.
A|Bresult is 1 if int(A) or int(B) differ from 0, - else 0.
- Note: Regardless of the values, both operands are always - evaluated. However, if the expression is optimized, it may - be changed such that only one of the operands is evaluated, - according to standard shortcut logical operation semantics.
- -

(Note that currently the exponentiation operator is not supported for - FunctionParser_li nor FunctionParser_gmpint. - With the former the result would very easily overflow, making its - usefulness questionable. With the latter it could be easily abused to - make the program run out of memory; think of a function like - "10^10^10^100000".) - -

Since the unary minus has higher precedence than any other operator, for - example the following expression is valid: x*-y - -

The comparison operators use an epsilon value, so expressions which may -differ in very least-significant digits should work correctly. For example, -"0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1 = 1" should always -return 1, and the same comparison done with ">" or -"<" should always return 0. (The epsilon value can be -configured in the fpconfig.hh file.) -Without epsilon this comparison probably returns the wrong value. - -

The class supports these functions: - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
abs(A)Absolute value (magnitude) of A. - With real numbers, if A is negative, returns -A otherwise returns A. - With complex numbers, equivalent to hypot(real(x),imag(x)).
acos(A)Arc-cosine of A. Returns the angle, measured in radians, whose cosine is A.
acosh(A)Same as acos() but for hyperbolic cosine.
arg(A)Phase angle of complex number A. Equivalent to atan2(imag(x),real(x)).
asin(A)Arc-sine of A. Returns the angle, measured in radians, whose sine is A.
asinh(A)Same as asin() but for hyperbolic sine.
atan(A)Arc-tangent of (A). Returns the angle, measured in radians, - whose tangent is A.
atan2(A,B)Principal arc-tangent of A/B, using the signs of the - two arguments to determine the quadrant of the result. - Returns the solution to the two expressions - hypot(A,B)*sin(x)=A, hypot(A,B)*cos(x)=B. - The return value is in range -pi to pi, inclusive.
atanh(A)Same as atan() but for hyperbolic tangent.
cbrt(A)Cube root of A. Returns a solution to expression pow(x,3)=A.
conj(A)Complex conjugate of A. Equivalent to real(x) - 1i*imag(x) or polar(abs(x),-arg(x)).
ceil(A)Ceiling of A. Returns the smallest integer not smaller than A. - Rounds up to the next higher integer. E.g. -2.9, -2.5 and -2.1 are - rounded to -2.0, and 2.9, 2.5 and 2.1 are rounded to 3.0.
cos(A)Cosine of A. Returns the cosine of the angle A, where A is - measured in radians.
cosh(A)Same as cos() but for hyperbolic cosine.
cot(A)Cotangent of A. Equivalent to 1/tan(A).
csc(A)Cosecant of A. Equivalent to 1/sin(A).
eval(...)This a recursive call to the function to be evaluated. The - number of parameters must be the same as the number of parameters - taken by the function. Must be called inside if() to avoid - infinite recursion.
exp(A)Exponential of A. Returns the value of e raised to the power - A where e is the base of the natural logarithm, i.e. the - non-repeating value approximately equal to 2.71828182846.
exp2(A)Base 2 exponential of A. Equivalent to pow(2,A).
floor(A)Floor of A. Returns the largest integer not greater than A. Rounds - down to the next lower integer. - E.g. -2.9, -2.5 and -2.1 are rounded to -3.0, - and 2.9, 2.5 and 2.1 are rounded to 2.0.
hypot(A,B)Euclidean distance function. Equivalent to sqrt(A^2+B^2).
if(A,B,C)If int(A) differs from 0, the return value of this function is B, - else C. Only the parameter which needs to be evaluated is - evaluated, the other parameter is skipped; this makes it safe to - use eval() in them.
imag(A)Return the imaginary part of complex number A. Equivalent to abs(A)*sin(arg(A)).
int(A)Rounds A to the closest integer. Equidistant values are rounded away from - zero. E.g. -2.9 and -2.5 are rounded to -3.0; -2.1 is rounded to -2.0, - and 2.9 and 2.5 are rounded to 3.0; 2.1 is rounded to 2.0.
log(A)Natural (base e) logarithm of A. Returns the solution to expression exp(x)=A.
log2(A)Base 2 logarithm of A. Equivalent to log(A)/log(2).
log10(A)Base 10 logarithm of A.
max(A,B)If A>B, the result is A, else B.
min(A,B)If A<B, the result is A, else B.
polar(A,B)Returns a complex number from magnitude A, phase angle B (in radians). - Equivalent to real(A)*(cos(real(B))+1i*sin(real(B))).
pow(A,B)Exponentiation (A raised to the power B).
real(A)Return the real part of complex number A. Equivalent to abs(A)*cos(arg(A)).
sec(A)Secant of A. Equivalent to 1/cos(A).
sin(A)Sine of A. Returns the sine of the angle A, where A is - measured in radians.
sinh(A)Same as sin() but for hyperbolic sine.
sqrt(A)Square root of A. Returns a solution to expression pow(x,2)=A.
tan(A)Tangent of A. Returns the tangent of the angle A, where A - is measured in radians.
tanh(A)Same as tan() but for hyperbolic tangent.
trunc(A)Truncated value of A. Returns an integer corresponding to the value - of A without its fractional part. - E.g. -2.9, -2.5 and -2.1 are rounded to -2.0, - and 2.9, 2.5 and 2.1 are rounded to 2.0.
- -

(Note that for FunctionParser_li and - FunctionParser_gmpint only the functions - abs(), eval(), if(), - min() and max() are supported.) - -

Examples of function string understood by the class: - -

"1+2"
-"x-1"
-"-sin(sqrt(x^2+y^2))"
-"sqrt(XCoord*XCoord + YCoord*YCoord)"
- -

An example of a recursive function is the factorial function: - -"if(n>1, n*eval(n-1), 1)" - -

Note that a recursive call has some overhead, which makes it a bit slower - than any other operation. It may be a good idea to avoid recursive functions - in very time-critical applications. Recursion also takes some memory, so - extremely deep recursions should be avoided (eg. millions of nested recursive - calls). - -

Also note that even though the maximum recursion level of -eval() is limited, it is possible to write functions which -never reach that level but still take enormous amounts of time to evaluate. -This can sometimes be undesirable because it is prone to exploitation, -which is why eval() is disabled by default. It can be enabled -in the fpconfig.hh file. - - - - -

Inline variables

- -

The function syntax supports defining new variables inside the function -string itself. This can be done with the following syntax: - -

"<variable name> := <expression>; <function>" - -

For example: - -

"length := sqrt(x*x+y*y); 2*length*sin(length)" - -

(Spaces around the ':=' operator are optional.) - -

The obvious benefit of this is that if a long expression needs to be -used in the function several times, this allows writing it only once and -using a named variable from that point forward. - -

The variable name must be an unused identifier (in other words, not an -existing function, variable or unit name). - -

The <function> part can have further inline variable -definitions, and thus it's possible to have any amount of them, for example: - -

"A := x^2; B := y^2; C := z^2; sqrt(A+B+C)" - -

The expressions in subsequent inline variable definitions can use any -of the previous inline variables. It is also possible to redefine an inline -variable. For example: - -

"A := x^2; A := 2*A; sqrt(A)" - - - - -

Whitespace

- -

Arbitrary amounts of whitespace can optionally be included between - elements in the function string. - The following unicode characters are interpreted as whitespace: - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Character numberCharacter nameUTF-8 byte sequence
U+0009HORIZONTAL TABULATION 09
U+000ALINE FEED 0A
U+000BVERTICAL TABULATION 0B
U+000DCARRIAGE RETURN 0D
U+0020SPACE 20
U+00A0NO-BREAK SPACE C2 A0
U+2000EN QUAD E2 80 80
U+2001EM QUAD E2 80 81
U+2002EN SPACE E2 80 82
U+2003EM SPACE E2 80 83
U+2004THREE-PER-EM SPACE E2 80 84
U+2005FOUR-PER-EM SPACE E2 80 85
U+2006SIX-PER-EM SPACE E2 80 86
U+2007FIGURE SPACE E2 80 87
U+2008PUNCTUATION SPACE E2 80 88
U+2009THIN SPACE E2 80 89
U+200AHAIR SPACE E2 80 8A
U+200BZERO WIDTH SPACE E2 80 8B
U+202FNARROW NO-BREAK SPACE E2 80 AF
U+205FMEDIUM MATHEMATICAL SPACEE2 81 9F
U+3000IDEOGRAPHIC SPACE E3 80 80
- - -

Miscellaneous

- - -

About floating point accuracy

- -

Note that if you are using FunctionParser_ld or -FunctionParser_cld and you want calculations to be as accurate -as the long double type allows, you should pay special attention -to floating point literals in your own code. For example, this is a very -typical mistake: - -

FunctionParser_ld parser;
-parser.AddConstant("pi", 3.14159265358979323846);
- -

The mistake might not be immediately apparent. The mistake is that a -literal of type double is passed to the AddConstant() -function even though it expects a value of type long double. -In most systems the latter has more bits of precision than the former, which -means that the value will have its least-significant bits clipped, -introducing a rounding error. The proper way of making the above calls is: - -

FunctionParser_ld parser;
-parser.AddConstant("pi", 3.14159265358979323846L);
- -

The same principle should be used everywhere in your own code, if you are -using the long double type. - -

This is especially important if you are using the MpfrFloat -type (in which case its string-parsing constructor or its -ParseValue() or parseString() member functions -should be used instead of using numerical literals). - - -

About evaluation-time checks

- -

FunctionParser::Eval() will perform certain sanity -checks before performing certain operations. For example, before calling the -sqrt function, it will check if the parameter is negative, and -if so, it will set the proper error code instead of calling the function. -These checks include: - -

- -

However, the library can not guarantee that it will catch all -possible floating point errors before performing them, because this is -impossible to do with standard C++. For example, dividing a very large -value by a value which is very close to zero, or calculating the logarithm -of a very small value may overflow the result, as well as multiplying two -very large values. Raising a negative number to a non-integral power may -cause a NaN result, etc. - -

As a rule of thumb, the library will (by default) detect invalid operations -if they are invalid for a range of values. For example, square root is undefined -for all negative values, and arc sine is undefined only values outside the range -[-1, 1]. In general, operations which are invalid for only one single value -(rather than a contiguous range of values) will not be detected (division by -the exact value of zero is an exception to this rule) nor will -overflow/underflow situations. - -

The library cannot guarantee that floating point -errors will never happen during evaluation. This can make the library to -return the floating point values inf and NaN. Moreover, -if floating point errors cause an interrupt in the target computer -architecture and/or when using certain compiler settings, this library -cannot guarantee that it will never happen. - -

Note that the optimizer never performs any sanity checks. - - - - -

About thread safety

- -

None of the member functions of the FunctionParser class are thread-safe. -Most prominently, the Eval() function is not thread-safe. -(In other words, the Eval() function of a single FunctionParser -instance cannot be safely called simultaneously by two threads.) - -

There are ways to use this library in a thread-safe way, though. If each -thread uses its own FunctionParser instance, no problems will obviously -happen. Note, however, that if these instances need to be a copy of a given -FunctionParser instance (eg. one where the user has entered a function), -a deep copy of this instance has to be performed for each thread. By -default FunctionParser uses shallow-copying (copy-on-write), which means -that a simple assignment of copy construction will not copy the data itself. -To force a deep copy you can all the ForceDeepCopy() function on -each of the instances of each thread after the assignment or copying has been -done. - -

Another possibility is to compile the FunctionParser library so that -its Eval() function will be thread-safe. (This can be done by -defining the FP_USE_THREAD_SAFE_EVAL or the -FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA -precompiler constant.) As long as only one thread calls the other functions -of FunctionParser, the other threads can safely call the Eval() -of this one instance. - -

Note, however, that compiling the library like this can make -Eval() slightly slower. (The alloca version, if -supported by the compiler, will not be as slow.) - -

Also note that the MPFR and GMP versions of the library cannot be - made thread-safe, and thus this setting has no effect on them. - - - - -

Tips and tricks

- -

Add constants automatically to all parser objects

- -

Often the same constants (such as pi and e) and other -user-defined identifiers (such as units) are always used in all the -FunctionParser objects throughout the program. It would be -troublesome to always have to manually add these constants every time a -new parser object is created. - -

There is, however, a simple way to always add these user-defined identifiers -to all instances. Write a class like this: - -

-    class ParserWithConsts: public FunctionParser
-    {
-     public:
-        ParserWithConsts()
-        {
-            AddConstant("pi", 3.14159265358979323846);
-            AddConstant("e", 2.71828182845904523536);
-        }
-    };
-
- -

Now instead of using FunctionParser, always use -ParserWithConsts. It will behave identically except that the -constants (and possibly other user-defined identifiers) will always be -automatically defined. (Objects of this type even survive -slicing, so -they are completely safe to use anywhere.) - - - - -

Contacting the author

- -

Any comments, bug reports, etc. should be sent to warp@iki.fi - - - - - - - - -

Usage license

- -

Copyright © 2003-2011 Juha Nieminen, Joel Yliluoma - -

This Library is distributed under the - Lesser General Public - License (LGPL) version 3. - - - diff --git a/fparser/docs/gpl.txt b/fparser/docs/gpl.txt deleted file mode 100644 index 94a9ed0..0000000 --- a/fparser/docs/gpl.txt +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/fparser/docs/lgpl.txt b/fparser/docs/lgpl.txt deleted file mode 100644 index cca7fc2..0000000 --- a/fparser/docs/lgpl.txt +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/fparser/docs/style.css b/fparser/docs/style.css deleted file mode 100644 index d5141d3..0000000 --- a/fparser/docs/style.css +++ /dev/null @@ -1,80 +0,0 @@ -html -{ - background-color: #E0E0E0; -} - -body -{ - background-color: white; - margin-left: 7%; - margin-top: 16px; - margin-right: 7%; - padding-top: 2em; - padding-left: 7%; - padding-right: 7%; - padding-bottom: 2%; - border-color: black; - border: solid; - border-width: 1px; -} - -h1 -{ - text-align: center; - background-color: #FFEEBB; - padding-bottom: 0.2em; - padding-top: 0.1em; -} - -h2 -{ - background-color: #FFFFCC; - padding-left: 0.5em; -} - -h3 -{ - background-color: #FFFFEE; -} - -blockquote -{ - padding-left: 2em; - padding-right: 2em; - font-style: italic; - background-color: #FFFAF0; -} - -li -{ - padding-top: 0.3em; -} - -pre -{ - background-color: #E8E8E8; - padding-left: 1em; - padding-top: 0.5em; - padding-bottom: 0.5em; -} - -code -{ - font-family: monospace; - color: #900040; -} - -.small -{ - font-size: 80%; -} - -.codecomment -{ - color: green; -} - -.highlight -{ - background: #C0D0FF; -} diff --git a/fparser/examples/example.cc b/fparser/examples/example.cc deleted file mode 100644 index b4ab5f4..0000000 --- a/fparser/examples/example.cc +++ /dev/null @@ -1,55 +0,0 @@ -// Simple example file for the function parser -// =========================================== - -/* When running the program, try for example with these values: - -f(x) = x^2 -min x: -5 -max x: 5 -step: 1 - -*/ - -#include "../fparser.hh" - -#include -#include - -int main() -{ - std::string function; - double minx, maxx, step; - FunctionParser fparser; - - fparser.AddConstant("pi", 3.1415926535897932); - - while(true) - { - std::cout << "f(x) = "; - std::getline(std::cin, function); - if(std::cin.fail()) return 0; - - int res = fparser.Parse(function, "x"); - if(res < 0) break; - - std::cout << std::string(res+7, ' ') << "^\n" - << fparser.ErrorMsg() << "\n\n"; - } - - std::cout << "min x: "; - std::cin >> minx; - std::cout << "max x: "; - std::cin >> maxx; - std::cout << "step: "; - std::cin >> step; - if(std::cin.fail()) return 0; - - double vals[] = { 0 }; - for(vals[0] = minx; vals[0] <= maxx; vals[0] += step) - { - std::cout << "f(" << vals[0] << ") = " << fparser.Eval(vals) - << std::endl; - } - - return 0; -} diff --git a/fparser/examples/example2.cc b/fparser/examples/example2.cc deleted file mode 100644 index 958b9a1..0000000 --- a/fparser/examples/example2.cc +++ /dev/null @@ -1,85 +0,0 @@ -// Simple example file for the function parser -// =========================================== -/* Note that the library has to be compiled with - FP_SUPPORT_FLOAT_TYPE, FP_SUPPORT_LONG_DOUBLE_TYPE and - FP_SUPPORT_LONG_INT_TYPE - preprocessor macros defined for this example to work. - - Try with these input values with the different floating point parser - types to see the difference in accuracy: - -f(x) = x + 1.234567890123456789 -min x: 0 -max x: 2 -step: 1 -*/ - -#include "../fparser.hh" - -#include -#include -#include - -template -void runExample(const char* valueTypeName) -{ - typedef typename Parser::value_type Value_t; - - std::cout << "Using " << valueTypeName << " parser." << std::endl; - - Parser fparser; - std::string function; - Value_t minx, maxx, step; - - fparser.AddConstant("pi", Value_t(3.1415926535897932)); - - std::cin.ignore(); - while(true) - { - std::cout << "f(x) = "; - std::getline(std::cin, function); - if(std::cin.fail()) return; - - int res = fparser.Parse(function, "x"); - if(res < 0) break; - - std::cout << std::string(res+7, ' ') << "^\n" - << fparser.ErrorMsg() << "\n\n"; - } - - std::cout << "min x: "; - std::cin >> minx; - std::cout << "max x: "; - std::cin >> maxx; - std::cout << "step: "; - std::cin >> step; - if(std::cin.fail()) return; - - Value_t vals[] = { 0 }; - for(vals[0] = minx; vals[0] <= maxx; vals[0] += step) - { - std::cout << std::setprecision(20); - std::cout << "f(" << vals[0] << ") = " << fparser.Eval(vals) - << std::endl; - } -} - -int main() -{ - int choice = 0; - do - { - std::cout << "1 = double, 2 = float, 3 = long double, 4 = long int: "; - std::cin >> choice; - } while(choice < 1 || choice > 4); - - switch(choice) - { - case 1: runExample("double"); break; - case 2: runExample("float"); break; - case 3: runExample("long double"); break; - case 4: runExample("long int"); break; - } - - return 0; -} diff --git a/fparser/extrasrc/fp_identifier_parser.inc b/fparser/extrasrc/fp_identifier_parser.inc deleted file mode 100644 index 7489fd0..0000000 --- a/fparser/extrasrc/fp_identifier_parser.inc +++ /dev/null @@ -1,379 +0,0 @@ -/* NOTE: - Do not include this file in your project. The fparser.cc file #includes -this file internally and thus you don't need to do anything (other than keep -this file in the same directory as fparser.cc). - - Part of this file is generated code (by using the make_function_name_parser -utility, found in the development version of this library). It's not intended -to be modified by hand. -*/ - - unsigned nameLength = 0; - const unsigned maximumNameLength = 0x80000000U-8; - /* - Due to the manner the identifier lengths are returned from - the readOpcode() function, the maximum supported length for - identifiers is 0x7FFFFFFF bytes. We minus 8 here to add some - buffer, because of the multibyteness of UTF-8. - Function names are limited to 0xFFFF bytes instead, but because - function names that long just are not defined, the point is moot. - */ - const unsigned char* const uptr = (const unsigned char*) input; - typedef signed char schar; - while(likely(nameLength < maximumNameLength)) - { - unsigned char byte = uptr[nameLength+0]; - /* Handle the common case of A-Za-z first */ - if(byte >= 0x40) - { - if(byte < 0x80) // 0x40..0x7F - most common case - { - // Valid characters in 40..7F: A-Za-z_ - // Valid bitmask for 40..5F: 01111111111111111111111111100001 - // Valid bitmask for 60..7F: 01111111111111111111111111100000 - if(sizeof(unsigned long) == 8) - { - const unsigned n = sizeof(unsigned long)*8-32; - // ^ avoids compiler warning when not 64-bit - unsigned long masklow6bits = 1UL << (byte & 0x3F); - if(masklow6bits & ~((1UL << 0) | (0x0FUL << (0x1B )) - | (1UL << n) | (0x1FUL << (0x1B+n)))) - { ++nameLength; continue; } - } - else - { - unsigned masklow5bits = 1 << (byte & 0x1F); - if((masklow5bits & ~(1 | (0x1F << 0x1B))) || byte == '_') - { ++nameLength; continue; } - } - break; - } - if(byte < 0xF0) - { - if(byte < 0xE0) - { - if(byte < 0xC2) break; // 0x80..0xC1 - if(byte == 0xC2 && uptr[nameLength+1]==0xA0) break; // skip nbsp - // C2-DF - next common case when >= 0x40 - // Valid sequence: C2-DF 80-BF - if(schar(uptr[nameLength+1]) > schar(0xBF)) break; - nameLength += 2; - continue; - } - if(byte == 0xE0) // E0 - { - // Valid sequence: E0 A0-BF 80-BF - if((unsigned char)(uptr[nameLength+1] - 0xA0) > (0xBF-0xA0)) break; - } - else - { - if(byte == 0xED) break; // ED is invalid - // Valid sequence: E1-EC 80-BF 80-BF - // And: EE-EF 80-BF 80-BF - if(byte == 0xE2) - { - // break on various space characters - if(uptr[nameLength+1] == 0x80 - && (schar(uptr[nameLength+2]) <= schar(0x8B) - || (uptr[nameLength+2] == 0xAF))) break; - if(uptr[nameLength+1] == 0x81 - && uptr[nameLength+2] == 0x9F) break; - } else - if(byte == 0xE3 && uptr[nameLength+1] == 0x80 - && uptr[nameLength+2] == 0x80) break; // this too - - if(schar(uptr[nameLength+1]) > schar(0xBF)) break; - } - if(schar(uptr[nameLength+2]) > schar(0xBF)) break; - nameLength += 3; - continue; - } - if(byte == 0xF0) // F0 - { - // Valid sequence: F0 90-BF 80-BF 80-BF - if((unsigned char)(uptr[nameLength+1] - 0x90) > (0xBF-0x90)) break; - } - else - { - if(byte > 0xF4) break; // F5-FF are invalid - if(byte == 0xF4) // F4 - { - // Valid sequence: F4 80-8F - if(schar(uptr[nameLength+1]) > schar(0x8F)) break; - } - else - { - // F1-F3 - // Valid sequence: F1-F3 80-BF 80-BF 80-BF - if(schar(uptr[nameLength+1]) > schar(0xBF)) break; - } - } - if(schar(uptr[nameLength+2]) > schar(0xBF)) break; - if(schar(uptr[nameLength+3]) > schar(0xBF)) break; - nameLength += 4; - continue; - } - if(nameLength > 0) - { - if(sizeof(unsigned long) == 8) - { - // Valid bitmask for 00..1F: 00000000000000000000000000000000 - // Valid bitmask for 20..3F: 00000000000000001111111111000000 - const unsigned n = sizeof(unsigned long)*8-32; - // ^ avoids compiler warning when not 64-bit - unsigned long masklow6bits = 1UL << byte; - if(masklow6bits & (((1UL << 10)-1UL) << (16+n))) - { ++nameLength; continue; } - } - else - { - if(byte >= '0' && byte <= '9') - { ++nameLength; continue; } - } - } - break; - } - - /* This function generated with make_function_name_parser.cc */ -#define lO l3 lH -#define lN switch( -#define lM l4 lH -#define lL if('i' l5 -#define lK 'n' l5 -#define lJ 0x80000003U; -#define lI l1 3]={ -#define lH case -#define lG 0x80000005U; -#define lF )==0)l0( -#define lE l8 3;}lH -#define lD std::memcmp(uptr+ -#define lC l2 3 lF -#define lB lA 1]){lH -#define lA :lN uptr[ -#define l9 'a' lB -#define l8 default:l0 -#define l7 lG l0 5;}lH -#define l6 <<16)| -#define l5 ==uptr[ -#define l4 lJ l0 3; -#define l3 0x80000004U;l0 4; -#define l2 lD 1,tmp, -#define l1 static const char tmp[ -#define l0 return -lN -nameLength){lH -2:lL -0]&&'f' l5 -1])l0(cIf -l6 -0x80000002U;l0 -2;lH -3 -lA -0]){lH -l9'b':if('s' l5 -2])l0(cAbs -l6 -lM'r':if('g' l5 -2])l0(cArg -l6 -l4 -lE'c' lB'o' lA -2]){lH's':l0(cCos -l6 -lJ -lH't':l0(cCot -l6 -lJ -lE's':if('c' l5 -2])l0(cCsc -l6 -l4 -lE'e':if('x' l5 -1]&&'p' l5 -2])l0(cExp -l6 -lM'i':if(lK -1]&&'t' l5 -2])l0(cInt -l6 -lM'l':if('o' l5 -1]&&'g' l5 -2])l0(cLog -l6 -lM'm' lB'a':if('x' l5 -2])l0(cMax -l6 -lM'i':if(lK -2])l0(cMin -l6 -l4 -lE'p':if('o' l5 -1]&&'w' l5 -2])l0(cPow -l6 -lM's' lB'e':if('c' l5 -2])l0(cSec -l6 -lM'i':if(lK -2])l0(cSin -l6 -l4 -lE't':if('a' l5 -1]&&lK -2])l0(cTan -l6 -l4 -lE -4 -lA -0]){lH -l9'c':if('o' l5 -2]&&'s' l5 -3])l0(cAcos -l6 -lO's':lL -2]&&lK -3])l0(cAsin -l6 -lO't':if('a' l5 -2]&&lK -3])l0(cAtan -l6 -l3 -l8 -4;} -lH'c' lB'b':if('r' l5 -2]&&'t' l5 -3])l0(cCbrt -l6 -lO'e':lL -2]&&'l' l5 -3])l0(cCeil -l6 -lO'o' lA -2]){lH'n':if('j' l5 -3])l0(cConj -l6 -lO's':if('h' l5 -3])l0(cCosh -l6 -l3 -l8 -4;} -l8 -4;} -lH'e':{lI'x','p','2'} -;if(lC -cExp2 -l6 -l3} -lH'i':{lI'm','a','g'} -;if(lC -cImag -l6 -l3} -lH'l':{lI'o','g','2'} -;if(lC -cLog2 -l6 -l3} -lH'r':{lI'e','a','l'} -;if(lC -cReal -l6 -l3} -lH's' lB'i':if(lK -2]&&'h' l5 -3])l0(cSinh -l6 -lO'q':if('r' l5 -2]&&'t' l5 -3])l0(cSqrt -l6 -l3 -l8 -4;} -lH't':{lI'a','n','h'} -;if(lC -cTanh -l6 -l3} -l8 -4;} -lH -5 -lA -0]){lH -l9'c':{lI'o','s','h'} -;if(lD -2,tmp,3 -lF -cAcosh -l6 -l7's':{lI'i','n','h'} -;if(lD -2,tmp,3 -lF -cAsinh -l6 -l7't':if('a' l5 -2]){if(lK -3]){lN -uptr[4]){lH'2':l0(cAtan2 -l6 -lG -lH'h':l0(cAtanh -l6 -lG -l8 -5;} -} -l0 -5;} -l0 -5;l8 -5;} -lH'f':{l1 -4]={'l','o','o','r'} -;if(l2 -4 -lF -cFloor -l6 -l7'h':{l1 -4]={'y','p','o','t'} -;if(l2 -4 -lF -cHypot -l6 -l7'l':{l1 -4]={'o','g','1','0'} -;if(l2 -4 -lF -cLog10 -l6 -l7'p':{l1 -4]={'o','l','a','r'} -;if(l2 -4 -lF -cPolar -l6 -l7't':{l1 -4]={'r','u','n','c'} -;if(l2 -4 -lF -cTrunc -l6 -lG -l0 -5;} -l8 -5;} -default:break;} -l0 -nameLength; diff --git a/fparser/extrasrc/fp_opcode_add.inc b/fparser/extrasrc/fp_opcode_add.inc deleted file mode 100644 index ed05b22..0000000 --- a/fparser/extrasrc/fp_opcode_add.inc +++ /dev/null @@ -1,7696 +0,0 @@ -/* Function Parser for C++ v4.5.1 - - NOTE: - Do not include this file in your project. The fparser.cc file #includes -this file internally and thus you don't need to do anything (other than keep -this file in the same directory as fparser.cc). - - This file contains generated code and is thus not intended to be to -be modified by hand. It was generated by util/bytecoderules_parser, which -is available in the development package. -*/ -#define HasInvalidRangesOpcode HasInvalidRangesOpcode::result> -#define FP_TRACE_BYTECODE_OPTIMIZATION(srcline,from,to,with) \ - /*std::cout << "Changing \"" from "\"\t(line " #srcline ")\n" \ - " into \"" to "\"\n" with << std::flush*/ -#define FP_TRACE_OPCODENAME(op) \ - (op < VarBegin \ - ? FP_GetOpcodeName(OPCODE(op)) \ - : findName(mData->mNamePtrs,op,NameData::VARIABLE)) -#define FP_TRACE_BYTECODE_ADD(opcode) \ - /*std::cout << "Adding opcode: " << FP_TRACE_OPCODENAME(opcode) \ - << ", bytecode length " << data->ByteCode.size() \ - << ", pointer is " << (void*)ByteCodePtr \ - << ", code is " << (data->ByteCode.empty() \ - ? (void*)0 \ - : (void*)&data->ByteCode[0]) \ - << std::endl*/ -#define qH1 " B" mF -#define qG1 gT y*x; -#define qF1 hV 2;qI -#define qE1 <<"," aD -#define qD1 <<"," aB -#define qC1 "cNeg" -#define qB1 wA"," aD -#define qA1 "x[x!=Value_t(0)] " -#define q91 <<"," a8 -#define q81 wA"," a1 -#define q71 );qW q6 -#define q61 "cPow " -#define q51 "cSqrt" -#define q41 "cSqr " -#define q31 " cExp2" -#define q21 "cExp " -#define q11 ){hD wB -#define q01 "cCeil" -#define mZ "cImag" -#define mY "cConj" -#define mX "cDup " -#define mW hO wB -#define mV "cAbs" -#define mU wQ wH" " -#define mT qS w2 wB -#define mS "cFloor" -#define mR "cTan" -#define mQ " cDup" -#define mP "cSin" -#define mO (y hX; -#define mN "[ y+x]" -#define mM hV 2 gC -#define mL " cExp" -#define mK "A " wX -#define mJ "cLess" -#define mI "[-x]" wH -#define mH "cDiv" a7 -#define mG "cLog" -#define mF " cDiv" -#define mE " " a6 -#define mD " " aF -#define mC "cMin" -#define mB "cMax" -#define mA aY"x " -#define m9 gN wB -#define m8 "x cPow" -#define m7 g1 oG wB -#define m6 (x);gJ -#define m5 "B cSqr" -#define m4 oH dE wB -#define m3 "[y*x]" wH -#define m2 "cGreater" -#define m1 mV" " wL -#define m0 "cNeg " -#define aZ " cAdd" -#define aY "y " -#define aX "B[IsVarOpcode(B)] " -#define aW " cSub" -#define aV gY if(dO wB -#define aU "cInv" -#define aT mX aU -#define aS "cAbsNot" -#define aR "cLessOrEq" -#define aQ "cAdd " q51 -#define aP "[y*x] cPow" -#define aO "cCos" -#define aN "cLog2" -#define aM "cCosh" -#define aL "cLog10" -#define aK "B[B==A]" -#define aJ "cNotNot" -#define aI " " a2 -#define aH "cDup" aZ -#define aG "cGreaterOrEq" -#define aF "x" aZ -#define aE "cEqual" -#define aD " " aC -#define aC "A" wY -#define aB " " wU -#define aA " cNeg" -#define a9 " cRDiv" -#define a8 " B" wY -#define a7 " x" wH -#define a6 "cRSub" -#define a5 "A[IsVarOpcode(A)]" -#define a4 "x[x!=Value_t()] " -#define a3 " " a5" " -#define a2 " with" aD -#define a1 " " wG -#define a0 " cNot" -#define wZ "x[x==Value_t()]" wH -#define wY " " wC -#define wX "[x]" wH -#define wW "cNEqual" -#define wV a5 mF -#define wU "x = "<Value_t(0)]" -#define wP "B[IsNeverNegativeValueOpcode(B)] " -#define wO "x[x==Value_t(1)] " -#define wN wA"\n" -#define wM <<"\n" -#define wL "x[x==Value_t(0)] " -#define wK "B[IsBinaryOpcode(B)&&!HasInvalidRangesOpcode(B)] " wD -#define wJ "A[IsNeverNegativeValueOpcode(A)] " -#define wI "A[IsVarOpcode(A)&&mData->mByteCode.size()>2] " -#define wH " cMul" -#define wG aY"= "<oP){ -#define dN mImmed -#define dM qE h3 gX -#define dL qK dJ w3 -#define dK cGreaterOrEq -#define dJ =q6; -#define dI qK dJ g6 -#define dH Value_t -#define dG q8 2 gH q4 -#define dF q0[0] -#define dE qK qR qX -#define dD qK qR IsLogicalOpcode(h2 -#define dC (qK== -#define dB hB oY -#define dA qY g8 oG -#define d9 pop_back() -#define d8 q6;q1 h3 gI -#define d7 q8 2 gC -#define d6 hR Lba; -#define d5 Default4 qU -#define d4 :if( -#define d3 qV hS d4 qL -#define d2 h3 gM if -#define d1 IsVarOpcode( -#define d0 mData-> -#define hZ ]qR w4 -#define hY gX Llq -#define hX ,x gX Lap -#define hW gT y+x;q8 -#define hV for qA -#define hU gQ cAbs: -#define hT unsigned -#define hS cAdd -#define hR ,y gX -#define hQ qL 3 hZ -#define hP y=q3-1]qR -#define hO y gO -#define hN qY if(dP -#define hM q6:qC -#define hL :if gF -#define hK qQ h9 hS hL -#define hJ 4 qZ mW(292,aY"cAdd B[IsVarOpcode(B)]" aW mD,mN aZ" B" aW,wA"," a8(B)<<"," a1);q4 -#define hI cNeg: -#define hH :qS cDup: -#define hG hS hH hK h1 wB(310,aH" " aH,"[Value_t(4)]" wH,);q4 -#define hF (x!=g1 -#define hE qL 2] -#define hD B g4 w4 -#define hC B=hE qO B)){ -#define hB if hF 0)){ -#define hA gX Lng; -#define h9 qK qV -#define h8 }break; -#define h7 ()){ -#define h6 hR Lap; -#define h5 isEvenInteger( -#define h4 DegreesToRadians(x -#define h3 cMul -#define h2 A)){ -#define h1 ]==cDup){ -#define h0 hI wB(201,m0 mV,mV,);q4 Lab qU qB -#define gZ 3 h1 wB(311,aH wH" " aH,"cMul [Value_t(4)]" wH,);q4 -#define gY qU hM -#define gX );q4 -#define gW y,x gX Lba; -#define gV IsUnaryOpcode( -#define gU g6 w5= -#define gT q3-1]= -#define gS gR qR IsAlwaysIntegerOpcode(h2 -#define gR ;oH dF -#define gQ )){qQ h9 -#define gP break gR qO A gQ -#define gO =q3-1]; -#define gN qJ hO -#define gM :qJ qC -#define gL d2(dO -#define gK ]=q6 q9 2 gH -#define gJ return; -#define gI );w5= -#define gH ;qI q5 -#define gG qL 2 gK q0-=2; -#define gF (qL 2 -#define gE y;hT B;hT -#define gD d0 mByteCode -#define gC ;qI q1 -#define gB q9 2 gC h3 gI -#define gA ){if gF -#define g9 oY h3 dV -#define g8 if(x==g1 -#define g7 default: -#define g6 q5 q0-=1; -#define g5 if(!q0){q2 -#define g4 =hE qR -#define g3 B g4 IsNeverNegativeValueOpcode(B)){ -#define g2 &&!HasInvalidRangesOpcode( -#define g1 dH( -#define g0 FP_ReDefinePointers(); -#define qZ ]==q6){ -#define qY if(q0[0 qZ qC -#define qX IsNeverNegativeValueOpcode(h2 -#define qW gD qD -#define qV ){case -#define qU ;case -#define qT }break qU -#define qS qQ dF qV -#define qR ;if( -#define qQ switch( -#define qP )&&gD oK> -#define qO qR d1 -#define qN dF w1 2){ -#define qM d0 dN.d9; -#define qL q0[- -#define qK qL 1] -#define qJ oY q6){ -#define qI tmp-->0;) -#define qH q4 Default0; -#define qG }}qH -#define qF d0 dN qD -#define qE AddFunctionOpcode( -#define qD .push_back( -#define qC x=q7; -#define qB hM wB(132,"x " mV,"[fp_abs(x)]",wN);q4 Lac; -#define qA (hT tmp= -#define q9 ;hV -#define q8 d0 dN.d9 q9 -#define q7 q3 0] -#define q6 cImmed -#define q5 gD.d9; -#define q4 goto -#define q3 dW[ -#define q2 q4 Laa;}case -#define q1 q5 qE -#define q0 ByteCodePtr -hT*q0;dH*dW; -#define FP_ReDefinePointers() q0=!gD.empty()?&gD[0]+gD oK-1:0;dW=!d0 dN.empty()?&d0 dN[0]+d0 dN oK-1:0; -g0 -wE(opcode); -#if(!(FP_COMPLEX_VERSION) && !(FP_FLOAT_VERSION)) -dH -x;hT -A;dH -gE -C;hT -D;qQ -w5){TailCall_cAbs:g5 -cAbs:qS -h0 -oH -dF -qR -qX -wB(393,wJ -mV,"A" -,aI(A)wM);gJ -qG -TailCall_cAdd:g5 -hG -Lad;qT -h3 -hL]==hS){if(qL -gZ -Lae;} -h8} -q4 -dX -qU -d2 -gF -h1 -wB(313,"cDup" -a7 -aZ,"[x+Value_t(1)]" -wH,wN);q4 -Laf;} -} -q4 -dX -oF -wB(199,qC1 -aZ,"cSub" -,);q4 -Lag -gY -hK -qZ -mW(127,aY"cAdd" -mD,"[y+x]" -aZ,q81);q4 -Lah;qT -cRSub:qQ -hE -d3 -3 -qZ -mW(298,aY"cAdd" -mE -mD,mN -aZ -mE,q81);q4 -Lai;qT -hI -wB(299,m0 -a6 -mD,"[-x]" -aZ -mE,wN);q4 -Laj -qU -q6:mW(297,aY -a6 -mD,mN -mE,q81);q4 -Lak;qT -oA -Lal;qT -hI -wB(293,m0"B[IsVarOpcode(B)]" -aW -mD,"[-x]" -aZ" B" -aW,wA"," -a8(B)wM);q4 -Lam -qU -q6:mW(291,aY"B[IsVarOpcode(B)]" -aW -mD,mN" B" -aW,wA"," -a8(B)<<"," -a1);q4 -Lan;} -w9 -mW(105,aY -aF,"[y+x]" -,q81);q4 -Lao;} -g8)){wB(57,"x[x==Value_t()]" -aZ,,wN);q4 -Lap;h8 -g7 -dX:;A=dF -w0 -oY -cRSub -dV -wB(290,"x" -mE -a3"cAdd" -,"[DO_STACKPLUS1] A [x]" -aZ -mE,aI(A)qD1 -wM);incStackPtr();--mStackPtr;q4 -Laq;} -wB(295,a6 -a3"cAdd" -,"[DO_STACKPLUS1] A" -aZ -mE,aI(A)wM);incStackPtr();--mStackPtr;q4 -Lba;} -qG -TailCall_cAnd:g5 -cAnd -hH -wB(224,mX"cAnd" -,aJ,);q4 -Lbb -gY -m9(117,mA"cAnd" -,"[fp_and(x,y)]" -,q81);q4 -Lbc;h8} -qH -TailCall_cDiv:g5 -cDiv -hH -wB(78,"cDup" -mF,"[Value_t()]" -wH" [Value_t(1)]" -aZ,);q4 -w7 -if -hF -gQ -hI -wB(125,m0 -a4"cDiv" -,"[-x]" -mF,wN);q4 -Lbe -qU -q6:mW(103,aY -a4"cDiv" -,"[y/x]" -,q81);q4 -Lbf;} -} -g8 -oG -wB(56,wO"cDiv" -,,wN);q4 -Lap;h8} -qH -TailCall_cEqual:g5 -w8:dA -A=dD -wB(421,"A[IsLogicalOpcode(A)] " -wO -aE,"A" -,qB1(A)wM);q4 -Lap;} -} -m9(115,mA -aE,"[fp_equal(y,x)]" -,q81);q4 -Lbg;} -g8 -0 -hU -wB(359,m1 -aE,"[x] " -aE,wN);q4 -Lbh -qU -cSqr:wB(361,q41 -wL -aE,"[x] " -aE,wN);q4 -Lbh;} -wB(411,wL -aE,"cNot" -,wN);q4 -Lbi;qG -TailCall_cGreater:g5 -o1:oL -hU -wB(413,m1 -m2,aJ,wN);q4 -Lbj;m4(417,wJ -wL -m2,"A " -aJ,qB1(A)wM);q4 -Lbk;} -} -} -m9(113,mA -m2,"[fp_less(x,y)]" -,q81);q4 -Lbl;qG -TailCall_cGreaterOrEq:g5 -dK:qY -g8 -1 -hU -wB(414,mV" " -wO -aG,aJ,wN);q4 -Lbj;m4(418,wJ -wO -aG,"A " -aJ,qB1(A)wM);q4 -Lbk;} -} -} -m9(114,mA -aG,"[fp_lessOrEq(x,y)]" -,q81);q4 -Lbm;qG -TailCall_cInv:g5 -cInv:qY -if -hF)){wB(101,a4 -aU,"[Value_t(1)/x]" -,wN);q4 -Lbn;qG -TailCall_cLess:g5 -cLess:oL)){A=dE -wB(301,wJ -wL -mJ,mK,qB1(A)wM);oS;} -} -g8 -1 -hU -wB(415,mV" " -wO -mJ,"cNot" -,wN);q4 -Lbp;m4(419,wJ -wO -mJ,"A" -a0,qB1(A)wM);q4 -Lbi;} -} -} -m9(111,mA -mJ,"[fp_less(y,x)]" -,q81);q4 -Lbq;qG -TailCall_cLessOrEq:g5 -cLessOrEq:oL -hU -wB(416,m1 -aR,"cNot" -,wN);q4 -Lbp;m4(420,wJ -wL -aR,"A" -a0,qB1(A)wM);q4 -Lbi;} -} -} -m9(112,mA -aR,"[fp_lessOrEq(y,x)]" -,q81);q4 -Lca;qG -TailCall_cMax:g5 -cMax -hH -wB(60,mX -mB,,);q4 -w6 -m9(141,mA -mB,"[fp_max(x,y)]" -,q81);q4 -Lcc;} -gP -cDup:hD -wB(66,aK -mQ -a3 -mB,"B" -mQ,aI(A)q91(B)wM);q4 -Lcb;qT -cMax:hD -wB(68,aK" " -mB -a3 -mB,"B " -mB,aI(A)q91(B)wM);q4 -Lcb;h8} -qG -TailCall_cMin:g5 -cMin -hH -wB(59,mX -mC,,);q4 -w6 -m9(140,mA -mC,"[fp_min(x,y)]" -,q81);q4 -Lcd;} -gP -cDup:hD -wB(65,aK -mQ -a3 -mC,"B" -mQ,aI(A)q91(B)wM);q4 -Lcb;qT -cMin:hD -wB(67,aK" " -mC -a3 -mC,"B " -mC,aI(A)q91(B)wM);q4 -Lcb;h8} -qG -TailCall_cMod:g5 -cMod:qY -if -hF)){m9(104,aY -a4"cMod" -,"[fp_mod(y,x)]" -,q81);q4 -Lce;} -qG -TailCall_cMul:g5 -h3 -hH -wB(202,"cDup" -wH,"cSqr" -,);q4 -Lcf -oF -qQ -h9 -cDup:wB(467,"cDup" -aA -wH,"cSqr" -aA,);q4 -Lcg;oH -qK -qO -A)gA -oM -B=hQ -wB(473,aK -wH -a3 -qC1 -wH,m5 -wH -aA,aI(A)q91(B)wM);q4 -Lch;} -} -} -} -q4 -dY -qU -cPow -gM -if -gF -h1 -wB(314,mX -m8 -wH,"[x+Value_t(1)] cPow" -,wN);q4 -Lci;} -} -q4 -dY -gY -g8 -gQ -h3:A=hE -w0 -wB(93,wS" " -wZ,wX,qB1(A)wM);q4 -Lcj;} -q4 -Default3;g7 -Default3:;A=qK -qR -IsBinaryOpcode(A)g2 -h2 -qQ -hE -qV -q6:mW(92,aY -wD,wX,qB1(A)<<"," -a1);q4 -Lck;g7 -B -g4 -IsBinaryOpcode(B)g2 -B)){qQ -oC -qV -q6:mW(96,aY -wK,mK,qB1(A)q91(B)<<"," -a1);q4 -Lcl;g7 -C=oC -qO -C)){wB(94,"C[IsVarOpcode(C)] " -wK,mK,qB1(A)q91(B)<<", C" -wY(C)wM);q4 -Lcm;} -if(gV -C)g2 -C)){wB(95,"C[IsUnaryOpcode(C)&&!HasInvalidRangesOpcode(C)] " -wK,"B " -mK,qB1(A)q91(B)<<", C" -wY(C)wM);q4 -Lcn;} -} -} -if(d1 -B)){wB(90,aX -wD,wX,qB1(A)q91(B)wM);q4 -Lcj;} -if(gV -B)g2 -B)){wB(91,"B[IsUnaryOpcode(B)&&!HasInvalidRangesOpcode(B)] " -wD,mK,qB1(A)q91(B)wM);q4 -Lco;} -} -} -if(d1 -h2 -wB(88,a5" " -wZ,"[x]" -,qB1(A)wM);q4 -Lcp;} -if(gV -A)g2 -h2 -wB(89,"A[IsUnaryOpcode(A)&&!HasInvalidRangesOpcode(A)] " -wZ,wX,qB1(A)wM);q4 -Lcq;} -} -} -qQ -h9 -hS:qQ -hE -qV -cDup:wB(317,aH -a7,"[x+x]" -wH,wN);q4 -Lda -qU -o5 -3 -qZ -hO -A=qL -4]w0 -wB(386,a5" y" -wH -aZ -a7,wX" A " -m3 -aZ,wA", " -aY"= " -<mByteCode.size()>1] A[IsUnaryOpcode(A)]" -wH,"D C cSqr" -wH,aI(A)q91(B)<<", C" -wY(C)<<", D" -wY(D)wM);q4 -Ldm;} -} -} -} -qG -TailCall_cNEqual:g5 -cNEqual:dA -A=dD -wB(422,"A[IsLogicalOpcode(A)] " -wO -wW,"A" -a0,qB1(A)wM);q4 -Lbi;} -} -m9(116,mA -wW,"[fp_nequal(y,x)]" -,q81);q4 -Ldn;} -g8 -0 -hU -wB(360,m1 -wW,"[x] " -wW,wN);q4 -Ldo -qU -cSqr:wB(362,q41 -wL -wW,"[x] " -wW,wN);q4 -Ldo;} -wB(412,wL -wW,aJ,wN);q4 -Lbk;qG -TailCall_cNeg:g5 -hI -qS -h3 -gM -wB(123,"x" -wH -aA,mI,wN);q4 -Ldp;qT -hI -wB(61,qC1 -aA,,);q4 -w6 -wB(100,"x" -aA,"[-x]" -,wN);q4 -Ldq;} -qH -TailCall_cNot:g5 -cNot:qS -cAbs:wB(227,mV -a0,"cNot" -,);q4 -Lea -qU -cAbsNot:A=dD -wB(389,"A[IsLogicalOpcode(A)] " -aS -a0,"A" -,aI(A)wM);q4 -Lcb;} -if(A!=q6){wB(390,"A[A!=cImmed] " -aS -a0,"A cAbsNotNot" -,aI(A)wM);q4 -Leb;} -q4 -o0 -qU -cAbsNotNot:wB(231,"cAbsNotNot" -a0,aS,);q4 -Lec -qU -hS -gM -wB(424,aF -a0,"[-x] " -aE,wN);q4 -Led;} -q4 -o0 -qU -w8:wB(220,aE -a0,wW,);q4 -Lee -qU -o1:wB(218,m2 -a0,aR,);q4 -Lef -qU -dK:wB(219,aG -a0,mJ,);q4 -Leg -qU -cLess:wB(216,mJ -a0,aG,);q4 -Leh -qU -cLessOrEq:wB(217,aR -a0,m2,);q4 -Lei -qU -cNEqual:wB(221,wW -a0,aE,);q4 -Lej -oF -wB(226,qC1 -a0,"cNot" -,);q4 -Lea -qU -cNot:wB(229,"cNot" -a0,aJ,);q4 -Lbb -qU -dS:wB(230,aJ -a0,"cNot" -,);q4 -Lea -gY -wB(107,"x" -a0,"[fp_not(x)]" -,wN);q4 -Lek;g7 -o0:;A=dF -qR -qX -wB(391,wJ"cNot" -,"A " -aS,aI(A)wM);q4 -Lel;qG -TailCall_cNotNot:g5 -dS:qS -hS -gM -wB(423,aF" " -aJ,"[-x] " -wW,wN);q4 -Lem;qT -cNot:wB(232,"cNot " -aJ,"cNot" -,);gJ} -qH -TailCall_cOr:g5 -cOr -hH -wB(223,mX"cOr" -,aJ,);q4 -Lbb -gY -m9(118,mA"cOr" -,"[fp_or(x,y)]" -,q81);q4 -Len;h8} -qH -TailCall_cRDiv:g5 -cRDiv:dA -wB(268,wO"cRDiv" -,aU,wN);q4 -Leo;qG -TailCall_cRSub:g5 -cRSub -d4 -q0[0 -h1 -wB(77,"cDup" -mE,"[Value_t()]" -wH,);q4 -Lep;} -qH -TailCall_cSqr:g5 -cSqr:qS -cAbs:wB(204,mV" cSqr" -,"cSqr" -,);q4 -Leq -oF -wB(203,m0"cSqr" -,"cSqr" -,);q4 -Leq;} -qH -TailCall_cSub:g5 -cSub -hH -wB(76,"cDup" -aW,"[Value_t()]" -wH,);q4 -Lep -oF -wB(200,qC1 -aW,"cAdd" -,);q4 -Lfa -gY -g8)){wB(58,"x[x==Value_t()]" -aW,,wN);q4 -Lap;} -m9(106,aY"x" -aW,"[y-x]" -,q81);q4 -Lfb;} -wB(51,"x" -aW,"[-x]" -aZ,wN);q4 -Lfc -gR -w0 -oY -cRSub -dV -wB(289,"x" -mE -a3"cSub" -,"A" -aZ" [x]" -mE,aI(A)qD1 -wM);q4 -Lfd;} -wB(296,a6 -a3"cSub" -,"[DO_STACKPLUS1] A" -aW -mE,aI(A)wM);incStackPtr();--mStackPtr;q4 -Lfe;} -qG -g7 -Default0:;A=w5 -qR -IsComparisonOpcode(h2 -qY -hK -qZ -mW(364,aY"cAdd" -wF,"[x-y] A" -,aI(A)qD1<<"," -a1);q4 -Lff;qT -hI -wB(365,qC1 -wF,"[-x] {OppositeComparisonOpcode(A)}" -,aI(A)qD1 -wM);q4 -Lfg;} -} -} -if(d1 -A -qP -0){B=q0[0 -hZ -wB(475,aK" A[IsVarOpcode(A)&&mData->mByteCode.size()>0]" -,"B" -mQ,aI(A)q91(B)wM);q4 -Lfh;} -} -if(gV -h2 -B=dF -qO -B -qP -1){C=qK -qR -C==A){D -g4 -D==B){wB(476,"D[D==B] C[C==A] B[IsVarOpcode(B)&&mData->mByteCode.size()>1] A[IsUnaryOpcode(A)]" -,"D C" -mQ,aI(A)q91(B)<<", C" -wY(C)<<", D" -wY(D)wM);q4 -Lfi;} -} -} -} -} -q4 -Laa;Laa:qW -w5);gJ -Lab:g6 -wE(cAbs);q4 -TailCall_cAbs;Lac:q7=dP;gJ -Lad:oZ -4));gG -Lfj:w5=h3;Lfk:g0 -Lfl:wE(cMul);q4 -TailCall_cMul;Lae:hV -4 -dT -oZ -4)q71 -gX -Lfj;Laf:q7=x+g1 -1);gG -Lbo:w5=h3;q4 -Lfl;Lag:gU -cSub;Lfm:wE(cSub);q4 -TailCall_cSub;Lah:hW -2 -gH -Lfn:g0 -Lfo:wE(cAdd);q4 -TailCall_cAdd;Lai:hW -oR -Lfp:qE -hS);Lfq:w5=cRSub;g0 -wE(cRSub);q4 -TailCall_cRSub;Laj:o9;qL -2 -gK -q4 -Lfp;Lak:hW -2 -gH -q4 -Lfq;Lal:hW -4 -gH -Lga:qE -hS);Lgb:qE -B);Lgc:w5=cSub;g0 -q4 -Lfm;Lam:o9;oC=q6 -q9 -oR -q4 -Lga;Lan:hW -oR -q4 -Lgb;Lao:gT -y+x;Lap:qM -Lcb:q5 -gJ -Laq:q8 -oV -o7 -x -q71 -gX -Lfp;Lba:mM -A -gX -Lfp;Lbb:gU -dS;Lgd:wE(cNotNot);q4 -TailCall_cNotNot;Lbc:gT -fp_and(x -h6 -Lbd:oZ));dF -dJ -qE -dU -oZ -1));Lge:qW -q6);Lgf:w5=hS;q4 -Lfn;Lbe:o9;dI -wE(cDiv);q4 -TailCall_cDiv;Lbf:gT -y/x;q4 -Lap;Lbg:gT -fp_equal -mO -Lbh:dI -Lgg:wE(cEqual);q4 -TailCall_cEqual;Lbi:qM -q5 -Lgh:w5=cNot;g0 -Lgi:wE(cNot);q4 -TailCall_cNot;Lbj:q8 -2 -gH -Lgj:w5=dS;g0 -q4 -Lgd;Lbk:qM -w3 -Lgj;Lbl:gT -fp_less(x -h6 -Lbm:gT -fp_lessOrEq(x -h6 -Lbn:q7=g1 -1)/x;gJ -Lbp:dG -Lgh;Lbq:gT -fp_less -mO -Lca:gT -fp_lessOrEq -mO -Lcc:gT -fp_max(x -h6 -Lcd:gT -fp_min(x -h6 -Lce:gT -fp_mod -mO -Lcf:gU -cSqr;Lgk:wE(cSqr);q4 -TailCall_cSqr;Lcg:mM -cSqr);Lgl:w5=cNeg;g0 -wE(cNeg);q4 -TailCall_cNeg;Lch:hV -3 -gC -cSqr);dM -Lgl;Lci:q7=x+g1 -1);hE=q6 -q9 -2 -gC -cPow);gJ -Lcj:gG -q4 -Lfl;Lck:gT -x;Lgm:dG -Lfk;Lcl:qF1 -qM -Lgn:hV -4 -gH -Lgo:o6 -x);Lgp:qW -q6 -gX -Lfk;Lcm:qM -q4 -Lgn;Lcn:q8 -4 -gC -B -gX -Lgo;Lco:q8 -oR -q4 -Lgo;Lcp:qK -dJ -q4 -Lcb;Lcq:dI -q4 -Lfl;Lda:q7=x+x;q4 -Lcj;Ldb:gT -x;qL -4]dJ -q8 -4 -dT -o6 -y*x -q71);dM -Lgf;Ldc:gT -x;d7 -dU -qF -y*x -gX -Lge;Ldd:q8 -4 -dT -qF -x+x -gX -Lgp;Lde:qF1 -q8 -oR -gJ -Ldf:qG1 -q4 -Lgm;Ldg:o9;q4 -Lcq;Ldh:gT -x;qL -4]dJ -q8 -4 -dT -o6 -y*x -q71);dM -Lgc;Ldi:qG1 -q4 -Lap;Ldj:qM -w3 -Lgl;Ldk:dF=cDup;dW-=1;qM -Lgq:w5=hS;q4 -Lfo;Ldl:hV -2 -gH -Lha:qE -cSqr -gX -Lfk;Ldm:hV -oR -q4 -Lha;Ldn:gT -fp_nequal -mO -Ldo:dI -Lhb:wE(cNEqual);q4 -TailCall_cNEqual;Ldp:o9;g6 -oS;Ldq:o9;gJ -Lea:g6 -q4 -Lgi;Leb:q1 -cAbsNotNot);gJ -Lec:q5 -Lel:qE -cAbsNot);gJ -Led:o9;Lej:gU -w8;q4 -Lgg;Lee:gU -cNEqual;q4 -Lhb;Lef:gU -cLessOrEq;wE(cLessOrEq);q4 -TailCall_cLessOrEq;Leg:gU -cLess;wE(cLess);q4 -TailCall_cLess;Leh:gU -dK;wE(cGreaterOrEq);q4 -TailCall_cGreaterOrEq;Lei:gU -o1;wE(cGreater);q4 -TailCall_cGreater;Lek:q7=fp_not -m6 -Lem:o9;q4 -Lee;Len:gT -fp_or(x -h6 -Leo:qM -q5 -w5=cInv;g0 -wE(cInv);q4 -TailCall_cInv;Lep:oZ));dF -dJ -q4 -Lfj;Leq:g6 -q4 -Lgk;Lfa:g6 -q4 -Lgq;Lfb:gT -y-x;q4 -Lap;Lfc:o9;q4 -Lgq;Lfd:q8 -oV -oJ -hS -o7 -x -q71 -gX -Lfq;Lfe:mM -A -oJ -cSub -gX -Lfq;Lff:gT -x-y;d7 -A);gJ -Lfg:o9;qK -dJ -q1 -OppositeComparisonOpcode(A));gJ -Lfh:qW -cDup);gJ -Lfi:dF=cDup;gJ -gJ -q4 -TailCall_cAnd;q4 -TailCall_cMax;q4 -TailCall_cMin;q4 -TailCall_cMod;q4 -TailCall_cNeg;q4 -TailCall_cOr;q4 -TailCall_cRDiv;q4 -TailCall_cSub; -#endif -#if((FP_COMPLEX_VERSION) && !(FP_FLOAT_VERSION)) -dH -x;dH -gE -A;hT -C;hT -D;qQ -w5){TailCall_cAbs:g5 -cAbs:qS -h0} -qH -TailCall_cAdd:g5 -hG -Lad;qT -h3 -hL]==hS){if(qL -gZ -Lae;} -h8} -q4 -dX -qU -d2 -gF -h1 -wB(313,"cDup" -a7 -aZ,"[x+Value_t(1)]" -wH,wN);q4 -Laf;} -} -q4 -dX -oF -wB(199,qC1 -aZ,"cSub" -,);q4 -Lag -gY -hK -qZ -mW(127,aY"cAdd" -mD,"[y+x]" -aZ,q81);q4 -Lah;qT -cRSub:qQ -hE -d3 -3 -qZ -mW(298,aY"cAdd" -mE -mD,mN -aZ -mE,q81);q4 -Lai;qT -hI -wB(299,m0 -a6 -mD,"[-x]" -aZ -mE,wN);q4 -Laj -qU -q6:mW(297,aY -a6 -mD,mN -mE,q81);q4 -Lak;qT -oA -Lal;qT -hI -wB(293,m0"B[IsVarOpcode(B)]" -aW -mD,"[-x]" -aZ" B" -aW,wA"," -a8(B)wM);q4 -Lam -qU -q6:mW(291,aY"B[IsVarOpcode(B)]" -aW -mD,mN" B" -aW,wA"," -a8(B)<<"," -a1);q4 -Lan;} -w9 -mW(105,aY -aF,"[y+x]" -,q81);q4 -Lao;} -g8)){wB(57,"x[x==Value_t()]" -aZ,,wN);q4 -Lap;h8 -g7 -dX:;A=dF -w0 -oY -cRSub -dV -wB(290,"x" -mE -a3"cAdd" -,"[DO_STACKPLUS1] A [x]" -aZ -mE,aI(A)qD1 -wM);incStackPtr();--mStackPtr;q4 -Laq;} -wB(295,a6 -a3"cAdd" -,"[DO_STACKPLUS1] A" -aZ -mE,aI(A)wM);incStackPtr();--mStackPtr;q4 -Lba;} -qG -TailCall_cAnd:g5 -cAnd -hH -wB(224,mX"cAnd" -,aJ,);q4 -Lbb -gY -m9(117,mA"cAnd" -,"[fp_and(x,y)]" -,q81);q4 -Lbc;h8} -qH -TailCall_cConj:g5 -cConj:qS -cConj:wB(63,mY" " -mY,,);q4 -w7 -wB(193,"x " -mY,"[fp_conj(x)]" -,wN);q4 -Lbe;} -qH -TailCall_cDiv:g5 -cDiv -hH -wB(78,"cDup" -mF,"[Value_t()]" -wH" [Value_t(1)]" -aZ,);q4 -Lbf -gY -if -hF -gQ -hI -wB(125,m0 -a4"cDiv" -,"[-x]" -mF,wN);q4 -Lbg -qU -q6:mW(103,aY -a4"cDiv" -,"[y/x]" -,q81);q4 -Lbh;} -} -g8 -oG -wB(56,wO"cDiv" -,,wN);q4 -Lap;h8} -qH -TailCall_cEqual:g5 -w8:dA -A=dD -wB(421,"A[IsLogicalOpcode(A)] " -wO -aE,"A" -,qB1(A)wM);q4 -Lap;} -} -m9(115,mA -aE,"[fp_equal(y,x)]" -,q81);q4 -Lbi;} -g8 -0 -hU -wB(359,m1 -aE,"[x] " -aE,wN);q4 -Lbj -qU -cSqr:wB(361,q41 -wL -aE,"[x] " -aE,wN);q4 -Lbj;} -wB(411,wL -aE,"cNot" -,wN);q4 -Lbk;qG -TailCall_cGreater:g5 -o1:qY -m9(113,mA -m2,"[fp_less(x,y)]" -,q81);q4 -Lbl;qG -TailCall_cGreaterOrEq:g5 -dK:qY -m9(114,mA -aG,"[fp_lessOrEq(x,y)]" -,q81);q4 -Lbm;qG -TailCall_cImag:g5 -cImag:qS -cAbs:wB(81,mV" " -mZ,"[Value_t()]" -wH,);q4 -Lbn -qU -cReal:wB(80,"cReal " -mZ,"[Value_t()]" -wH,);q4 -Lbn -gY -wB(192,"x " -mZ,"[fp_imag(x)]" -,wN);oS;} -qH -TailCall_cInv:g5 -cInv:qY -if -hF)){wB(101,a4 -aU,"[Value_t(1)/x]" -,wN);q4 -Lbp;qG -TailCall_cLess:g5 -cLess:oL)){A=dE -wB(301,wJ -wL -mJ,mK,qB1(A)wM);q4 -Lbq;} -} -m9(111,mA -mJ,"[fp_less(y,x)]" -,q81);q4 -Lca;qG -TailCall_cLessOrEq:g5 -cLessOrEq:qY -m9(112,mA -aR,"[fp_lessOrEq(y,x)]" -,q81);q4 -Lcb;qG -TailCall_cMax:g5 -cMax -hH -wB(60,mX -mB,,);q4 -w7 -m9(141,mA -mB,"[fp_max(x,y)]" -,q81);q4 -Lcc;} -gP -cDup:hD -wB(66,aK -mQ -a3 -mB,"B" -mQ,aI(A)q91(B)wM);q4 -Lbd;qT -cMax:hD -wB(68,aK" " -mB -a3 -mB,"B " -mB,aI(A)q91(B)wM);q4 -Lbd;h8} -qG -TailCall_cMin:g5 -cMin -hH -wB(59,mX -mC,,);q4 -w7 -m9(140,mA -mC,"[fp_min(x,y)]" -,q81);q4 -Lcd;} -gP -cDup:hD -wB(65,aK -mQ -a3 -mC,"B" -mQ,aI(A)q91(B)wM);q4 -Lbd;qT -cMin:hD -wB(67,aK" " -mC -a3 -mC,"B " -mC,aI(A)q91(B)wM);q4 -Lbd;h8} -qG -TailCall_cMod:g5 -cMod:qY -if -hF)){m9(104,aY -a4"cMod" -,"[fp_mod(y,x)]" -,q81);q4 -Lce;} -qG -TailCall_cMul:g5 -h3 -hH -wB(202,"cDup" -wH,"cSqr" -,);q4 -Lcf -oF -qQ -h9 -cDup:wB(467,"cDup" -aA -wH,"cSqr" -aA,);q4 -Lcg;oH -qK -qO -A)gA -oM -B=hQ -wB(473,aK -wH -a3 -qC1 -wH,m5 -wH -aA,aI(A)q91(B)wM);q4 -Lch;} -} -} -} -q4 -dY -qU -cPow -gM -if -gF -h1 -wB(314,mX -m8 -wH,"[x+Value_t(1)] cPow" -,wN);q4 -Lci;} -} -q4 -dY -gY -g8 -gQ -h3:A=hE -w0 -wB(93,wS" " -wZ,wX,qB1(A)wM);q4 -Lcj;} -q4 -Default3;g7 -Default3:;A=qK -qR -IsBinaryOpcode(A)g2 -h2 -qQ -hE -qV -q6:mW(92,aY -wD,wX,qB1(A)<<"," -a1);q4 -Lck;g7 -B -g4 -IsBinaryOpcode(B)g2 -B)){qQ -oC -qV -q6:mW(96,aY -wK,mK,qB1(A)q91(B)<<"," -a1);q4 -Lcl;g7 -C=oC -qO -C)){wB(94,"C[IsVarOpcode(C)] " -wK,mK,qB1(A)q91(B)<<", C" -wY(C)wM);q4 -Lcm;} -if(gV -C)g2 -C)){wB(95,"C[IsUnaryOpcode(C)&&!HasInvalidRangesOpcode(C)] " -wK,"B " -mK,qB1(A)q91(B)<<", C" -wY(C)wM);q4 -Lcn;} -} -} -if(d1 -B)){wB(90,aX -wD,wX,qB1(A)q91(B)wM);q4 -Lcj;} -if(gV -B)g2 -B)){wB(91,"B[IsUnaryOpcode(B)&&!HasInvalidRangesOpcode(B)] " -wD,mK,qB1(A)q91(B)wM);q4 -Lco;} -} -} -if(d1 -h2 -wB(88,a5" " -wZ,"[x]" -,qB1(A)wM);q4 -Lcp;} -if(gV -A)g2 -h2 -wB(89,"A[IsUnaryOpcode(A)&&!HasInvalidRangesOpcode(A)] " -wZ,wX,qB1(A)wM);q4 -Lcq;} -} -} -qQ -h9 -hS:qQ -hE -qV -cDup:wB(317,aH -a7,"[x+x]" -wH,wN);q4 -Lda -qU -o5 -3 -qZ -hO -A=qL -4]w0 -wB(386,a5" y" -wH -aZ -a7,wX" A " -m3 -aZ,wA", " -aY"= " -<mByteCode.size()>1] A[IsUnaryOpcode(A)]" -wH,"D C cSqr" -wH,aI(A)q91(B)<<", C" -wY(C)<<", D" -wY(D)wM);q4 -Ldm;} -} -} -} -qG -TailCall_cNEqual:g5 -cNEqual:dA -A=dD -wB(422,"A[IsLogicalOpcode(A)] " -wO -wW,"A" -a0,qB1(A)wM);q4 -Lbk;} -} -m9(116,mA -wW,"[fp_nequal(y,x)]" -,q81);q4 -Ldn;} -g8 -0 -hU -wB(360,m1 -wW,"[x] " -wW,wN);q4 -Ldo -qU -cSqr:wB(362,q41 -wL -wW,"[x] " -wW,wN);q4 -Ldo;} -wB(412,wL -wW,aJ,wN);q4 -Ldp;qG -TailCall_cNeg:g5 -hI -qS -h3 -gM -wB(123,"x" -wH -aA,mI,wN);q4 -Ldq;qT -hI -wB(61,qC1 -aA,,);q4 -w7 -wB(100,"x" -aA,"[-x]" -,wN);q4 -Lea;} -qH -TailCall_cNot:g5 -cNot:qS -cAbsNotNot:wB(231,"cAbsNotNot" -a0,aS,);q4 -Leb -qU -hS -gM -wB(424,aF -a0,"[-x] " -aE,wN);q4 -Lec;qT -w8:wB(220,aE -a0,wW,);q4 -Led -qU -o1:wB(218,m2 -a0,aR,);q4 -Lee -qU -dK:wB(219,aG -a0,mJ,);q4 -Lef -qU -cLess:wB(216,mJ -a0,aG,);q4 -Leg -qU -cLessOrEq:wB(217,aR -a0,m2,);q4 -Leh -qU -cNEqual:wB(221,wW -a0,aE,);q4 -Lei -qU -cNot:wB(229,"cNot" -a0,aJ,);q4 -Lbb -qU -dS:wB(230,aJ -a0,"cNot" -,);q4 -Lej -gY -wB(107,"x" -a0,"[fp_not(x)]" -,wN);q4 -Lek;} -qH -TailCall_cNotNot:g5 -dS:qS -hS -gM -wB(423,aF" " -aJ,"[-x] " -wW,wN);q4 -Lel;qT -cNot:wB(232,"cNot " -aJ,"cNot" -,);gJ} -qH -TailCall_cOr:g5 -cOr -hH -wB(223,mX"cOr" -,aJ,);q4 -Lbb -gY -m9(118,mA"cOr" -,"[fp_or(x,y)]" -,q81);q4 -Lem;h8} -qH -TailCall_cRDiv:g5 -cRDiv:dA -wB(268,wO"cRDiv" -,aU,wN);q4 -Len;qG -TailCall_cRSub:g5 -cRSub -d4 -q0[0 -h1 -wB(77,"cDup" -mE,"[Value_t()]" -wH,);q4 -Lbn;} -qH -TailCall_cReal:g5 -cReal:qY -wB(191,"x cReal" -,"[fp_real(x)]" -,wN);q4 -Leo;} -qH -TailCall_cSqr:g5 -cSqr:qS -cAbs:wB(204,mV" cSqr" -,"cSqr" -,);q4 -Lep -oF -wB(203,m0"cSqr" -,"cSqr" -,);q4 -Lep;} -qH -TailCall_cSub:g5 -cSub -hH -wB(76,"cDup" -aW,"[Value_t()]" -wH,);q4 -Lbn -oF -wB(200,qC1 -aW,"cAdd" -,);q4 -Leq -gY -g8)){wB(58,"x[x==Value_t()]" -aW,,wN);q4 -Lap;} -m9(106,aY"x" -aW,"[y-x]" -,q81);q4 -Lfa;} -wB(51,"x" -aW,"[-x]" -aZ,wN);q4 -Lfb -gR -w0 -oY -cRSub -dV -wB(289,"x" -mE -a3"cSub" -,"A" -aZ" [x]" -mE,aI(A)qD1 -wM);q4 -Lfc;} -wB(296,a6 -a3"cSub" -,"[DO_STACKPLUS1] A" -aW -mE,aI(A)wM);incStackPtr();--mStackPtr;q4 -Lfd;} -qG -g7 -Default0:;A=w5 -w1 -0){B=q0[0 -hZ -wB(475,aK" A[IsVarOpcode(A)&&mData->mByteCode.size()>0]" -,"B" -mQ,aI(A)q91(B)wM);q4 -Lfe;} -} -if(gV -h2 -B=dF -qO -B -qP -1){C=qK -qR -C==A){D -g4 -D==B){wB(476,"D[D==B] C[C==A] B[IsVarOpcode(B)&&mData->mByteCode.size()>1] A[IsUnaryOpcode(A)]" -,"D C" -mQ,aI(A)q91(B)<<", C" -wY(C)<<", D" -wY(D)wM);q4 -Lff;} -} -} -} -} -q4 -Laa;Laa:qW -w5);gJ -Lab:g6 -wE(cAbs);q4 -TailCall_cAbs;Lac:q7=dP;gJ -Lad:oZ -4));gG -Lfg:w5=h3;Lfh:g0 -Lfi:wE(cMul);q4 -TailCall_cMul;Lae:hV -4 -dT -oZ -4)q71 -gX -Lfg;Laf:q7=x+g1 -1);gG -Lbq:w5=h3;q4 -Lfi;Lag:gU -cSub;Lfj:wE(cSub);q4 -TailCall_cSub;Lah:hW -2 -gH -Lfk:g0 -Lfl:wE(cAdd);q4 -TailCall_cAdd;Lai:hW -oR -Lfm:qE -hS);Lfn:w5=cRSub;g0 -wE(cRSub);q4 -TailCall_cRSub;Laj:o9;qL -2 -gK -q4 -Lfm;Lak:hW -2 -gH -q4 -Lfn;Lal:hW -4 -gH -Lfo:qE -hS);Lfp:qE -B);Lfq:w5=cSub;g0 -q4 -Lfj;Lam:o9;oC=q6 -q9 -oR -q4 -Lfo;Lan:hW -oR -q4 -Lfp;Lao:gT -y+x;Lap:qM -Lbd:q5 -gJ -Laq:q8 -oV -o7 -x -q71 -gX -Lfm;Lba:mM -A -gX -Lfm;Lbb:gU -dS;Lga:wE(cNotNot);q4 -TailCall_cNotNot;Lbc:gT -fp_and(x -h6 -Lbe:q7=fp_conj -m6 -Lbf:oZ));dF -dJ -qE -dU -oZ -1));Lgb:qW -q6);Lgc:w5=hS;q4 -Lfk;Lbg:o9;dI -wE(cDiv);q4 -TailCall_cDiv;Lbh:gT -y/x;q4 -Lap;Lbi:gT -fp_equal -mO -Lbj:dI -Lgd:wE(cEqual);q4 -TailCall_cEqual;Lbk:qM -q5 -w5=cNot;g0 -Lge:wE(cNot);q4 -TailCall_cNot;Lbl:gT -fp_less(x -h6 -Lbm:gT -fp_lessOrEq(x -h6 -Lbn:oZ));dF -dJ -q4 -Lfg;Lbo:q7=fp_imag -m6 -Lbp:q7=g1 -1)/x;gJ -Lca:gT -fp_less -mO -Lcb:gT -fp_lessOrEq -mO -Lcc:gT -fp_max(x -h6 -Lcd:gT -fp_min(x -h6 -Lce:gT -fp_mod -mO -Lcf:gU -cSqr;Lgf:wE(cSqr);q4 -TailCall_cSqr;Lcg:mM -cSqr);Lgg:w5=cNeg;g0 -wE(cNeg);q4 -TailCall_cNeg;Lch:hV -3 -gC -cSqr);dM -Lgg;Lci:q7=x+g1 -1);hE=q6 -q9 -2 -gC -cPow);gJ -Lcj:gG -q4 -Lfi;Lck:gT -x;Lgh:dG -Lfh;Lcl:qF1 -qM -Lgi:hV -4 -gH -Lgj:o6 -x);Lgk:qW -q6 -gX -Lfh;Lcm:qM -q4 -Lgi;Lcn:q8 -4 -gC -B -gX -Lgj;Lco:q8 -oR -q4 -Lgj;Lcp:qK -dJ -q4 -Lbd;Lcq:dI -q4 -Lfi;Lda:q7=x+x;q4 -Lcj;Ldb:gT -x;qL -4]dJ -q8 -4 -dT -o6 -y*x -q71);dM -Lgc;Ldc:gT -x;d7 -dU -qF -y*x -gX -Lgb;Ldd:q8 -4 -dT -qF -x+x -gX -Lgk;Lde:qF1 -q8 -oR -gJ -Ldf:qG1 -q4 -Lgh;Ldg:o9;q4 -Lcq;Ldh:gT -x;qL -4]dJ -q8 -4 -dT -o6 -y*x -q71);dM -Lfq;Ldi:qG1 -q4 -Lap;Ldj:qM -w3 -Lgg;Ldk:dF=cDup;dW-=1;qM -Lgl:w5=hS;q4 -Lfl;Ldl:hV -2 -gH -Lgm:qE -cSqr -gX -Lfh;Ldm:hV -oR -q4 -Lgm;Ldn:gT -fp_nequal -mO -Ldo:dI -Lgn:wE(cNEqual);q4 -TailCall_cNEqual;Ldp:qM -q5 -w5=dS;g0 -q4 -Lga;Ldq:o9;g6 -q4 -Lbq;Lea:o9;gJ -Leb:q1 -cAbsNot);gJ -Lec:o9;Lei:gU -w8;q4 -Lgd;Led:gU -cNEqual;q4 -Lgn;Lee:gU -cLessOrEq;wE(cLessOrEq);q4 -TailCall_cLessOrEq;Lef:gU -cLess;wE(cLess);q4 -TailCall_cLess;Leg:gU -dK;wE(cGreaterOrEq);q4 -TailCall_cGreaterOrEq;Leh:gU -o1;wE(cGreater);q4 -TailCall_cGreater;Lej:g6 -q4 -Lge;Lek:q7=fp_not -m6 -Lel:o9;q4 -Led;Lem:gT -fp_or(x -h6 -Len:qM -q5 -w5=cInv;g0 -wE(cInv);q4 -TailCall_cInv;Leo:q7=fp_real -m6 -Lep:g6 -q4 -Lgf;Leq:g6 -q4 -Lgl;Lfa:gT -y-x;q4 -Lap;Lfb:o9;q4 -Lgl;Lfc:q8 -oV -oJ -hS -o7 -x -q71 -gX -Lfn;Lfd:mM -A -oJ -cSub -gX -Lfn;Lfe:qW -cDup);gJ -Lff:dF=cDup;gJ -gJ -q4 -TailCall_cAnd;q4 -TailCall_cConj;q4 -TailCall_cImag;q4 -TailCall_cMax;q4 -TailCall_cMin;q4 -TailCall_cMod;q4 -TailCall_cNeg;q4 -TailCall_cOr;q4 -TailCall_cRDiv;q4 -TailCall_cReal;q4 -TailCall_cSub; -#endif -#if((FP_FLOAT_VERSION) && !(FP_COMPLEX_VERSION)) -dH -x;hT -A;dH -gE -C;hT -D;qQ -w5){TailCall_cAbs:g5 -cAbs:qS -h0 -oH -dF -qR -qX -wB(393,wJ -mV,"A" -,aI(A)wM);gJ -qG -TailCall_cAcos:g5 -cAcos:hN<=m7(148,"x[fp_abs(x)<=Value_t(1)] cAcos" -,"[fp_acos(x)]" -,wN);q4 -Lad;qG -TailCall_cAcosh:g5 -cAcosh:qY -if(x>=m7(145,"x[x>=Value_t(1)] cAcosh" -,"[fp_acosh(x)]" -,wN);q4 -Lae;qG -TailCall_cAdd:g5 -hG -Laf;qT -h3 -hL]==hS){if(qL -gZ -Lag;} -h8} -q4 -dX -qU -d2 -gF -h1 -wB(313,"cDup" -a7 -aZ,"[x+Value_t(1)]" -wH,wN);q4 -Lah;} -} -q4 -dX -oF -wB(199,qC1 -aZ,"cSub" -,);q4 -Lai -gY -hK -qZ -mW(127,aY"cAdd" -mD,"[y+x]" -aZ,q81);q4 -Laj;qT -cRSub:qQ -hE -d3 -3 -qZ -mW(298,aY"cAdd" -mE -mD,mN -aZ -mE,q81);q4 -Lak;qT -hI -wB(299,m0 -a6 -mD,"[-x]" -aZ -mE,wN);q4 -Lal -qU -q6:mW(297,aY -a6 -mD,mN -mE,q81);q4 -Lam;qT -oA -Lan;qT -hI -wB(293,m0"B[IsVarOpcode(B)]" -aW -mD,"[-x]" -aZ" B" -aW,wA"," -a8(B)wM);q4 -Lao -qU -q6:mW(291,aY"B[IsVarOpcode(B)]" -aW -mD,mN" B" -aW,wA"," -a8(B)<<"," -a1);q4 -Lap;} -w9 -mW(105,aY -aF,"[y+x]" -,q81);q4 -Laq;} -g8)){wB(57,"x[x==Value_t()]" -aZ,,wN);q4 -Lba;h8 -g7 -dX:;A=dF -w0 -oY -cRSub -dV -wB(290,"x" -mE -a3"cAdd" -,"[DO_STACKPLUS1] A [x]" -aZ -mE,aI(A)qD1 -wM);incStackPtr();--mStackPtr;q4 -Lbb;} -wB(295,a6 -a3"cAdd" -,"[DO_STACKPLUS1] A" -aZ -mE,aI(A)wM);incStackPtr();--mStackPtr;q4 -Lbc;} -qG -TailCall_cAnd:g5 -cAnd -hH -wB(224,mX"cAnd" -,aJ,);q4 -w7 -m9(117,mA"cAnd" -,"[fp_and(x,y)]" -,q81);q4 -Lbe;h8} -qH -TailCall_cAsin:g5 -cAsin:hN<=m7(149,"x[fp_abs(x)<=Value_t(1)] cAsin" -,"[fp_asin(x)]" -,wN);q4 -Lbf;qG -TailCall_cAsinh:g5 -cAsinh:qY -wB(146,"x cAsinh" -,"[fp_asinh(x)]" -,wN);q4 -Lbg;} -qH -TailCall_cAtan:g5 -cAtan:qY -wB(150,"x cAtan" -,"[fp_atan(x)]" -,wN);q4 -Lbh;} -qH -TailCall_cAtan2:g5 -cAtan2:qY -m9(139,mA"cAtan2" -,"[fp_atan2(y,x)]" -,q81);q4 -Lbi;qG -TailCall_cAtanh:g5 -cAtanh:hN()]" -wH" " -wR,"cDeg" -,q81);q4 -Ldd;} -if((y/x)==fp_const_deg_to_rad -h7 -wB(322,"y[(y/x)==fp_const_deg_to_rad()]" -wH" " -wR,"cRad" -,q81);q4 -Lde;} -wB(323,"y" -wH" " -wR,"[y/x]" -wH,q81);q4 -Ldf;} -} -wB(325,wR,"[Value_t(1)/x]" -wH,wN);q4 -Ldg;} -gP -cDiv:hC -wB(271,aX"cDiv " -wV,"[DO_STACKPLUS1] B A" -wH -mF,aI(A)q91(B)wM);incStackPtr();--mStackPtr;q4 -Ldh;qT -cRDiv:qQ -hE -qV -hM -wB(266,"x" -a9" " -wV,"A" -wH" [x]" -a9,aI(A)qD1 -wM);q4 -Ldi;g7 -hC -wB(265,"B[IsVarOpcode(B)]" -a9" " -wV,"A" -wH" B" -a9,aI(A)q91(B)wM);q4 -Ldj;} -h8} -qG -TailCall_cEqual:g5 -w8:oL -hU -wB(359,m1 -aE,"[x] " -aE,wN);q4 -Ldk -qU -cSqr:wB(361,q41 -wL -aE,"[x] " -aE,wN);q4 -Ldk;} -} -m9(115,mA -aE,"[fp_equal(y,x)]" -,q81);q4 -Ldl;qG -TailCall_cExp:g5 -w2 -qS -hS -gM -wB(404,aF -mL,q21"[fp_exp(x)]" -wH,wN);q4 -Ldm;qT -cLog:A=dE -wB(340,wJ -mG -mL,"A" -,aI(A)wM);q4 -oN -hM -wB(154,"x" -mL,"[fp_exp(x)]" -,wN);q4 -Ldo;} -qH -TailCall_cExp2:g5 -cExp2:qS -hS -gM -wB(405,aF -q31,"cExp2 [fp_exp2(x)]" -wH,wN);q4 -Ldp;qT -cLog2:A=dE -wB(341,wJ -aN -q31,"A" -,aI(A)wM);q4 -oN -hM -wB(155,"x" -q31,"[fp_exp2(x)]" -,wN);q4 -Ldq;} -wB(479,"cExp2" -,"[DO_STACKPLUS1] [fp_log(Value_t(2))]" -wH -mL,);incStackPtr();--mStackPtr;q4 -Lea;TailCall_cFloor:g5 -cFloor:qS -hI -wB(401,m0 -mS,q01 -aA,);q4 -Leb -gY -wB(136,"x " -mS,"[fp_floor(x)]" -,wN);q4 -Lec -gS -wB(395,"A[IsAlwaysIntegerOpcode(A)] " -mS,"A" -,aI(A)wM);gJ -qG -TailCall_cGreater:g5 -o1:qY -m9(113,mA -m2,"[fp_less(x,y)]" -,q81);q4 -Led;} -g8-oO -wB(431,"x[x==Value_t(-0.5)] " -m2,m0 -aS,wN);q4 -Lee;qG -TailCall_cGreaterOrEq:g5 -dK:qY -dB -cAbs){wB(427,mV" x[x!=Value_t(0)] " -aG,"[Value_t(0.5)/x]" -wH" " -aJ,wN);q4 -Lef;} -} -m9(114,mA -aG,"[fp_lessOrEq(x,y)]" -,q81);q4 -Leg;} -g8 -oO -wB(430,"x[x==Value_t(0.5)] " -aG,"cAbsNotNot" -,wN);q4 -Leh;qG -TailCall_cHypot:g5 -cHypot -d4 -dF==cSinCos){wB(84,"cSinCos cHypot" -,"[Value_t()]" -wH" [Value_t(1)]" -aZ,);q4 -Lci;} -qH -TailCall_cInt:g5 -cInt:qS -hM -wB(137,"x cInt" -,"[fp_int(x)]" -,wN);q4 -Lei -gS -wB(397,"A[IsAlwaysIntegerOpcode(A)] cInt" -,"A" -,aI(A)wM);gJ -qG -TailCall_cInv:g5 -cInv:qS -cCos:wB(256,aO" " -aU,"cSec" -,);q4 -Lej -qU -cCot:wB(260,"cCot " -aU,mR,);q4 -Lcp -qU -cCsc:wB(258,"cCsc " -aU,mP,);q4 -Lek -qU -cInv:wB(62,aU" " -aU,,);q4 -Ldn -qU -cPow:wB(355,q61 -aU,m0"cPow" -,);q4 -Lel -qU -cSec:wB(259,"cSec " -aU,aO,);q4 -Lem -qU -cSin:wB(255,mP" " -aU,"cCsc" -,);q4 -Len -qU -cSqrt:wB(206,q51" " -aU,"cRSqrt" -,);q4 -Leo -qU -cTan:wB(257,mR" " -aU,"cCot" -,);q4 -Lep -gY -if -hF)){wB(101,a4 -aU,"[Value_t(1)/x]" -,wN);q4 -Leq;h8} -qH -TailCall_cLess:g5 -cLess:oL)){A=dE -wB(301,wJ -wL -mJ,mK,qB1(A)wM);q4 -Lfa;} -} -dB -cAbs){wB(426,mV" x[x!=Value_t(0)] " -mJ,"[Value_t(0.5)/x]" -wH -a0,wN);q4 -Lfb;} -} -m9(111,mA -mJ,"[fp_less(y,x)]" -,q81);q4 -Lfc;} -g8 -oO -wB(429,"x[x==Value_t(0.5)] " -mJ,aS,wN);q4 -Lfd;qG -TailCall_cLessOrEq:g5 -cLessOrEq:qY -m9(112,mA -aR,"[fp_lessOrEq(y,x)]" -,q81);q4 -Lfe;} -g8-oO -wB(432,"x[x==Value_t(-0.5)] " -aR,m0"cAbsNotNot" -,wN);q4 -Lff;qG -TailCall_cLog:g5 -cLog:mT(343,q21 -mG,,);q4 -Ldn -qU -gL -wB(491,mU -mG,mG" [fp_log(x)]" -aZ,wN);q4 -Lfg;} -o2 -wB(303,q41 -mG,mV" " -mG" " -aH,);q4 -Lfh -aV(156,wQ" " -mG,"[fp_log(x)]" -,wN);q4 -Lfi;h8} -qH -TailCall_cLog10:g5 -cLog10:mT(481,q21 -aL,"[DO_STACKPLUS1] [fp_log10(fp_const_e())]" -wH,);incStackPtr();--mStackPtr;q4 -Lfj -qU -gL -wB(492,mU -aL,aL" [fp_log10(x)]" -aZ,wN);q4 -Lfk;} -o2 -wB(305,q41 -aL,mV" " -aL" " -aH,);q4 -Lfl -aV(157,wQ" " -aL,"[fp_log10(x)]" -,wN);q4 -Lfm;h8} -qH -TailCall_cLog2:g5 -cLog2:mT(480,q21 -aN,"[DO_STACKPLUS1] [fp_log2(fp_const_e())]" -wH,);incStackPtr();--mStackPtr;q4 -Lfn -qU -cExp2:wB(344,"cExp2 " -aN,,);q4 -Ldn -qU -gL -wB(490,mU -aN,aN" [fp_log2(x)]" -aZ,wN);q4 -Lfo;} -o2 -wB(304,q41 -aN,mV" " -aN" " -aH,);q4 -Lfp -aV(158,wQ" " -aN,"[fp_log2(x)]" -,wN);q4 -Lfq;h8} -qH -TailCall_cMax:g5 -cMax -hH -wB(60,mX -mB,,);q4 -Ldn -gY -m9(141,mA -mB,"[fp_max(x,y)]" -,q81);q4 -Lga;} -gP -cDup:hD -wB(66,aK -mQ -a3 -mB,"B" -mQ,aI(A)q91(B)wM);q4 -oN -cMax:hD -wB(68,aK" " -mB -a3 -mB,"B " -mB,aI(A)q91(B)wM);q4 -Ldn;h8} -qG -TailCall_cMin:g5 -cMin -hH -wB(59,mX -mC,,);q4 -Ldn -gY -m9(140,mA -mC,"[fp_min(x,y)]" -,q81);q4 -Lgb;} -gP -cDup:hD -wB(65,aK -mQ -a3 -mC,"B" -mQ,aI(A)q91(B)wM);q4 -oN -cMin:hD -wB(67,aK" " -mC -a3 -mC,"B " -mC,aI(A)q91(B)wM);q4 -Ldn;h8} -qG -TailCall_cMod:g5 -cMod:qY -if -hF)){m9(104,aY -a4"cMod" -,"[fp_mod(y,x)]" -,q81);q4 -Lgc;} -qG -TailCall_cMul:g5 -h3:qS -cCsc:A=qK -w1 -3 -gA]==cCos){B=hQ -wB(508,aK" " -aO" A[IsVarOpcode(A)&&mData->mByteCode.size()>3] cCsc" -wH,"B cCot" -,aI(A)q91(B)wM);q4 -Lgd;} -} -} -q4 -dY -qU -cDup:wB(202,"cDup" -wH,"cSqr" -,);q4 -Lge -qU -cInv:wB(214,aU -wH,"cDiv" -,);q4 -Lgf -oF -qQ -h9 -cDup:wB(467,"cDup" -aA -wH,"cSqr" -aA,);q4 -Lgg;oH -qK -qO -A)gA -oM -B=hQ -wB(473,aK -wH -a3 -qC1 -wH,m5 -wH -aA,aI(A)q91(B)wM);q4 -Lgh;} -} -} -} -q4 -dY -qU -cPow -gM -if -gF -h1 -wB(314,mX -m8 -wH,"[x+Value_t(1)] cPow" -,wN);q4 -Lgi;} -} -q4 -dY -gY -g8 -gQ -h3:A=hE -w0 -wB(93,wS" " -wZ,wX,qB1(A)wM);q4 -Lgj;} -q4 -Default3;g7 -Default3:;A=qK -qR -IsBinaryOpcode(A)g2 -h2 -qQ -hE -qV -q6:mW(92,aY -wD,wX,qB1(A)<<"," -a1);q4 -Lgk;g7 -B -g4 -IsBinaryOpcode(B)g2 -B)){qQ -oC -qV -q6:mW(96,aY -wK,mK,qB1(A)q91(B)<<"," -a1);q4 -Lgl;g7 -C=oC -qO -C)){wB(94,"C[IsVarOpcode(C)] " -wK,mK,qB1(A)q91(B)<<", C" -wY(C)wM);q4 -Lgm;} -if(gV -C)g2 -C)){wB(95,"C[IsUnaryOpcode(C)&&!HasInvalidRangesOpcode(C)] " -wK,"B " -mK,qB1(A)q91(B)<<", C" -wY(C)wM);q4 -Lgn;} -} -} -if(d1 -B)){wB(90,aX -wD,wX,qB1(A)q91(B)wM);q4 -Lgj;} -if(gV -B)g2 -B)){wB(91,"B[IsUnaryOpcode(B)&&!HasInvalidRangesOpcode(B)] " -wD,mK,qB1(A)q91(B)wM);q4 -Lgo;} -} -} -if(d1 -h2 -wB(88,a5" " -wZ,"[x]" -,qB1(A)wM);q4 -Lgp;} -if(gV -A)g2 -h2 -wB(89,"A[IsUnaryOpcode(A)&&!HasInvalidRangesOpcode(A)] " -wZ,wX,qB1(A)wM);q4 -Lgq;} -} -} -qQ -h9 -hS:qQ -hE -qV -cDup -d4 -x+oU -wB(316,"cDup[x+x==Value_t(1)]" -aZ -a7,,wN);q4 -Lha;} -wB(317,aH -a7,"[x+x]" -wH,wN);q4 -Lhb -qU -o5 -3 -qZ -hO -A=qL -4]w0 -wB(386,a5" y" -wH -aZ -a7,wX" A " -m3 -aZ,wA", " -aY"= " -<()]" -wH -a7,"cDeg" -,q81);q4 -Ldd;} -if((y*x)==fp_const_deg_to_rad -h7 -wB(308,"y[(y*x)==fp_const_deg_to_rad()]" -wH -a7,"cRad" -,q81);q4 -Lde;} -wB(128,"y" -wH -a7,m3,q81);q4 -Lhl;qT -hI -wB(122,qC1 -a7,mI,wN);q4 -Lhm -qU -cRDiv:qQ -hE -qV -o5 -3 -qZ -mW(285,"y" -wH -a9 -a7,m3 -a9,q81);q4 -Lhn;qT -hI -wB(286,qC1 -a9 -a7,mI -a9,wN);q4 -Lho -qU -q6:mW(284,"y" -a9 -a7,"[y*x]" -a9,q81);q4 -Lhp;qT -cRad:wB(210,"cRad" -a7,"[DegreesToRadians(x)]" -wH,wN);q4 -Lhq -qU -cSub -hL -oM -if(qL -3 -qZ -hO -A=qL -4]w0 -wB(387,a5" y" -wH -aW -a7,wX" A " -m3 -aW,wA", " -aY"= " -<()]" -wH,"cDeg" -,wN);q4 -Lie;} -if(x==fp_const_deg_to_rad -h7 -wB(208,"x[x==fp_const_deg_to_rad()]" -wH,"cRad" -,wN);q4 -Lif;h8 -g7 -dY:;A=dF -qO -A -gQ -cDiv:hC -wB(274,aX"cDiv " -wS,"[DO_STACKPLUS1] A" -wH -qH1,aI(A)q91(B)wM);incStackPtr();--mStackPtr;q4 -Lig;} -q4 -d5 -h3:qQ -hE -qV -hI -B=hQ -wB(470,aK -aA -wH" " -wS,m5 -wH -aA,aI(A)q91(B)wM);q4 -Lgh;} -q4 -dZ;g7 -dZ:;hD -wB(461,aK -wH" " -wS,m5 -wH,aI(A)q91(B)wM);q4 -Lih;} -} -q4 -d5 -hI -hD -wB(464,aK -aA" " -wS,m5 -aA,aI(A)q91(B)wM);q4 -Lgg;} -q4 -d5 -cRDiv -hL -qZ -qC -wB(267,"x" -a9" " -wS,"[DO_STACKPLUS1] " -mK -a9,aI(A)qD1 -wM);incStackPtr();--mStackPtr;q4 -Lii;} -wB(281,"cRDiv " -wS,"[DO_STACKPLUS1] A" -wH -a9,aI(A)wM);incStackPtr();--mStackPtr;q4 -Lij;g7 -Default4:;B=qK -qR -w4 -wB(458,aK" " -wS,m5,aI(A)q91(B)wM);q4 -Lge;} -} -} -if(gV -h2 -B=qK -qO -B -qP -1 -gA -oM -C=oC -qR -C==A){D=qL -4]qR -D==B){wB(477,"D[D==B] C[C==A]" -wH" B[IsVarOpcode(B)&&mData->mByteCode.size()>1] A[IsUnaryOpcode(A)]" -wH,"D C cSqr" -wH,aI(A)q91(B)<<", C" -wY(C)<<", D" -wY(D)wM);q4 -Lik;} -} -} -} -qG -TailCall_cNEqual:g5 -cNEqual:oL -hU -wB(360,m1 -wW,"[x] " -wW,wN);q4 -Lil -qU -cSqr:wB(362,q41 -wL -wW,"[x] " -wW,wN);q4 -Lil;} -} -m9(116,mA -wW,"[fp_nequal(y,x)]" -,q81);q4 -Lim;qG -TailCall_cNeg:g5 -hI -qS -h3 -gM -wB(123,"x" -wH -aA,mI,wN);q4 -Lin;qT -hI -wB(61,qC1 -aA,,);q4 -Ldn -qU -cSin:g9 -wB(244,"x" -wH" " -mP -aA,mI" " -mP,wN);q4 -Lio;} -qT -oQ -g9 -wB(245,"x" -wH" cSinh" -aA,mI" cSinh" -,wN);q4 -Lip;} -qT -cTan:g9 -wB(246,"x" -wH" " -mR -aA,mI" " -mR,wN);q4 -Liq;} -qT -cTanh:g9 -wB(247,"x" -wH" cTanh" -aA,mI" cTanh" -,wN);q4 -Lja;} -qT -hM -wB(100,"x" -aA,"[-x]" -,wN);q4 -Ljb;} -qH -TailCall_cNot:g5 -cNot:qS -cAbs:wB(227,mV -a0,"cNot" -,);q4 -Ljc -qU -cAbsNot:A=dD -wB(389,"A[IsLogicalOpcode(A)] " -aS -a0,"A" -,aI(A)wM);q4 -Ldn;} -if(A!=q6){wB(390,"A[A!=cImmed] " -aS -a0,"A cAbsNotNot" -,aI(A)wM);q4 -Ljd;} -q4 -o0 -qU -cAbsNotNot:wB(231,"cAbsNotNot" -a0,aS,);q4 -Lje -qU -w8:wB(220,aE -a0,wW,);q4 -Ljf -qU -o1:wB(218,m2 -a0,aR,);q4 -Ljg -qU -dK:wB(219,aG -a0,mJ,);q4 -Ljh -qU -cLess:wB(216,mJ -a0,aG,);q4 -Lji -qU -cLessOrEq:wB(217,aR -a0,m2,);q4 -Ljj -qU -cNEqual:wB(221,wW -a0,aE,);q4 -Ljk -oF -wB(226,qC1 -a0,"cNot" -,);q4 -Ljc -qU -cNot:wB(229,"cNot" -a0,aJ,);q4 -Lbd -qU -dS:wB(230,aJ -a0,"cNot" -,);q4 -Ljc -gY -wB(107,"x" -a0,"[fp_not(x)]" -,wN);q4 -Ljl;g7 -o0:;A=dF -qR -qX -wB(391,wJ"cNot" -,"A " -aS,aI(A)wM);q4 -Ljm;qG -TailCall_cNotNot:g5 -dS -d4 -dF==cNot){wB(232,"cNot " -aJ,"cNot" -,);gJ} -qH -TailCall_cOr:g5 -cOr -hH -wB(223,mX"cOr" -,aJ,);q4 -w7 -m9(118,mA"cOr" -,"[fp_or(x,y)]" -,q81);q4 -Ljn;h8} -qH -TailCall_cPow:g5 -cPow:qY -if(!h5 -x+x)){oY -cSqr){wB(22,q41"x[!isEvenInteger(x+x)] cPow" -,mV" [x+x] cPow" -,wN);q4 -Ljo;} -} -if(isInteger(x -gQ -w2 -wB(43,q21 -wT,wX -mL,wN);q4 -Ljp -qU -cExp2:wB(44,"cExp2 " -wT,wX -q31,wN);q4 -Ljq -qU -cPow -hL -qZ -hP!isInteger(y)){wB(42,"y[!isInteger(y)] " -q61 -wT,aP,q81);q4 -Lka;} -} -wB(45,q61 -wT,wX" cPow" -,wN);q4 -Lkb;} -} -if(h5 -x -hU -wB(434,mV" x[isEvenInteger(x)] cPow" -,"[x] cPow" -,wN);q4 -Lkc -qU -h3 -hL]==cAbs){wB(435,mV -wH" x[isEvenInteger(x)] cPow" -,"cMul [x] cPow" -,wN);q4 -Lkd;h8} -} -g8)){wB(83,"x[x==Value_t()] cPow" -,"[Value_t()]" -wH" [Value_t(1)]" -aZ,wN);q4 -Lke;} -g8 -oO -wB(332,"x[x==Value_t(0.5)] cPow" -,q51,wN);q4 -Lkf;} -g8 -1)/g1 -3)){wB(333,"x[x==Value_t(1)/Value_t(3)] cPow" -,"cCbrt" -,wN);q4 -Lkg;} -g8 -1)/g1-3)){wB(334,"x[x==Value_t(1)/Value_t(-3)] cPow" -,"cCbrt " -aU,wN);q4 -Lkh;} -g8-oO -wB(335,"x[x==Value_t(-0.5)] cPow" -,"cRSqrt" -,wN);q4 -Lki;} -g8-oG -wB(336,"x[x==Value_t(-1)] cPow" -,aU,wN);q4 -Lkj;} -qQ -h9 -cPow -hL -qZ -hP -h5 -y)&&!h5 -x*y)){wB(21,"y[isEvenInteger(y)&&!isEvenInteger(x*y)] " -q61 -m8,mV" " -aP,q81);q4 -Lkk;} -wB(330,aY -q61 -m8,aP,q81);q4 -Lka;o2 -wB(46,q41 -m8,"[x+x] cPow" -,wN);q4 -Lkl -qU -q6:hP -y!=oP||x>=oP){wB(165,"y[y!=Value_t(0)||x>=Value_t(0)] " -m8,"[fp_pow(y,x)]" -,q81);q4 -Lkm;h8} -wB(455,m8,"[DO_POWI]" -,wN)qR -TryCompilePowi(x))gJ} -qH -TailCall_cRDiv:g5 -cRDiv:qS -cSinCos:wB(503,"cSinCos" -a9,"cCot" -,);q4 -Lep -qU -cSinhCosh:wB(510,"cSinhCosh" -a9,"cTanh " -aU,);q4 -Lkn -gY -g8 -oG -wB(268,wO"cRDiv" -,aU,wN);q4 -Lkj;h8} -qH -TailCall_cRSub:g5 -cRSub -d4 -q0[0 -h1 -wB(77,"cDup" -mE,"[Value_t()]" -wH,);q4 -Lko;} -qH -TailCall_cRad:g5 -cRad:qS -h3 -gM -wB(211,"x" -wH" cRad" -,"[DegreesToRadians(x)]" -wH,wN);q4 -Lkp;qT -hM -wB(134,"x cRad" -,"[DegreesToRadians(x)]" -,wN);q4 -Lkq;} -qH -TailCall_cSec:g5 -cSec:A=qN -qQ -h9 -cCos:hD -wB(497,aK" " -aO" " -wI"cSec" -,"B " -aO" " -aT,aI(A)q91(B)wM);q4 -Lbp;qT -cSin:hD -wB(495,aK" " -mP" " -wI"cSec" -,"B cSinCos " -aU,aI(A)q91(B)wM);q4 -Lla;h8 -qG -TailCall_cSin:g5 -cSin:qS -hI -wB(240,m0 -mP,mP -aA,);q4 -Llb -gY -wB(159,"x " -mP,"[fp_sin(x)]" -,wN);q4 -Llc;oH -qN -oY -cCsc -q11(499,aK" cCsc " -wI -mP,"B cCsc " -aT,aI(A)q91(B)wM);q4 -Lbp;} -} -qG -TailCall_cSinh:g5 -oQ -qS -cAcosh:wB(437,"cAcosh cSinh" -,"[DO_STACKPLUS1] " -q41"[Value_t(-1)] " -aQ,);incStackPtr();--mStackPtr;q4 -Lld -qU -cAsinh:wB(349,"cAsinh cSinh" -,,);q4 -Ldn -oF -wB(241,m0"cSinh" -,"cSinh" -aA,);q4 -Lle -gY -wB(160,"x cSinh" -,"[fp_sinh(x)]" -,wN);q4 -Llf;} -qH -TailCall_cSqr:g5 -cSqr:qS -cAbs:wB(204,mV" cSqr" -,"cSqr" -,);q4 -Llg -oF -wB(203,m0"cSqr" -,"cSqr" -,);q4 -Llg -qU -cSqrt:A=dE -wB(338,wJ -q51" cSqr" -,"A" -,aI(A)wM);q4 -Ldn;h8} -qH -TailCall_cSqrt:g5 -cSqrt:qS -hS -d4 -qK -o3 -A=hE -w0 -if(oC -o3 -wB(512,"cSqr" -a3 -q41 -aQ,"A cHypot" -,aI(A)wM);q4 -Llh;} -} -B -g4 -gV -B)){A=oC -w0 -if(qL -4]o3 -wB(513,"cSqr" -a3"B[IsUnaryOpcode(B)] " -q41 -aQ,"A B cHypot" -," with" -a8(B)qE1(A)wM);q4 -Lli;} -} -} -o2 -wB(23,q41 -q51,mV,);q4 -Llj -gY -if(x>=oP){wB(161,"x[x>=Value_t(0)] " -q51,"[fp_sqrt(x)]" -,wN);q4 -Llk;h8} -qH -TailCall_cSub:g5 -cSub -hH -wB(76,"cDup" -aW,"[Value_t()]" -wH,);q4 -Lko -oF -wB(200,qC1 -aW,"cAdd" -,);q4 -Lll -gY -g8)){wB(58,"x[x==Value_t()]" -aW,,wN);q4 -Lba;} -m9(106,aY"x" -aW,"[y-x]" -,q81);q4 -Llm;} -wB(51,"x" -aW,"[-x]" -aZ,wN);q4 -Lln -gR -w0 -oY -cRSub -dV -wB(289,"x" -mE -a3"cSub" -,"A" -aZ" [x]" -mE,aI(A)qD1 -wM);q4 -Llo;} -wB(296,a6 -a3"cSub" -,"[DO_STACKPLUS1] A" -aW -mE,aI(A)wM);incStackPtr();--mStackPtr;q4 -Llp;} -qG -TailCall_cTan:g5 -cTan:qS -cAtan2:wB(354,"cAtan2 " -mR,"cDiv" -,);q4 -Lgf -oF -wB(242,m0 -mR,mR -aA,);q4 -Llq -gY -wB(163,"x " -mR,"[fp_tan(x)]" -,wN);q4 -Lma;oH -qN -oY -cCot -q11(501,aK" cCot " -wI -mR,"B cCot " -aT,aI(A)q91(B)wM);q4 -Lbp;} -} -qG -TailCall_cTanh:g5 -cTanh:qS -hI -wB(243,m0"cTanh" -,"cTanh" -aA,);q4 -Lmb -gY -wB(164,"x cTanh" -,"[fp_tanh(x)]" -,wN);q4 -Lmc;} -qH -TailCall_cTrunc:g5 -cTrunc:qS -hM -wB(138,"x cTrunc" -,"[fp_trunc(x)]" -,wN);q4 -Lmd -gS -wB(394,"A[IsAlwaysIntegerOpcode(A)] cTrunc" -,"A" -,aI(A)wM);gJ -qG -g7 -Default0:;A=w5 -qR -IsComparisonOpcode(h2 -qY -hK -qZ -mW(364,aY"cAdd" -wF,"[x-y] A" -,aI(A)qD1<<"," -a1);q4 -Lme;qT -cAtan -d4 -dP()*g1 -oO -wB(380,"cAtan[fp_abs(x)()*Value_t(0.5)]" -wF,"[fp_tan(x)] A" -,aI(A)qD1 -wM);q4 -Lmf;qT -cExp -d4 -dO -wB(370,"cExp[x>Value_t(0)]" -wF,"[fp_log(x)] A" -,aI(A)qD1 -wM);q4 -Lmg;qT -cExp2 -d4 -dO -wB(371,"cExp2[x>Value_t(0)]" -wF,"[fp_log2(x)] A" -,aI(A)qD1 -wM);q4 -Lmh;qT -cLog:g3 -wB(373,wP -mG -wF,"B [fp_exp(x)] A" -,aI(A)qD1 -q91(B)wM);q4 -Lmi;qT -cLog10:g3 -wB(375,wP -aL -wF,"B [fp_pow(Value_t(10),x)] A" -,aI(A)qD1 -q91(B)wM);q4 -Lmj;qT -cLog2:g3 -wB(374,wP -aN -wF,"B [fp_exp2(x)] A" -,aI(A)qD1 -q91(B)wM);q4 -Lmk;qT -h3 -hL -qZ -hP -y>oP){wB(366,"y[y>Value_t(0)]" -wH -wF,"[x/y] A" -,aI(A)qD1<<"," -a1);q4 -Lml;} -if(yoP -gA -qZ -hP -y>oP){wB(368,"y[y>Value_t(0)] cPow[x>Value_t(0)]" -wF,"[fp_pow(x,Value_t(1)/y)] A" -,aI(A)qD1<<"," -a1);q4 -Lmo;} -} -qT -oQ -wB(381,"cSinh" -wF,"[fp_asinh(x)] A" -,aI(A)qD1 -wM);q4 -Lmp -qU -cSqr -d4 -dO -wB(369,"cSqr[x>Value_t(0)]" -wF,mV" [fp_sqrt(x)] A" -,aI(A)qD1 -wM);q4 -Lmq;qT -cTanh -d4 -dPmByteCode.size()>0]" -,"B" -mQ,aI(A)q91(B)wM);q4 -Lnb;} -} -if(gV -h2 -B=dF -qO -B -qP -1){C=qK -qR -C==A){D -g4 -D==B){wB(476,"D[D==B] C[C==A] B[IsVarOpcode(B)&&mData->mByteCode.size()>1] A[IsUnaryOpcode(A)]" -,"D C" -mQ,aI(A)q91(B)<<", C" -wY(C)<<", D" -wY(D)wM);q4 -Lnc;} -} -} -} -C=w5 -qR -IsCommutativeOrParamSwappableBinaryOpcode(C)){qS -cSin:A=qK -w1 -3 -gA]==cCos){B=hQ -wB(505,aK" " -aO" A[IsVarOpcode(A)&&mData->mByteCode.size()>3] " -mP" C[IsCommutativeOrParamSwappableBinaryOpcode(C)]" -,"B cSinCos {GetParamSwappedBinaryOpcode(C)}" -," with C" -wY(C)qE1(A)q91(B)wM);q4 -Lnd;} -} -qT -oQ -A=qK -w1 -3 -gA]==cCosh){B=hQ -wB(506,aK" " -aM" A[IsVarOpcode(A)&&mData->mByteCode.size()>3] cSinh C[IsCommutativeOrParamSwappableBinaryOpcode(C)]" -,"B cSinhCosh {GetParamSwappedBinaryOpcode(C)}" -," with C" -wY(C)qE1(A)q91(B)wM);q4 -Lne;} -} -h8} -} -} -q4 -Laa;Laa:qW -w5);gJ -Lab:g6 -Lnf:wE(cAbs);q4 -TailCall_cAbs;Lac:q7=dP;gJ -Lad:q7=fp_acos -m6 -Lae:q7=fp_acosh -m6 -Laf:oZ -4));gG -Lng:w5=h3;Lnh:g0 -Lni:wE(cMul);q4 -TailCall_cMul;Lag:hV -4 -dT -oZ -4));Lnj:qW -q6 -hA -Lah:q7=x+g1 -1);gG -Lfa:w5=h3;q4 -Lni;Lai:gU -cSub;Lnk:wE(cSub);q4 -TailCall_cSub;Laj:hW -2 -gH -Lnl:g0 -Lnm:wE(cAdd);q4 -TailCall_cAdd;Lak:hW -oR -Lnn:qE -hS);Lno:w5=cRSub;g0 -wE(cRSub);q4 -TailCall_cRSub;Lal:o9;qL -2 -gK -q4 -Lnn;Lam:hW -2 -gH -q4 -Lno;Lan:hW -4 -gH -Lnp:qE -hS);Lnq:qE -B);Loa:w5=cSub;g0 -q4 -Lnk;Lao:o9;oC=q6 -q9 -oR -q4 -Lnp;Lap:hW -oR -q4 -Lnq;Laq:gT -y+x;Lba:qM -Ldn:q5 -gJ -Lbb:q8 -oV -o7 -x -q71 -gX -Lnn;Lbc:mM -A -gX -Lnn;Lbd:gU -dS;Lob:wE(cNotNot);q4 -TailCall_cNotNot;Lbe:gT -fp_and(x -d6 -Lbf:q7=fp_asin -m6 -Lbg:q7=fp_asinh -m6 -Lbh:q7=fp_atan -m6 -Lbi:gT -fp_atan2(gW -Lbj:q7=fp_atanh -m6 -Lbk:q7=fp_cbrt -m6 -Lbl:q1 -cFloor);Loc:w5=cNeg;g0 -wE(cNeg);q4 -TailCall_cNeg;Lbm:q7=fp_ceil -m6 -Lbn:g6 -Lod:wE(cCos);q4 -TailCall_cCos;Lbo:q7=fp_cos -m6 -Lbp:dF=cDup;w5=cInv;Loe:wE(cInv);q4 -TailCall_cInv;Lbq:mM -cSinCos);gJ -Lca:g6 -wE(cCosh);q4 -TailCall_cCosh;Lcb:q1 -cSqr -o7 -g1 -1));Lof:qW -q6 -oJ -hS);Log:w5=cSqrt;g0 -wE(cSqrt);q4 -TailCall_cSqrt;Lcc:q7=fp_cosh -m6 -Lcd:mM -cSinhCosh);gJ -Lce:q7=RadiansToDegrees -m6 -Lcf:q1 -cSec -hA -Lcg:q1 -cTan -hA -Lch:q1 -cSin -hA -Lci:oZ));dF -dJ -Loh:qE -dU -oZ -1));Loi:qW -q6);Loj:w5=hS;q4 -Lnl;Lcj:q1 -cNeg -oJ -cExp -hA -Lck:q1 -cNeg -oJ -cExp2 -hA -Lcl:g6 -q4 -Lfa;Lcm:q1 -cNeg -oJ -cPow -hA -Lcn:q1 -cCos -hA -Lco:q1 -cCsc -hA -Lcp:gU -cTan;Lok:wE(cTan);q4 -TailCall_cTan;Lcq:gU -cTanh;Lol:wE(cTanh);q4 -TailCall_cTanh;Lda:q1 -cCot -hA -Ldb:o9;dI -Lom:wE(cDiv);q4 -TailCall_cDiv;Ldc:gT -y/x;q4 -Lba;Ldd:qF1 -q8 -oR -Lon:w5=cDeg;g0 -wE(cDeg);q4 -TailCall_cDeg;Lde:qF1 -q8 -oR -Loo:w5=cRad;g0 -wE(cRad);q4 -TailCall_cRad;Ldf:gT -y/x;dG -Lng;Ldg:q7=g1 -1)/x;q4 -Lfa;Ldh:mM -oI -Lop:g0 -q4 -Lom;Ldi:q8 -3 -gC -oI -qF -x -q71);Loq:w5=cRDiv;g0 -wE(cRDiv);q4 -TailCall_cRDiv;Ldj:hV -3 -gC -oI -qE -B -gX -Loq;Ldk:dI -Lpa:wE(cEqual);q4 -TailCall_cEqual;Ldl:gT -fp_equal(gW -Ldm:d7 -cExp -o7 -fp_exp(x)gX -Lnj;Ldo:q7=fp_exp -m6 -Ldp:d7 -cExp2 -o7 -fp_exp2(x)gX -Lnj;Ldq:q7=fp_exp2 -m6 -Lea:qF -oW -g1 -2))q71);Lpb:qE -h3 -gI -cExp;g0 -wE(cExp);q4 -TailCall_cExp;Leb:q1 -cCeil -gX -Loc;Lec:q7=fp_floor -m6 -Led:gT -fp_less(x -d6 -Lee:qM -q1 -cNeg);Ljm:qE -cAbsNot);gJ -Lef:q7=g1 -0.5)/x;qK=d8 -dS;g0 -q4 -Lob;Leg:gT -fp_lessOrEq(x -d6 -Leh:qM -Ljd:q5 -Lpc:qE -cAbsNotNot);gJ -Lei:q7=fp_int -m6 -Lej:gU -cSec;wE(cSec);q4 -TailCall_cSec;Lek:gU -cSin;Lpd:wE(cSin);q4 -TailCall_cSin;Lel:q1 -cNeg -gI -cPow;Lpe:g0 -Lpf:wE(cPow);q4 -TailCall_cPow;Lem:gU -cCos;q4 -Lod;Len:gU -cCsc;wE(cCsc);q4 -TailCall_cCsc;Leo:q1 -cRSqrt);gJ -Lep:g6 -Lpg:w5=cCot;wE(cCot);q4 -TailCall_cCot;Leq:q7=g1 -1)/x;gJ -Lfb:q7=g1 -0.5)/x;qK=d8 -cNot;g0 -Lph:wE(cNot);q4 -TailCall_cNot;Lfc:gT -fp_less(gW -Lfd:qM -Lje:w3 -Ljm;Lfe:gT -fp_lessOrEq(gW -Lff:qM -q1 -cNeg -gX -Lpc;Lfg:d7 -cLog -o7 -oW -x)o8 -Lfh:q1 -dQ -qE -cLog);Lpi:qW -cDup -gX -Loj;Lfi:q7=oW -x);gJ -Lfj:qF -dR -fp_const_e()));Lpj:dF -dJ -q4 -Lng;Lfk:d7 -cLog10 -o7 -dR -x)o8 -Lfl:q1 -dQ -qE -cLog10 -gX -Lpi;Lfm:q7=dR -x);gJ -Lfn:qF -o4 -fp_const_e())gX -Lpj;Lfo:d7 -cLog2 -o7 -o4 -x)o8 -Lfp:q1 -dQ -qE -cLog2 -gX -Lpi;Lfq:q7=o4 -x);gJ -Lga:gT -fp_max(x -d6 -Lgb:gT -fp_min(x -d6 -Lgc:gT -fp_mod(gW -Lgd:hV -oR -q0-=3;q4 -Lpg;Lge:gU -cSqr;Lpk:wE(cSqr);q4 -TailCall_cSqr;Lgf:gU -cDiv;q4 -Lom;Lgg:mM -cSqr -gX -Loc;Lgh:hV -3 -gC -cSqr);dM -Loc;Lgi:q7=x+g1 -1);gG -w5=cPow;q4 -Lpf;Lgj:gG -q4 -Lni;Lgk:gT -x;Lpl:dG -Lnh;Lgl:qF1 -qM -Lpm:hV -4 -gH -Lpn:o6 -x);Lpo:qW -q6 -gX -Lnh;Lgm:qM -q4 -Lpm;Lgn:q8 -4 -gC -B -gX -Lpn;Lgo:q8 -oR -q4 -Lpn;Lgp:qK -dJ -q4 -Ldn;Lgq:dI -q4 -Lni;Lha:qM -Lpp:hV -oR -gJ -Lhb:q7=x+x;q4 -Lgj;Lhc:gT -x;qL -4]dJ -q8 -4 -dT -o6 -y*x -q71);dM -Loj;Lhd:gT -x;d7 -dU -qF -y*x -o8 -Lhe:q7=RadiansToDegrees(x -gX -Lgq;Lhf:qG1 -q8 -4 -gH -Lpq:qE -dU -Lqa:qE -B -gI -cDiv;q4 -Lop;Lhg:o9;oC=q6 -q9 -oR -q4 -Lpq;Lhh:qG1 -q8 -oR -q4 -Lqa;Lhi:q8 -4 -gH -q4 -Lnh;Lhj:q8 -4 -dT -qF -x+x -gX -Lpo;Lhk:qF1 -qM -q4 -Lpp;Lhl:qG1 -q4 -Lpl;Lhm:o9;q4 -Lgq;Lhn:qG1 -q8 -oR -Lqb:dM -Loq;Lho:o9;qL -2 -gK -q4 -Lqb;Lhp:qG1 -dG -Loq;Lhq:q7=h4 -gX -Lgq;Lia:gT -x;qL -4]dJ -q8 -4 -dT -o6 -y*x -q71);dM -Loa;Lib:qG1 -q4 -Lba;Lic:qM -w3 -Loc;Lid:dF=cDup;dW-=1;qM -Lqc:w5=hS;q4 -Lnm;Lie:qM -w3 -Lon;Lif:qM -w3 -Loo;Lig:hV -oV -gX -Lpq;Lih:hV -2 -gH -Lqd:qE -cSqr -gX -Lnh;Lii:q8 -oV -o7 -x -q71 -gX -Lqb;Lij:mM -A -gX -Lqb;Lik:hV -oR -q4 -Lqd;Lil:dI -Lqe:wE(cNEqual);q4 -TailCall_cNEqual;Lim:gT -fp_nequal(gW -Lin:o9;q4 -Lcl;Lio:o9 -gB -cSin;g0 -q4 -Lpd;Lip:o9 -gB -cSinh;g0 -wE(cSinh);q4 -TailCall_cSinh;Liq:o9 -gB -cTan;g0 -q4 -Lok;Lja:o9 -gB -cTanh;g0 -q4 -Lol;Ljb:o9;gJ -Ljc:g6 -q4 -Lph;Ljf:gU -cNEqual;q4 -Lqe;Ljg:gU -cLessOrEq;wE(cLessOrEq);q4 -TailCall_cLessOrEq;Ljh:gU -cLess;wE(cLess);q4 -TailCall_cLess;Lji:gU -dK;wE(cGreaterOrEq);q4 -TailCall_cGreaterOrEq;Ljj:gU -o1;wE(cGreater);q4 -TailCall_cGreater;Ljk:gU -w8;q4 -Lpa;Ljl:q7=fp_not -m6 -Ljn:gT -fp_or(x -d6 -Ljo:d7 -dQ -qF -x+x);Lqf:qW -q6 -gX -Lpe;Ljp:dL -Lpb;Ljq:qK=d8 -cExp2;g0 -wE(cExp2);q4 -TailCall_cExp2;Lka:qG1 -dG -Lpe;Lkb:qK -dJ -q1 -h3 -gX -Lpe;Lkc:dI -q4 -Lpf;Lkd:q8 -3 -dT -qF -x -gX -Lqf;Lke:q7=g1 -gX -Loh;Lkf:qM -w3 -Log;Lkg:qM -q5 -w5=cCbrt;g0 -wE(cCbrt);q4 -TailCall_cCbrt;Lkh:qM -q1 -cCbrt);Lqg:w5=cInv;g0 -q4 -Loe;Lki:qM -q4 -Leo;Lkj:qM -w3 -Lqg;Lkk:qF1 -q8 -3 -gC -dQ -qF -y*x -gX -Lqf;Lkl:q7=x+x;q4 -Lkc;Lkm:gT -oX -gW -Lkn:q1 -cTanh -gX -Lqg;Lko:oZ)gX -Lpj;Lkp:q7=h4 -gX -Lcl;Lkq:q7=h4);gJ -Lla:mM -cSinCos -gX -Lqg;Llb:q1 -cSin -gX -Loc;Llc:q7=fp_sin -m6 -Lld:q1 -cSqr -o7 -g1-1)gX -Lof;Lle:q1 -cSinh -gX -Loc;Llf:q7=fp_sinh -m6 -Llg:g6 -q4 -Lpk;Llh:hV -4 -gC -A);Lqh:w5=cHypot;g0 -wE(cHypot);q4 -TailCall_cHypot;Lli:hV -5 -gC -A -oJ -B -gX -Lqh;Llj:gU -cAbs;q4 -Lnf;Llk:q7=fp_sqrt -m6 -Lll:g6 -q4 -Lqc;Llm:gT -y-x;q4 -Lba;Lln:o9;q4 -Lqc;Llo:q8 -oV -oJ -hS -o7 -x -q71 -gX -Lno;Llp:mM -A -oJ -cSub -gX -Lno;Llq:q1 -cTan -gX -Loc;Lma:q7=fp_tan -m6 -Lmb:q1 -cTanh -gX -Loc;Lmc:q7=fp_tanh -m6 -Lmd:q7=fp_trunc -m6 -Lme:gT -x-y;Lqi:q8 -2 -gH -Lqj:qE -A);gJ -Lmf:q7=fp_tan(x);Lqk:dL -Lqj;Lmg:q7=oW -x -gX -Lqk;Lmh:q7=o4 -x -gX -Lqk;Lmi:q7=fp_exp(x -gX -Lqk;Lmj:q7=oX -g1 -10),x -gX -Lqk;Lmk:q7=fp_exp2(x -gX -Lqk;Lml:gT -x/y;q4 -Lqi;Lmm:gT -x/y;q8 -2 -gH -Lql:qE -OppositeComparisonOpcode(A));gJ -Lmn:o9;dL -Lql;Lmo:gT -oX -x,g1 -1)/y -gX -Lqi;Lmp:q7=fp_asinh(x -gX -Lqk;Lmq:d7 -dQ -qF -fp_sqrt(x)q71 -gX -Lqj;Lna:q7=fp_atanh(x -gX -Lqk;Lnb:qW -cDup);gJ -Lnc:dF=cDup;gJ -Lnd:hV -3 -gC -cSinCos);Lqm:qE -GetParamSwappedBinaryOpcode(C));gJ -Lne:hV -3 -gC -cSinhCosh -gX -Lqm;gJ -q4 -TailCall_cAcos;q4 -TailCall_cAcosh;q4 -TailCall_cAnd;q4 -TailCall_cAsin;q4 -TailCall_cAsinh;q4 -TailCall_cAtan;q4 -TailCall_cAtan2;q4 -TailCall_cAtanh;q4 -TailCall_cCeil;q4 -TailCall_cFloor;q4 -TailCall_cInt;q4 -TailCall_cLog;q4 -TailCall_cLog10;q4 -TailCall_cLog2;q4 -TailCall_cMax;q4 -TailCall_cMin;q4 -TailCall_cMod;q4 -TailCall_cOr;q4 -TailCall_cRDiv;q4 -TailCall_cRad;q4 -TailCall_cSec;q4 -TailCall_cSin;q4 -TailCall_cSinh;q4 -TailCall_cSqrt;q4 -TailCall_cSub;q4 -TailCall_cTan;q4 -TailCall_cTanh;q4 -TailCall_cTrunc; -#endif -#if((FP_COMPLEX_VERSION) && (FP_FLOAT_VERSION)) -dH -x;dH -gE -A;hT -C;hT -D;qQ -w5){TailCall_cAbs:g5 -cAbs:qS -h0} -qH -TailCall_cAcos:g5 -cAcos:qY -wB(172,"x cAcos" -,"[fp_acos(x)]" -,wN);q4 -Lad;} -qH -TailCall_cAcosh:g5 -cAcosh:qY -wB(169,"x cAcosh" -,"[fp_acosh(x)]" -,wN);q4 -Lae;} -qH -TailCall_cAdd:g5 -hG -Laf;qT -h3 -hL]==hS){if(qL -gZ -Lag;} -h8} -q4 -dX -qU -d2 -gF -h1 -wB(313,"cDup" -a7 -aZ,"[x+Value_t(1)]" -wH,wN);q4 -Lah;} -} -q4 -dX -oF -wB(199,qC1 -aZ,"cSub" -,);q4 -Lai -gY -hK -qZ -mW(127,aY"cAdd" -mD,"[y+x]" -aZ,q81);q4 -Laj;qT -cRSub:qQ -hE -d3 -3 -qZ -mW(298,aY"cAdd" -mE -mD,mN -aZ -mE,q81);q4 -Lak;qT -hI -wB(299,m0 -a6 -mD,"[-x]" -aZ -mE,wN);q4 -Lal -qU -q6:mW(297,aY -a6 -mD,mN -mE,q81);q4 -Lam;qT -oA -Lan;qT -hI -wB(293,m0"B[IsVarOpcode(B)]" -aW -mD,"[-x]" -aZ" B" -aW,wA"," -a8(B)wM);q4 -Lao -qU -q6:mW(291,aY"B[IsVarOpcode(B)]" -aW -mD,mN" B" -aW,wA"," -a8(B)<<"," -a1);q4 -Lap;} -w9 -mW(105,aY -aF,"[y+x]" -,q81);q4 -Laq;} -g8)){wB(57,"x[x==Value_t()]" -aZ,,wN);q4 -Lba;h8 -g7 -dX:;A=dF -w0 -oY -cRSub -dV -wB(290,"x" -mE -a3"cAdd" -,"[DO_STACKPLUS1] A [x]" -aZ -mE,aI(A)qD1 -wM);incStackPtr();--mStackPtr;q4 -Lbb;} -wB(295,a6 -a3"cAdd" -,"[DO_STACKPLUS1] A" -aZ -mE,aI(A)wM);incStackPtr();--mStackPtr;q4 -Lbc;} -qG -TailCall_cAnd:g5 -cAnd -hH -wB(224,mX"cAnd" -,aJ,);q4 -w7 -m9(117,mA"cAnd" -,"[fp_and(x,y)]" -,q81);q4 -Lbe;h8} -qH -TailCall_cArg:g5 -cArg:qY -wB(190,"x cArg" -,"[fp_arg(x)]" -,wN);q4 -Lbf;} -qH -TailCall_cAsin:g5 -cAsin:qY -wB(173,"x cAsin" -,"[fp_asin(x)]" -,wN);q4 -Lbg;} -qH -TailCall_cAsinh:g5 -cAsinh:qY -wB(170,"x cAsinh" -,"[fp_asinh(x)]" -,wN);q4 -Lbh;} -qH -TailCall_cAtan:g5 -cAtan:qY -if(g1 -x.real(),fp_abs(x.imag()))!=g1 -0,oG -wB(174,"x[Value_t(x.real(),fp_abs(x.imag()))!=Value_t(0,1)] cAtan" -,"[fp_atan(x)]" -,wN);q4 -Lbi;qG -TailCall_cAtan2:g5 -cAtan2:qY -m9(139,mA"cAtan2" -,"[fp_atan2(y,x)]" -,q81);q4 -Lbj;qG -TailCall_cAtanh:g5 -cAtanh:qY -if(g1 -fp_abs(x.real()),x.imag())!=g1 -1,0)){wB(171,"x[Value_t(fp_abs(x.real()),x.imag())!=Value_t(1,0)] cAtanh" -,"[fp_atanh(x)]" -,wN);q4 -Lbk;qG -TailCall_cCbrt:g5 -cCbrt:qY -wB(175,"x cCbrt" -,"[fp_cbrt(x)]" -,wN);q4 -Lbl;} -qH -TailCall_cCeil:g5 -cCeil:qS -hI -wB(402,m0 -q01,mS -aA,);q4 -Lbm -gY -wB(135,"x " -q01,"[fp_ceil(x)]" -,wN);q4 -Lbn -gS -wB(396,"A[IsAlwaysIntegerOpcode(A)] " -q01,"A" -,aI(A)wM);gJ -qG -TailCall_cConj:g5 -cConj:qS -cConj:wB(63,mY" " -mY,,);oS -gY -wB(193,"x " -mY,"[fp_conj(x)]" -,wN);q4 -Lbp;} -qH -TailCall_cCos:g5 -cCos:qS -cAcos:wB(346,"cAcos " -aO,,);q4 -oE -wB(238,m0 -aO,aO,);q4 -Lbq -gY -wB(176,"x " -aO,"[fp_cos(x)]" -,wN);q4 -Lca;oH -qN -qQ -h9 -cSec:hD -wB(500,aK" cSec " -wI -aO,"B cSec " -aT,aI(A)q91(B)wM);q4 -Lcb;qT -cSin:hD -wB(494,aK" " -mP" " -wI -aO,"B cSinCos" -,aI(A)q91(B)wM);q4 -Lcc;h8} -qG -TailCall_cCosh:g5 -cCosh:qS -cAsinh:wB(450,"cAsinh " -aM,"[DO_STACKPLUS1] " -q41"[Value_t(1)] " -aQ,);incStackPtr();--mStackPtr;q4 -Lcd -oF -wB(239,m0 -aM,aM,);q4 -Lce -gY -wB(177,"x " -aM,"[fp_cosh(x)]" -,wN);q4 -Lcf;oH -qN -oY -cSinh -q11(507,aK" cSinh " -wI -aM,"B cSinhCosh" -,aI(A)q91(B)wM);q4 -Lcg;} -} -qG -TailCall_cCot:g5 -cCot:A=qN -oY -cTan -q11(498,aK" " -mR" " -wI"cCot" -,"B " -mR" " -aT,aI(A)q91(B)wM);q4 -Lcb;} -qG -TailCall_cCsc:g5 -cCsc:A=qN -oY -cSin -q11(496,aK" " -mP" " -wI"cCsc" -,"B " -mP" " -aT,aI(A)q91(B)wM);q4 -Lcb;} -qG -TailCall_cDeg:g5 -cDeg:qY -wB(133,"x cDeg" -,"[RadiansToDegrees(x)]" -,wN);q4 -Lch;} -qH -TailCall_cDiv:g5 -cDiv:qS -cCos:wB(250,aO -mF,"cSec" -wH,);q4 -Lci -qU -cCot:wB(254,"cCot" -mF,mR -wH,);q4 -Lcj -qU -cCsc:wB(252,"cCsc" -mF,mP -wH,);q4 -Lck -qU -cDup:wB(78,"cDup" -mF,"[Value_t()]" -wH" [Value_t(1)]" -aZ,);q4 -Lcl -qU -w2 -wB(408,"cExp" -mF,m0"cExp" -wH,);q4 -Lcm -qU -cExp2:wB(409,"cExp2" -mF,m0"cExp2" -wH,);q4 -Lcn -qU -cInv:wB(213,aU -mF,"cMul" -,);q4 -Lco -qU -cPow:wB(407,"cPow" -mF,m0"cPow" -wH,);q4 -Lcp -qU -cSec:wB(253,"cSec" -mF,aO -wH,);q4 -Lcq -qU -cSin:wB(249,mP -mF,"cCsc" -wH,);q4 -Lda -qU -cSinCos:wB(502,"cSinCos" -mF,mR,);q4 -Ldb -qU -cSinhCosh:wB(509,"cSinhCosh" -mF,"cTanh" -,);q4 -Ldc -qU -cTan:wB(251,mR -mF,"cCot" -wH,);q4 -Ldd -gY -if -hF -gQ -hI -wB(125,m0 -a4"cDiv" -,"[-x]" -mF,wN);q4 -Lde -qU -q6:mW(103,aY -a4"cDiv" -,"[y/x]" -,q81);q4 -Ldf;} -} -g8 -oG -wB(56,wO"cDiv" -,,wN);q4 -Lba;} -dB -h3 -gA -qZ -hP(y/x)==fp_const_rad_to_deg -h7 -wB(321,"y[(y/x)==fp_const_rad_to_deg()]" -wH" " -wR,"cDeg" -,q81);q4 -Ldg;} -if((y/x)==fp_const_deg_to_rad -h7 -wB(322,"y[(y/x)==fp_const_deg_to_rad()]" -wH" " -wR,"cRad" -,q81);q4 -Ldh;} -wB(323,"y" -wH" " -wR,"[y/x]" -wH,q81);q4 -Ldi;} -} -wB(325,wR,"[Value_t(1)/x]" -wH,wN);q4 -Ldj;} -gP -cDiv:hC -wB(271,aX"cDiv " -wV,"[DO_STACKPLUS1] B A" -wH -mF,aI(A)q91(B)wM);incStackPtr();--mStackPtr;q4 -Ldk;qT -cRDiv:qQ -hE -qV -hM -wB(266,"x" -a9" " -wV,"A" -wH" [x]" -a9,aI(A)qD1 -wM);q4 -Ldl;g7 -hC -wB(265,"B[IsVarOpcode(B)]" -a9" " -wV,"A" -wH" B" -a9,aI(A)q91(B)wM);q4 -Ldm;} -h8} -qG -TailCall_cEqual:g5 -w8:oL -hU -wB(359,m1 -aE,"[x] " -aE,wN);q4 -Ldn -qU -cSqr:wB(361,q41 -wL -aE,"[x] " -aE,wN);q4 -Ldn;} -} -m9(115,mA -aE,"[fp_equal(y,x)]" -,q81);q4 -Ldo;qG -TailCall_cExp:g5 -w2 -qS -hS -gM -wB(404,aF -mL,q21"[fp_exp(x)]" -wH,wN);q4 -Ldp;qT -cLog:A=dE -wB(340,wJ -mG -mL,"A" -,aI(A)wM);oS;qT -hM -wB(178,"x" -mL,"[fp_exp(x)]" -,wN);q4 -Ldq;} -qH -TailCall_cExp2:g5 -cExp2:qS -hS -gM -wB(405,aF -q31,"cExp2 [fp_exp2(x)]" -wH,wN);q4 -Lea;qT -cLog2:A=dE -wB(341,wJ -aN -q31,"A" -,aI(A)wM);oS;qT -hM -wB(179,"x" -q31,"[fp_exp2(x)]" -,wN);q4 -Leb;} -wB(479,"cExp2" -,"[DO_STACKPLUS1] [fp_log(Value_t(2))]" -wH -mL,);incStackPtr();--mStackPtr;q4 -Lec;TailCall_cFloor:g5 -cFloor:qS -hI -wB(401,m0 -mS,q01 -aA,);q4 -Led -gY -wB(136,"x " -mS,"[fp_floor(x)]" -,wN);q4 -Lee -gS -wB(395,"A[IsAlwaysIntegerOpcode(A)] " -mS,"A" -,aI(A)wM);gJ -qG -TailCall_cGreater:g5 -o1:qY -m9(113,mA -m2,"[fp_less(x,y)]" -,q81);q4 -Lef;qG -TailCall_cGreaterOrEq:g5 -dK:qY -m9(114,mA -aG,"[fp_lessOrEq(x,y)]" -,q81);q4 -Leg;qG -TailCall_cHypot:g5 -cHypot -d4 -dF==cSinCos){wB(84,"cSinCos cHypot" -,"[Value_t()]" -wH" [Value_t(1)]" -aZ,);q4 -Lcl;} -qH -TailCall_cImag:g5 -cImag:qS -cAbs:wB(81,mV" " -mZ,"[Value_t()]" -wH,);q4 -Leh -qU -cReal:wB(80,"cReal " -mZ,"[Value_t()]" -wH,);q4 -Leh -gY -wB(192,"x " -mZ,"[fp_imag(x)]" -,wN);q4 -Lei;} -qH -TailCall_cInt:g5 -cInt:qS -hM -wB(137,"x cInt" -,"[fp_int(x)]" -,wN);q4 -Lej -gS -wB(397,"A[IsAlwaysIntegerOpcode(A)] cInt" -,"A" -,aI(A)wM);gJ -qG -TailCall_cInv:g5 -cInv:qS -cCos:wB(256,aO" " -aU,"cSec" -,);q4 -Lek -qU -cCot:wB(260,"cCot " -aU,mR,);q4 -Ldb -qU -cCsc:wB(258,"cCsc " -aU,mP,);q4 -Lel -qU -cInv:wB(62,aU" " -aU,,);oS -qU -cPow:wB(355,q61 -aU,m0"cPow" -,);q4 -Lem -qU -cSec:wB(259,"cSec " -aU,aO,);q4 -Len -qU -cSin:wB(255,mP" " -aU,"cCsc" -,);q4 -Leo -qU -cSqrt:wB(206,q51" " -aU,"cRSqrt" -,);q4 -Lep -qU -cTan:wB(257,mR" " -aU,"cCot" -,);q4 -Leq -gY -if -hF)){wB(101,a4 -aU,"[Value_t(1)/x]" -,wN);q4 -Lfa;h8} -qH -TailCall_cLess:g5 -cLess:oL)){A=dE -wB(301,wJ -wL -mJ,mK,qB1(A)wM);q4 -Lfb;} -} -m9(111,mA -mJ,"[fp_less(y,x)]" -,q81);q4 -Lfc;qG -TailCall_cLessOrEq:g5 -cLessOrEq:qY -m9(112,mA -aR,"[fp_lessOrEq(y,x)]" -,q81);q4 -Lfd;qG -TailCall_cLog:g5 -cLog:mT(343,q21 -mG,,);oS -qU -gL -wB(491,mU -mG,mG" [fp_log(x)]" -aZ,wN);q4 -Lfe;} -oD -wB(180,qA1 -mG,"[fp_log(x)]" -,wN);q4 -Lff;h8} -qH -TailCall_cLog10:g5 -cLog10:mT(481,q21 -aL,"[DO_STACKPLUS1] [fp_log10(fp_const_e())]" -wH,);incStackPtr();--mStackPtr;q4 -Lfg -qU -gL -wB(492,mU -aL,aL" [fp_log10(x)]" -aZ,wN);q4 -Lfh;} -oD -wB(181,qA1 -aL,"[fp_log10(x)]" -,wN);q4 -Lfi;h8} -qH -TailCall_cLog2:g5 -cLog2:mT(480,q21 -aN,"[DO_STACKPLUS1] [fp_log2(fp_const_e())]" -wH,);incStackPtr();--mStackPtr;q4 -Lfj -qU -cExp2:wB(344,"cExp2 " -aN,,);oS -qU -gL -wB(490,mU -aN,aN" [fp_log2(x)]" -aZ,wN);q4 -Lfk;} -oD -wB(182,qA1 -aN,"[fp_log2(x)]" -,wN);q4 -Lfl;h8} -qH -TailCall_cMax:g5 -cMax -hH -wB(60,mX -mB,,);oS -gY -m9(141,mA -mB,"[fp_max(x,y)]" -,q81);q4 -Lfm;} -gP -cDup:hD -wB(66,aK -mQ -a3 -mB,"B" -mQ,aI(A)q91(B)wM);oS;qT -cMax:hD -wB(68,aK" " -mB -a3 -mB,"B " -mB,aI(A)q91(B)wM);oS;h8} -qG -TailCall_cMin:g5 -cMin -hH -wB(59,mX -mC,,);oS -gY -m9(140,mA -mC,"[fp_min(x,y)]" -,q81);q4 -Lfn;} -gP -cDup:hD -wB(65,aK -mQ -a3 -mC,"B" -mQ,aI(A)q91(B)wM);oS;qT -cMin:hD -wB(67,aK" " -mC -a3 -mC,"B " -mC,aI(A)q91(B)wM);oS;h8} -qG -TailCall_cMod:g5 -cMod:qY -if -hF)){m9(104,aY -a4"cMod" -,"[fp_mod(y,x)]" -,q81);q4 -Lfo;} -qG -TailCall_cMul:g5 -h3:qS -cCsc:A=qK -w1 -3 -gA]==cCos){B=hQ -wB(508,aK" " -aO" A[IsVarOpcode(A)&&mData->mByteCode.size()>3] cCsc" -wH,"B cCot" -,aI(A)q91(B)wM);q4 -Lfp;} -} -} -q4 -dY -qU -cDup:wB(202,"cDup" -wH,"cSqr" -,);q4 -Lfq -qU -cInv:wB(214,aU -wH,"cDiv" -,);q4 -Lga -oF -qQ -h9 -cDup:wB(467,"cDup" -aA -wH,"cSqr" -aA,);q4 -Lgb;oH -qK -qO -A)gA -oM -B=hQ -wB(473,aK -wH -a3 -qC1 -wH,m5 -wH -aA,aI(A)q91(B)wM);q4 -Lgc;} -} -} -} -q4 -dY -qU -cPow -gM -if -gF -h1 -wB(314,mX -m8 -wH,"[x+Value_t(1)] cPow" -,wN);q4 -Lgd;} -} -q4 -dY -gY -g8 -gQ -h3:A=hE -w0 -wB(93,wS" " -wZ,wX,qB1(A)wM);q4 -Lge;} -q4 -Default3;g7 -Default3:;A=qK -qR -IsBinaryOpcode(A)g2 -h2 -qQ -hE -qV -q6:mW(92,aY -wD,wX,qB1(A)<<"," -a1);q4 -Lgf;g7 -B -g4 -IsBinaryOpcode(B)g2 -B)){qQ -oC -qV -q6:mW(96,aY -wK,mK,qB1(A)q91(B)<<"," -a1);q4 -Lgg;g7 -C=oC -qO -C)){wB(94,"C[IsVarOpcode(C)] " -wK,mK,qB1(A)q91(B)<<", C" -wY(C)wM);q4 -Lgh;} -if(gV -C)g2 -C)){wB(95,"C[IsUnaryOpcode(C)&&!HasInvalidRangesOpcode(C)] " -wK,"B " -mK,qB1(A)q91(B)<<", C" -wY(C)wM);q4 -Lgi;} -} -} -if(d1 -B)){wB(90,aX -wD,wX,qB1(A)q91(B)wM);q4 -Lge;} -if(gV -B)g2 -B)){wB(91,"B[IsUnaryOpcode(B)&&!HasInvalidRangesOpcode(B)] " -wD,mK,qB1(A)q91(B)wM);q4 -Lgj;} -} -} -if(d1 -h2 -wB(88,a5" " -wZ,"[x]" -,qB1(A)wM);q4 -Lgk;} -if(gV -A)g2 -h2 -wB(89,"A[IsUnaryOpcode(A)&&!HasInvalidRangesOpcode(A)] " -wZ,wX,qB1(A)wM);q4 -Lgl;} -} -} -qQ -h9 -hS:qQ -hE -qV -cDup -d4 -x+oU -wB(316,"cDup[x+x==Value_t(1)]" -aZ -a7,,wN);q4 -Lgm;} -wB(317,aH -a7,"[x+x]" -wH,wN);q4 -Lgn -qU -o5 -3 -qZ -hO -A=qL -4]w0 -wB(386,a5" y" -wH -aZ -a7,wX" A " -m3 -aZ,wA", " -aY"= " -<()]" -wH -a7,"cDeg" -,q81);q4 -Ldg;} -if((y*x)==fp_const_deg_to_rad -h7 -wB(308,"y[(y*x)==fp_const_deg_to_rad()]" -wH -a7,"cRad" -,q81);q4 -Ldh;} -wB(128,"y" -wH -a7,m3,q81);q4 -Lhg;qT -hI -wB(122,qC1 -a7,mI,wN);q4 -Lhh -qU -cRDiv:qQ -hE -qV -o5 -3 -qZ -mW(285,"y" -wH -a9 -a7,m3 -a9,q81);q4 -Lhi;qT -hI -wB(286,qC1 -a9 -a7,mI -a9,wN);q4 -Lhj -qU -q6:mW(284,"y" -a9 -a7,"[y*x]" -a9,q81);q4 -Lhk;qT -cRad:wB(210,"cRad" -a7,"[DegreesToRadians(x)]" -wH,wN);q4 -Lhl -qU -cSub -hL -oM -if(qL -3 -qZ -hO -A=qL -4]w0 -wB(387,a5" y" -wH -aW -a7,wX" A " -m3 -aW,wA", " -aY"= " -<()]" -wH,"cDeg" -,wN);q4 -Lhq;} -if(x==fp_const_deg_to_rad -h7 -wB(208,"x[x==fp_const_deg_to_rad()]" -wH,"cRad" -,wN);q4 -Lia;h8 -g7 -dY:;A=dF -qO -A -gQ -cDiv:hC -wB(274,aX"cDiv " -wS,"[DO_STACKPLUS1] A" -wH -qH1,aI(A)q91(B)wM);incStackPtr();--mStackPtr;q4 -Lib;} -q4 -d5 -h3:qQ -hE -qV -hI -B=hQ -wB(470,aK -aA -wH" " -wS,m5 -wH -aA,aI(A)q91(B)wM);q4 -Lgc;} -q4 -dZ;g7 -dZ:;hD -wB(461,aK -wH" " -wS,m5 -wH,aI(A)q91(B)wM);q4 -Lic;} -} -q4 -d5 -hI -hD -wB(464,aK -aA" " -wS,m5 -aA,aI(A)q91(B)wM);q4 -Lgb;} -q4 -d5 -cRDiv -hL -qZ -qC -wB(267,"x" -a9" " -wS,"[DO_STACKPLUS1] " -mK -a9,aI(A)qD1 -wM);incStackPtr();--mStackPtr;q4 -Lid;} -wB(281,"cRDiv " -wS,"[DO_STACKPLUS1] A" -wH -a9,aI(A)wM);incStackPtr();--mStackPtr;q4 -Lie;g7 -Default4:;B=qK -qR -w4 -wB(458,aK" " -wS,m5,aI(A)q91(B)wM);q4 -Lfq;} -} -} -if(gV -h2 -B=qK -qO -B -qP -1 -gA -oM -C=oC -qR -C==A){D=qL -4]qR -D==B){wB(477,"D[D==B] C[C==A]" -wH" B[IsVarOpcode(B)&&mData->mByteCode.size()>1] A[IsUnaryOpcode(A)]" -wH,"D C cSqr" -wH,aI(A)q91(B)<<", C" -wY(C)<<", D" -wY(D)wM);q4 -Lif;} -} -} -} -qG -TailCall_cNEqual:g5 -cNEqual:oL -hU -wB(360,m1 -wW,"[x] " -wW,wN);q4 -Lig -qU -cSqr:wB(362,q41 -wL -wW,"[x] " -wW,wN);q4 -Lig;} -} -m9(116,mA -wW,"[fp_nequal(y,x)]" -,q81);q4 -Lih;qG -TailCall_cNeg:g5 -hI -qS -h3 -gM -wB(123,"x" -wH -aA,mI,wN);q4 -Lii;qT -hI -wB(61,qC1 -aA,,);oS -qU -cSin:g9 -wB(244,"x" -wH" " -mP -aA,mI" " -mP,wN);q4 -Lij;} -qT -oQ -g9 -wB(245,"x" -wH" cSinh" -aA,mI" cSinh" -,wN);q4 -Lik;} -qT -cTan:g9 -wB(246,"x" -wH" " -mR -aA,mI" " -mR,wN);q4 -Lil;} -qT -cTanh:g9 -wB(247,"x" -wH" cTanh" -aA,mI" cTanh" -,wN);q4 -Lim;} -qT -hM -wB(100,"x" -aA,"[-x]" -,wN);q4 -Lin;} -qH -TailCall_cNot:g5 -cNot:qS -cAbsNotNot:wB(231,"cAbsNotNot" -a0,aS,);q4 -Lio -qU -w8:wB(220,aE -a0,wW,);q4 -Lip -qU -o1:wB(218,m2 -a0,aR,);q4 -Liq -qU -dK:wB(219,aG -a0,mJ,);q4 -Lja -qU -cLess:wB(216,mJ -a0,aG,);q4 -Ljb -qU -cLessOrEq:wB(217,aR -a0,m2,);q4 -Ljc -qU -cNEqual:wB(221,wW -a0,aE,);q4 -Ljd -qU -cNot:wB(229,"cNot" -a0,aJ,);q4 -Lbd -qU -dS:wB(230,aJ -a0,"cNot" -,);q4 -Lje -gY -wB(107,"x" -a0,"[fp_not(x)]" -,wN);q4 -Ljf;} -qH -TailCall_cNotNot:g5 -dS -d4 -dF==cNot){wB(232,"cNot " -aJ,"cNot" -,);gJ} -qH -TailCall_cOr:g5 -cOr -hH -wB(223,mX"cOr" -,aJ,);q4 -w7 -m9(118,mA"cOr" -,"[fp_or(x,y)]" -,q81);q4 -Ljg;h8} -qH -TailCall_cPolar:g5 -cPolar -d4 -q0[0 -qZ -y=q7;qJ -x -gO -wB(194,"x " -aY"cPolar" -,"[fp_polar(x,y)]" -," with " -aY"= " -<mByteCode.size()>0]" -,"B" -mQ,aI(A)q91(B)wM);q4 -Lll;} -} -if(gV -h2 -B=dF -qO -B -qP -1){C=qK -qR -C==A){D -g4 -D==B){wB(476,"D[D==B] C[C==A] B[IsVarOpcode(B)&&mData->mByteCode.size()>1] A[IsUnaryOpcode(A)]" -,"D C" -mQ,aI(A)q91(B)<<", C" -wY(C)<<", D" -wY(D)wM);q4 -Llm;} -} -} -} -C=w5 -qR -IsCommutativeOrParamSwappableBinaryOpcode(C)){qS -cSin:A=qK -w1 -3 -gA]==cCos){B=hQ -wB(505,aK" " -aO" A[IsVarOpcode(A)&&mData->mByteCode.size()>3] " -mP" C[IsCommutativeOrParamSwappableBinaryOpcode(C)]" -,"B cSinCos {GetParamSwappedBinaryOpcode(C)}" -," with C" -wY(C)qE1(A)q91(B)wM);q4 -Lln;} -} -qT -oQ -A=qK -w1 -3 -gA]==cCosh){B=hQ -wB(506,aK" " -aM" A[IsVarOpcode(A)&&mData->mByteCode.size()>3] cSinh C[IsCommutativeOrParamSwappableBinaryOpcode(C)]" -,"B cSinhCosh {GetParamSwappedBinaryOpcode(C)}" -," with C" -wY(C)qE1(A)q91(B)wM);q4 -Llo;} -} -h8} -} -} -q4 -Laa;Laa:qW -w5);gJ -Lab:g6 -Llp:wE(cAbs);q4 -TailCall_cAbs;Lac:q7=dP;gJ -Lad:q7=fp_acos -m6 -Lae:q7=fp_acosh -m6 -Laf:oZ -4));gG -Llq:w5=h3;Lma:g0 -Lmb:wE(cMul);q4 -TailCall_cMul;Lag:hV -4 -dT -oZ -4));Lmc:qW -q6 -hY;Lah:q7=x+g1 -1);gG -Lfb:w5=h3;q4 -Lmb;Lai:gU -cSub;Lmd:wE(cSub);q4 -TailCall_cSub;Laj:hW -2 -gH -Lme:g0 -Lmf:wE(cAdd);q4 -TailCall_cAdd;Lak:hW -oR -Lmg:qE -hS);Lmh:w5=cRSub;g0 -wE(cRSub);q4 -TailCall_cRSub;Lal:o9;qL -2 -gK -q4 -Lmg;Lam:hW -2 -gH -q4 -Lmh;Lan:hW -4 -gH -Lmi:qE -hS);Lmj:qE -B);Lmk:w5=cSub;g0 -q4 -Lmd;Lao:o9;oC=q6 -q9 -oR -q4 -Lmi;Lap:hW -oR -q4 -Lmj;Laq:gT -y+x;Lba:qM -Lbo:q5 -gJ -Lbb:q8 -oV -o7 -x -q71 -gX -Lmg;Lbc:mM -A -gX -Lmg;Lbd:gU -dS;wE(cNotNot);q4 -TailCall_cNotNot;Lbe:gT -fp_and(x -d6 -Lbf:q7=fp_arg -m6 -Lbg:q7=fp_asin -m6 -Lbh:q7=fp_asinh -m6 -Lbi:q7=fp_atan -m6 -Lbj:gT -fp_atan2(gW -Lbk:q7=fp_atanh -m6 -Lbl:q7=fp_cbrt -m6 -Lbm:q1 -cFloor);Lml:w5=cNeg;g0 -wE(cNeg);q4 -TailCall_cNeg;Lbn:q7=fp_ceil -m6 -Lbp:q7=fp_conj -m6 -Lbq:g6 -Lmm:wE(cCos);q4 -TailCall_cCos;Lca:q7=fp_cos -m6 -Lcb:dF=cDup;w5=cInv;Lmn:wE(cInv);q4 -TailCall_cInv;Lcc:mM -cSinCos);gJ -Lcd:q1 -cSqr -o7 -g1 -1));Lmo:qW -q6 -oJ -hS);Lmp:w5=cSqrt;g0 -wE(cSqrt);q4 -TailCall_cSqrt;Lce:g6 -wE(cCosh);q4 -TailCall_cCosh;Lcf:q7=fp_cosh -m6 -Lcg:mM -cSinhCosh);gJ -Lch:q7=RadiansToDegrees -m6 -Lci:q1 -cSec -hY;Lcj:q1 -cTan -hY;Lck:q1 -cSin -hY;Lcl:oZ));dF -dJ -Lmq:qE -dU -oZ -1));Lna:qW -q6);Lnb:w5=hS;q4 -Lme;Lcm:q1 -cNeg -oJ -cExp -hY;Lcn:q1 -cNeg -oJ -cExp2 -hY;Lco:g6 -q4 -Lfb;Lcp:q1 -cNeg -oJ -cPow -hY;Lcq:q1 -cCos -hY;Lda:q1 -cCsc -hY;Ldb:gU -cTan;Lnc:wE(cTan);q4 -TailCall_cTan;Ldc:gU -cTanh;Lnd:wE(cTanh);q4 -TailCall_cTanh;Ldd:q1 -cCot -hY;Lde:o9;dI -Lne:wE(cDiv);q4 -TailCall_cDiv;Ldf:gT -y/x;q4 -Lba;Ldg:qF1 -q8 -oR -Lnf:w5=cDeg;g0 -wE(cDeg);q4 -TailCall_cDeg;Ldh:qF1 -q8 -oR -Lng:w5=cRad;g0 -wE(cRad);q4 -TailCall_cRad;Ldi:gT -y/x;dG -Llq;Ldj:q7=g1 -1)/x;q4 -Lfb;Ldk:mM -oI -Lnh:g0 -q4 -Lne;Ldl:q8 -3 -gC -oI -qF -x -q71);Lni:w5=cRDiv;g0 -wE(cRDiv);q4 -TailCall_cRDiv;Ldm:hV -3 -gC -oI -qE -B -gX -Lni;Ldn:dI -Lnj:wE(cEqual);q4 -TailCall_cEqual;Ldo:gT -fp_equal(gW -Ldp:d7 -cExp -o7 -fp_exp(x)gX -Lmc;Ldq:q7=fp_exp -m6 -Lea:d7 -cExp2 -o7 -fp_exp2(x)gX -Lmc;Leb:q7=fp_exp2 -m6 -Lec:qF -oW -g1 -2))q71);Lnk:qE -h3 -gI -cExp;g0 -wE(cExp);q4 -TailCall_cExp;Led:q1 -cCeil -oT -Lee:q7=fp_floor -m6 -Lef:gT -fp_less(x -d6 -Leg:gT -fp_lessOrEq(x -d6 -Leh:oZ));Lnl:dF -dJ -q4 -Llq;Lei:q7=fp_imag -m6 -Lej:q7=fp_int -m6 -Lek:gU -cSec;wE(cSec);q4 -TailCall_cSec;Lel:gU -cSin;Lnm:wE(cSin);q4 -TailCall_cSin;Lem:q1 -cNeg -gI -cPow;Lnn:g0 -Lno:wE(cPow);q4 -TailCall_cPow;Len:gU -cCos;q4 -Lmm;Leo:gU -cCsc;wE(cCsc);q4 -TailCall_cCsc;Lep:q1 -cRSqrt);gJ -Leq:g6 -Lnp:w5=cCot;wE(cCot);q4 -TailCall_cCot;Lfa:q7=g1 -1)/x;gJ -Lfc:gT -fp_less(gW -Lfd:gT -fp_lessOrEq(gW -Lfe:d7 -cLog -o7 -oW -x)gX -Lna;Lff:q7=oW -x);gJ -Lfg:qF -dR -fp_const_e())gX -Lnl;Lfh:d7 -cLog10 -o7 -dR -x)gX -Lna;Lfi:q7=dR -x);gJ -Lfj:qF -o4 -fp_const_e())gX -Lnl;Lfk:d7 -cLog2 -o7 -o4 -x)gX -Lna;Lfl:q7=o4 -x);gJ -Lfm:gT -fp_max(x -d6 -Lfn:gT -fp_min(x -d6 -Lfo:gT -fp_mod(gW -Lfp:hV -oR -q0-=3;q4 -Lnp;Lfq:gU -cSqr;Lnq:wE(cSqr);q4 -TailCall_cSqr;Lga:gU -cDiv;q4 -Lne;Lgb:mM -cSqr -oT -Lgc:hV -3 -gC -cSqr);dM -Lml;Lgd:q7=x+g1 -1);gG -w5=cPow;q4 -Lno;Lge:gG -q4 -Lmb;Lgf:gT -x;Loa:dG -Lma;Lgg:qF1 -qM -Lob:hV -4 -gH -Loc:o6 -x);Lod:qW -q6 -gX -Lma;Lgh:qM -q4 -Lob;Lgi:q8 -4 -gC -B -gX -Loc;Lgj:q8 -oR -q4 -Loc;Lgk:qK -dJ -oS;Lgl:dI -q4 -Lmb;Lgm:qM -Loe:hV -oR -gJ -Lgn:q7=x+x;q4 -Lge;Lgo:gT -x;qL -4]dJ -q8 -4 -dT -o6 -y*x -q71);dM -Lnb;Lgp:gT -x;d7 -dU -qF -y*x -gX -Lna;Lgq:q7=RadiansToDegrees(x -gX -Lgl;Lha:qG1 -q8 -4 -gH -Lof:qE -dU -Log:qE -B -gI -cDiv;q4 -Lnh;Lhb:o9;oC=q6 -q9 -oR -q4 -Lof;Lhc:qG1 -q8 -oR -q4 -Log;Lhd:q8 -4 -gH -q4 -Lma;Lhe:q8 -4 -dT -qF -x+x -gX -Lod;Lhf:qF1 -qM -q4 -Loe;Lhg:qG1 -q4 -Loa;Lhh:o9;q4 -Lgl;Lhi:qG1 -q8 -oR -Loh:dM -Lni;Lhj:o9;qL -2 -gK -q4 -Loh;Lhk:qG1 -dG -Lni;Lhl:q7=h4 -gX -Lgl;Lhm:gT -x;qL -4]dJ -q8 -4 -dT -o6 -y*x -q71);dM -Lmk;Lhn:qG1 -q4 -Lba;Lho:qM -w3 -Lml;Lhp:dF=cDup;dW-=1;qM -Loi:w5=hS;q4 -Lmf;Lhq:qM -w3 -Lnf;Lia:qM -w3 -Lng;Lib:hV -oV -gX -Lof;Lic:hV -2 -gH -Loj:qE -cSqr -gX -Lma;Lid:q8 -oV -o7 -x -q71 -gX -Loh;Lie:mM -A -gX -Loh;Lif:hV -oR -q4 -Loj;Lig:dI -Lok:wE(cNEqual);q4 -TailCall_cNEqual;Lih:gT -fp_nequal(gW -Lii:o9;q4 -Lco;Lij:o9 -gB -cSin;g0 -q4 -Lnm;Lik:o9 -gB -cSinh;g0 -wE(cSinh);q4 -TailCall_cSinh;Lil:o9 -gB -cTan;g0 -q4 -Lnc;Lim:o9 -gB -cTanh;g0 -q4 -Lnd;Lin:o9;gJ -Lio:q1 -cAbsNot);gJ -Lip:gU -cNEqual;q4 -Lok;Liq:gU -cLessOrEq;wE(cLessOrEq);q4 -TailCall_cLessOrEq;Lja:gU -cLess;wE(cLess);q4 -TailCall_cLess;Ljb:gU -dK;wE(cGreaterOrEq);q4 -TailCall_cGreaterOrEq;Ljc:gU -o1;wE(cGreater);q4 -TailCall_cGreater;Ljd:gU -w8;q4 -Lnj;Lje:g6 -wE(cNot);q4 -TailCall_cNot;Ljf:q7=fp_not -m6 -Ljg:gT -fp_or(x -d6 -Ljh:gT -fp_polar(x -d6 -Lji:dL -Lnk;Ljj:qK=d8 -cExp2;g0 -wE(cExp2);q4 -TailCall_cExp2;Ljk:qG1 -dG -Lnn;Ljl:qK -dJ -q1 -h3 -gX -Lnn;Ljm:q7=g1 -gX -Lmq;Ljn:qM -w3 -Lmp;Ljo:qM -q5 -w5=cCbrt;g0 -wE(cCbrt);q4 -TailCall_cCbrt;Ljp:qM -q1 -cCbrt);Lol:w5=cInv;g0 -q4 -Lmn;Ljq:qM -q4 -Lep;Lka:qM -w3 -Lol;Lkb:q7=x+x;dI -q4 -Lno;Lkc:gT -oX -gW -Lkd:q1 -cTanh -gX -Lol;Lke:q7=h4 -gX -Lco;Lkf:q7=h4);gJ -Lkg:q7=fp_real -m6 -Lkh:mM -cSinCos -gX -Lol;Lki:q1 -cSin -oT -Lkj:q7=fp_sin -m6 -Lkk:q1 -cSqr -o7 -g1-1)gX -Lmo;Lkl:q1 -cSinh -oT -Lkm:q7=fp_sinh -m6 -Lkn:g6 -q4 -Lnq;Lko:hV -4 -gC -A);Lom:w5=cHypot;g0 -wE(cHypot);q4 -TailCall_cHypot;Lkp:hV -5 -gC -A -oJ -B -gX -Lom;Lkq:gU -cAbs;q4 -Llp;Lla:q7=fp_sqrt -m6 -Llb:g6 -q4 -Loi;Llc:gT -y-x;q4 -Lba;Lld:o9;q4 -Loi;Lle:q8 -oV -oJ -hS -o7 -x -q71 -gX -Lmh;Llf:mM -A -oJ -cSub -gX -Lmh;Llg:q1 -cTan -oT -Llh:q7=fp_tan -m6 -Lli:q1 -cTanh -oT -Llj:q7=fp_tanh -m6 -Llk:q7=fp_trunc -m6 -Lll:qW -cDup);gJ -Llm:dF=cDup;gJ -Lln:hV -3 -gC -cSinCos);Lon:qE -GetParamSwappedBinaryOpcode(C));gJ -Llo:hV -3 -gC -cSinhCosh -gX -Lon;gJ -q4 -TailCall_cAcos;q4 -TailCall_cAcosh;q4 -TailCall_cAnd;q4 -TailCall_cArg;q4 -TailCall_cAsin;q4 -TailCall_cAsinh;q4 -TailCall_cAtan;q4 -TailCall_cAtan2;q4 -TailCall_cAtanh;q4 -TailCall_cCeil;q4 -TailCall_cConj;q4 -TailCall_cFloor;q4 -TailCall_cImag;q4 -TailCall_cInt;q4 -TailCall_cLog;q4 -TailCall_cLog10;q4 -TailCall_cLog2;q4 -TailCall_cMax;q4 -TailCall_cMin;q4 -TailCall_cMod;q4 -TailCall_cOr;q4 -TailCall_cPolar;q4 -TailCall_cRDiv;q4 -TailCall_cRad;q4 -TailCall_cReal;q4 -TailCall_cSec;q4 -TailCall_cSin;q4 -TailCall_cSinh;q4 -TailCall_cSqrt;q4 -TailCall_cSub;q4 -TailCall_cTan;q4 -TailCall_cTanh;q4 -TailCall_cTrunc; -#endif -#undef FP_ReDefinePointers -#undef FP_TRACE_BYTECODE_OPTIMIZATION -#undef FP_TRACE_OPCODENAME diff --git a/fparser/extrasrc/fpaux.hh b/fparser/extrasrc/fpaux.hh deleted file mode 100644 index fe2011c..0000000 --- a/fparser/extrasrc/fpaux.hh +++ /dev/null @@ -1,1238 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.5.1 *| -|*-------------------------------------------------------------------------*| -|* Copyright: Juha Nieminen, Joel Yliluoma *| -|* *| -|* This library is distributed under the terms of the *| -|* GNU Lesser General Public License version 3. *| -|* (See lgpl.txt and gpl.txt for the license text.) *| -\***************************************************************************/ - -// NOTE: -// This file contains only internal types for the function parser library. -// You don't need to include this file in your code. Include "fparser.hh" -// only. - -#ifndef ONCE_FPARSER_AUX_H_ -#define ONCE_FPARSER_AUX_H_ - -#include "fptypes.hh" - -#include - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE -#include "mpfr/MpfrFloat.hh" -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE -#include "mpfr/GmpInt.hh" -#endif - -#ifdef FP_SUPPORT_COMPLEX_NUMBERS -#include -#endif - -#ifdef ONCE_FPARSER_H_ -namespace FUNCTIONPARSERTYPES -{ - template - struct IsIntType - { - enum { result = false }; - }; - template<> - struct IsIntType - { - enum { result = true }; - }; -#ifdef FP_SUPPORT_GMP_INT_TYPE - template<> - struct IsIntType - { - enum { result = true }; - }; -#endif - - template - struct IsComplexType - { - enum { result = false }; - }; -#ifdef FP_SUPPORT_COMPLEX_NUMBERS - template - struct IsComplexType > - { - enum { result = true }; - }; -#endif - - -//========================================================================== -// Constants -//========================================================================== - template - inline Value_t fp_const_pi() // CONSTANT_PI - { - return Value_t(3.1415926535897932384626433832795028841971693993751L); - } - - template - inline Value_t fp_const_e() // CONSTANT_E - { - return Value_t(2.7182818284590452353602874713526624977572L); - } - template - inline Value_t fp_const_einv() // CONSTANT_EI - { - return Value_t(0.367879441171442321595523770161460867445811131L); - } - template - inline Value_t fp_const_log2() // CONSTANT_L2, CONSTANT_L2EI - { - return Value_t(0.69314718055994530941723212145817656807550013436025525412L); - } - template - inline Value_t fp_const_log10() // CONSTANT_L10, CONSTANT_L10EI - { - return Value_t(2.302585092994045684017991454684364207601101488628772976L); - } - template - inline Value_t fp_const_log2inv() // CONSTANT_L2I, CONSTANT_L2E - { - return Value_t(1.442695040888963407359924681001892137426645954L); - } - template - inline Value_t fp_const_log10inv() // CONSTANT_L10I, CONSTANT_L10E - { - return Value_t(0.434294481903251827651128918916605082294397L); - } - - template - inline const Value_t& fp_const_deg_to_rad() // CONSTANT_DR - { - static const Value_t factor = fp_const_pi() / Value_t(180); // to rad from deg - return factor; - } - - template - inline const Value_t& fp_const_rad_to_deg() // CONSTANT_RD - { - static const Value_t factor = Value_t(180) / fp_const_pi(); // to deg from rad - return factor; - } - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE - template<> - inline MpfrFloat fp_const_pi() { return MpfrFloat::const_pi(); } - - template<> - inline MpfrFloat fp_const_e() { return MpfrFloat::const_e(); } - - template<> - inline MpfrFloat fp_const_einv() { return MpfrFloat(1) / MpfrFloat::const_e(); } - - template<> - inline MpfrFloat fp_const_log2() { return MpfrFloat::const_log2(); } - - /* - template<> - inline MpfrFloat fp_const_log10() { return fp_log(MpfrFloat(10)); } - - template<> - inline MpfrFloat fp_const_log2inv() { return MpfrFloat(1) / MpfrFloat::const_log2(); } - - template<> - inline MpfrFloat fp_const_log10inv() { return fp_log10(MpfrFloat::const_e()); } - */ -#endif - - -//========================================================================== -// Generic math functions -//========================================================================== - template - inline Value_t fp_abs(const Value_t& x) { return std::fabs(x); } - - template - inline Value_t fp_acos(const Value_t& x) { return std::acos(x); } - - template - inline Value_t fp_asin(const Value_t& x) { return std::asin(x); } - - template - inline Value_t fp_atan(const Value_t& x) { return std::atan(x); } - - template - inline Value_t fp_atan2(const Value_t& x, const Value_t& y) - { return std::atan2(x, y); } - - template - inline Value_t fp_ceil(const Value_t& x) { return std::ceil(x); } - - template - inline Value_t fp_cos(const Value_t& x) { return std::cos(x); } - - template - inline Value_t fp_cosh(const Value_t& x) { return std::cosh(x); } - - template - inline Value_t fp_exp(const Value_t& x) { return std::exp(x); } - - template - inline Value_t fp_floor(const Value_t& x) { return std::floor(x); } - - template - inline Value_t fp_log(const Value_t& x) { return std::log(x); } - - template - inline Value_t fp_mod(const Value_t& x, const Value_t& y) - { return std::fmod(x, y); } - - template - inline Value_t fp_sin(const Value_t& x) { return std::sin(x); } - - template - inline Value_t fp_sinh(const Value_t& x) { return std::sinh(x); } - - template - inline Value_t fp_sqrt(const Value_t& x) { return std::sqrt(x); } - - template - inline Value_t fp_tan(const Value_t& x) { return std::tan(x); } - - template - inline Value_t fp_tanh(const Value_t& x) { return std::tanh(x); } - -#ifdef FP_SUPPORT_CPLUSPLUS11_MATH_FUNCS - template - inline Value_t fp_asinh(const Value_t& x) { return std::asinh(x); } - - template - inline Value_t fp_acosh(const Value_t& x) { return std::acosh(x); } - - template - inline Value_t fp_atanh(const Value_t& x) { return std::atanh(x); } -#else - template - inline Value_t fp_asinh(const Value_t& x) - { return fp_log(x + fp_sqrt(x*x + Value_t(1))); } - - template - inline Value_t fp_acosh(const Value_t& x) - { return fp_log(x + fp_sqrt(x*x - Value_t(1))); } - - template - inline Value_t fp_atanh(const Value_t& x) - { - return fp_log( (Value_t(1)+x) / (Value_t(1)-x)) * Value_t(0.5); - // Note: x = +1 causes division by zero - // x = -1 causes log(0) - // Thus, x must not be +-1 - } -#endif // FP_SUPPORT_ASINH - -#ifdef FP_SUPPORT_CPLUSPLUS11_MATH_FUNCS - template - inline Value_t fp_hypot(const Value_t& x, const Value_t& y) - { return std::hypot(x,y); } -#else - template - inline Value_t fp_hypot(const Value_t& x, const Value_t& y) - { return fp_sqrt(x*x + y*y); } -#endif - - template - inline Value_t fp_pow_base(const Value_t& x, const Value_t& y) - { return std::pow(x, y); } - -#ifdef FP_SUPPORT_CPLUSPLUS11_MATH_FUNCS - template - inline Value_t fp_log2(const Value_t& x) { return std::log2(x); } -#else - template - inline Value_t fp_log2(const Value_t& x) - { - return fp_log(x) * fp_const_log2inv(); - } -#endif // FP_SUPPORT_LOG2 - - template - inline Value_t fp_log10(const Value_t& x) - { - return fp_log(x) * fp_const_log10inv(); - } - - template - inline Value_t fp_trunc(const Value_t& x) - { - return x < Value_t() ? fp_ceil(x) : fp_floor(x); - } - - template - inline Value_t fp_int(const Value_t& x) - { - return x < Value_t() ? - fp_ceil(x - Value_t(0.5)) : fp_floor(x + Value_t(0.5)); - } - - template - inline void fp_sinCos(Value_t& sinvalue, Value_t& cosvalue, - const Value_t& param) - { - // Assuming that "cosvalue" and "param" do not - // overlap, but "sinvalue" and "param" may. - cosvalue = fp_cos(param); - sinvalue = fp_sin(param); - } - - template - inline void fp_sinhCosh(Value_t& sinhvalue, Value_t& coshvalue, - const Value_t& param) - { - const Value_t ex(fp_exp(param)), emx(fp_exp(-param)); - sinhvalue = Value_t(0.5)*(ex-emx); - coshvalue = Value_t(0.5)*(ex+emx); - } - - template - struct Epsilon - { - static Value_t value; - static Value_t defaultValue() { return 0; } - }; - - template<> inline double Epsilon::defaultValue() { return 1E-12; } - template<> inline float Epsilon::defaultValue() { return 1E-5F; } - template<> inline long double Epsilon::defaultValue() { return 1E-14L; } - - template<> inline std::complex - Epsilon >::defaultValue() { return 1E-12; } - - template<> inline std::complex - Epsilon >::defaultValue() { return 1E-5F; } - - template<> inline std::complex - Epsilon >::defaultValue() { return 1E-14L; } - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE - template<> inline MpfrFloat - Epsilon::defaultValue() { return MpfrFloat::someEpsilon(); } -#endif - - template Value_t Epsilon::value = - Epsilon::defaultValue(); - - -#ifdef _GNU_SOURCE - inline void fp_sinCos(double& sin, double& cos, const double& a) - { - sincos(a, &sin, &cos); - } - inline void fp_sinCos(float& sin, float& cos, const float& a) - { - sincosf(a, &sin, &cos); - } - inline void fp_sinCos(long double& sin, long double& cos, - const long double& a) - { - sincosl(a, &sin, &cos); - } -#endif - - -// ------------------------------------------------------------------------- -// Long int -// ------------------------------------------------------------------------- - inline long fp_abs(const long& x) { return x < 0 ? -x : x; } - inline long fp_acos(const long&) { return 0; } - inline long fp_asin(const long&) { return 0; } - inline long fp_atan(const long&) { return 0; } - inline long fp_atan2(const long&, const long&) { return 0; } - inline long fp_cbrt(const long&) { return 0; } - inline long fp_ceil(const long& x) { return x; } - inline long fp_cos(const long&) { return 0; } - inline long fp_cosh(const long&) { return 0; } - inline long fp_exp(const long&) { return 0; } - inline long fp_exp2(const long&) { return 0; } - inline long fp_floor(const long& x) { return x; } - inline long fp_log(const long&) { return 0; } - inline long fp_log2(const long&) { return 0; } - inline long fp_log10(const long&) { return 0; } - inline long fp_mod(const long& x, const long& y) { return x % y; } - inline long fp_pow(const long&, const long&) { return 0; } - inline long fp_sin(const long&) { return 0; } - inline long fp_sinh(const long&) { return 0; } - inline long fp_sqrt(const long&) { return 1; } - inline long fp_tan(const long&) { return 0; } - inline long fp_tanh(const long&) { return 0; } - inline long fp_asinh(const long&) { return 0; } - inline long fp_acosh(const long&) { return 0; } - inline long fp_atanh(const long&) { return 0; } - inline long fp_pow_base(const long&, const long&) { return 0; } - inline void fp_sinCos(long&, long&, const long&) {} - inline void fp_sinhCosh(long&, long&, const long&) {} - - //template<> inline long fp_epsilon() { return 0; } - - -// ------------------------------------------------------------------------- -// MpfrFloat -// ------------------------------------------------------------------------- -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE - inline MpfrFloat fp_abs(const MpfrFloat& x) { return MpfrFloat::abs(x); } - inline MpfrFloat fp_acos(const MpfrFloat& x) { return MpfrFloat::acos(x); } - inline MpfrFloat fp_acosh(const MpfrFloat& x) { return MpfrFloat::acosh(x); } - inline MpfrFloat fp_asin(const MpfrFloat& x) { return MpfrFloat::asin(x); } - inline MpfrFloat fp_asinh(const MpfrFloat& x) { return MpfrFloat::asinh(x); } - inline MpfrFloat fp_atan(const MpfrFloat& x) { return MpfrFloat::atan(x); } - inline MpfrFloat fp_atan2(const MpfrFloat& x, const MpfrFloat& y) - { return MpfrFloat::atan2(x, y); } - inline MpfrFloat fp_atanh(const MpfrFloat& x) { return MpfrFloat::atanh(x); } - inline MpfrFloat fp_cbrt(const MpfrFloat& x) { return MpfrFloat::cbrt(x); } - inline MpfrFloat fp_ceil(const MpfrFloat& x) { return MpfrFloat::ceil(x); } - inline MpfrFloat fp_cos(const MpfrFloat& x) { return MpfrFloat::cos(x); } - inline MpfrFloat fp_cosh(const MpfrFloat& x) { return MpfrFloat::cosh(x); } - inline MpfrFloat fp_exp(const MpfrFloat& x) { return MpfrFloat::exp(x); } - inline MpfrFloat fp_exp2(const MpfrFloat& x) { return MpfrFloat::exp2(x); } - inline MpfrFloat fp_floor(const MpfrFloat& x) { return MpfrFloat::floor(x); } - inline MpfrFloat fp_hypot(const MpfrFloat& x, const MpfrFloat& y) - { return MpfrFloat::hypot(x, y); } - inline MpfrFloat fp_int(const MpfrFloat& x) { return MpfrFloat::round(x); } - inline MpfrFloat fp_log(const MpfrFloat& x) { return MpfrFloat::log(x); } - inline MpfrFloat fp_log2(const MpfrFloat& x) { return MpfrFloat::log2(x); } - inline MpfrFloat fp_log10(const MpfrFloat& x) { return MpfrFloat::log10(x); } - inline MpfrFloat fp_mod(const MpfrFloat& x, const MpfrFloat& y) { return x % y; } - inline MpfrFloat fp_sin(const MpfrFloat& x) { return MpfrFloat::sin(x); } - inline MpfrFloat fp_sinh(const MpfrFloat& x) { return MpfrFloat::sinh(x); } - inline MpfrFloat fp_sqrt(const MpfrFloat& x) { return MpfrFloat::sqrt(x); } - inline MpfrFloat fp_tan(const MpfrFloat& x) { return MpfrFloat::tan(x); } - inline MpfrFloat fp_tanh(const MpfrFloat& x) { return MpfrFloat::tanh(x); } - inline MpfrFloat fp_trunc(const MpfrFloat& x) { return MpfrFloat::trunc(x); } - - inline MpfrFloat fp_pow(const MpfrFloat& x, const MpfrFloat& y) { return MpfrFloat::pow(x, y); } - inline MpfrFloat fp_pow_base(const MpfrFloat& x, const MpfrFloat& y) { return MpfrFloat::pow(x, y); } - - - inline void fp_sinCos(MpfrFloat& sin, MpfrFloat& cos, const MpfrFloat& a) - { - MpfrFloat::sincos(a, sin, cos); - } - - inline void fp_sinhCosh(MpfrFloat& sinhvalue, MpfrFloat& coshvalue, - const MpfrFloat& param) - { - const MpfrFloat paramCopy = param; - sinhvalue = fp_sinh(paramCopy); - coshvalue = fp_cosh(paramCopy); - } -#endif // FP_SUPPORT_MPFR_FLOAT_TYPE - - -// ------------------------------------------------------------------------- -// GMP int -// ------------------------------------------------------------------------- -#ifdef FP_SUPPORT_GMP_INT_TYPE - inline GmpInt fp_abs(const GmpInt& x) { return GmpInt::abs(x); } - inline GmpInt fp_acos(const GmpInt&) { return 0; } - inline GmpInt fp_acosh(const GmpInt&) { return 0; } - inline GmpInt fp_asin(const GmpInt&) { return 0; } - inline GmpInt fp_asinh(const GmpInt&) { return 0; } - inline GmpInt fp_atan(const GmpInt&) { return 0; } - inline GmpInt fp_atan2(const GmpInt&, const GmpInt&) { return 0; } - inline GmpInt fp_atanh(const GmpInt&) { return 0; } - inline GmpInt fp_cbrt(const GmpInt&) { return 0; } - inline GmpInt fp_ceil(const GmpInt& x) { return x; } - inline GmpInt fp_cos(const GmpInt&) { return 0; } - inline GmpInt fp_cosh(const GmpInt&) { return 0; } - inline GmpInt fp_exp(const GmpInt&) { return 0; } - inline GmpInt fp_exp2(const GmpInt&) { return 0; } - inline GmpInt fp_floor(const GmpInt& x) { return x; } - inline GmpInt fp_hypot(const GmpInt&, const GmpInt&) { return 0; } - inline GmpInt fp_int(const GmpInt& x) { return x; } - inline GmpInt fp_log(const GmpInt&) { return 0; } - inline GmpInt fp_log2(const GmpInt&) { return 0; } - inline GmpInt fp_log10(const GmpInt&) { return 0; } - inline GmpInt fp_mod(const GmpInt& x, const GmpInt& y) { return x % y; } - inline GmpInt fp_pow(const GmpInt&, const GmpInt&) { return 0; } - inline GmpInt fp_sin(const GmpInt&) { return 0; } - inline GmpInt fp_sinh(const GmpInt&) { return 0; } - inline GmpInt fp_sqrt(const GmpInt&) { return 0; } - inline GmpInt fp_tan(const GmpInt&) { return 0; } - inline GmpInt fp_tanh(const GmpInt&) { return 0; } - inline GmpInt fp_trunc(const GmpInt& x) { return x; } - inline GmpInt fp_pow_base(const GmpInt&, const GmpInt&) { return 0; } - inline void fp_sinCos(GmpInt&, GmpInt&, const GmpInt&) {} - inline void fp_sinhCosh(GmpInt&, GmpInt&, const GmpInt&) {} -#endif // FP_SUPPORT_GMP_INT_TYPE - - -#ifdef FP_SUPPORT_CPLUSPLUS11_MATH_FUNCS - template - inline Value_t fp_cbrt(const Value_t& x) { return std::cbrt(x); } -#else - template - inline Value_t fp_cbrt(const Value_t& x) - { - return (x > Value_t() ? fp_exp(fp_log( x) / Value_t(3)) : - x < Value_t() ? -fp_exp(fp_log(-x) / Value_t(3)) : - Value_t()); - } -#endif - -// ------------------------------------------------------------------------- -// Synthetic functions and fallbacks for when an optimized -// implementation or a library function is not available -// ------------------------------------------------------------------------- - template inline Value_t fp_arg(const Value_t& x); - template inline Value_t fp_exp2(const Value_t& x); - template inline Value_t fp_int(const Value_t& x); - template inline Value_t fp_trunc(const Value_t& x); - template - inline void fp_sinCos(Value_t& , Value_t& , const Value_t& ); - template - inline void fp_sinhCosh(Value_t& , Value_t& , const Value_t& ); - -#ifdef FP_SUPPORT_COMPLEX_NUMBERS - /* NOTE: Complex multiplication of a and b can be done with: - tmp = b.real * (a.real + a.imag) - result.real = tmp - a.imag * (b.real + b.imag) - result.imag = tmp + a.real * (b.imag - b.real) - This has fewer multiplications than the standard - algorithm. Take note, if you support mpfr complex one day. - */ - - template - struct FP_ProbablyHasFastLibcComplex - { enum { result = false }; }; - /* The generic sqrt() etc. implementations in libstdc++ - * are very plain and non-optimized; however, it contains - * callbacks to libc complex math functions where possible, - * and I suspect that those may actually be well optimized. - * So we use std:: functions when we suspect they may be fast, - * and otherwise we use our own optimized implementations. - */ -#ifdef __GNUC__ - template<> struct FP_ProbablyHasFastLibcComplex - { enum { result = true }; }; - template<> struct FP_ProbablyHasFastLibcComplex - { enum { result = true }; }; - template<> struct FP_ProbablyHasFastLibcComplex - { enum { result = true }; }; -#endif - - template - inline const std::complex fp_make_imag(const std::complex& v) - { - return std::complex ( T(), v.real() ); - } - - template - inline std::complex fp_real(const std::complex& x) - { - return x.real(); - } - template - inline std::complex fp_imag(const std::complex& x) - { - return x.imag(); - } - template - inline std::complex fp_arg(const std::complex& x) - { - return std::arg(x); - } - template - inline std::complex fp_conj(const std::complex& x) - { - return std::conj(x); - } - template - inline std::complex fp_polar(const T& x, const T& y) - { - T si, co; fp_sinCos(si, co, y); - return std::complex (x*co, x*si); - } - template - inline std::complex fp_polar(const std::complex& x, const std::complex& y) - { - // x * cos(y) + i * x * sin(y) -- arguments are supposed to be REAL numbers - return fp_polar (x.real(), y.real()); - //return std::polar(x.real(), y.real()); - //return x * (fp_cos(y) + (std::complex(0,1) * fp_sin(y)); - } - - // These provide fallbacks in case there's no library function - template - inline std::complex fp_floor(const std::complex& x) - { - return std::complex (fp_floor(x.real()), fp_floor(x.imag())); - } - template - inline std::complex fp_trunc(const std::complex& x) - { - return std::complex (fp_trunc(x.real()), fp_trunc(x.imag())); - } - template - inline std::complex fp_int(const std::complex& x) - { - return std::complex (fp_int(x.real()), fp_int(x.imag())); - } - template - inline std::complex fp_ceil(const std::complex& x) - { - return std::complex (fp_ceil(x.real()), fp_ceil(x.imag())); - } - template - inline std::complex fp_abs(const std::complex& x) - { - return std::abs(x); - //T extent = fp_max(fp_abs(x.real()), fp_abs(x.imag())); - //if(extent == T()) return x; - //return extent * fp_hypot(x.real() / extent, x.imag() / extent); - } - template - inline std::complex fp_exp(const std::complex& x) - { - if(FP_ProbablyHasFastLibcComplex::result) - return std::exp(x); - return fp_polar(fp_exp(x.real()), x.imag()); - } - template - inline std::complex fp_log(const std::complex& x) - { - if(FP_ProbablyHasFastLibcComplex::result) - return std::log(x); - // log(abs(x)) + i*arg(x) - // log(Xr^2+Xi^2)*0.5 + i*arg(x) - if(x.imag()==T()) - return std::complex( fp_log(fp_abs(x.real())), - fp_arg(x.real()) ); // Note: Uses real-value fp_arg() here! - return std::complex( - fp_log(std::norm(x)) * T(0.5), - fp_arg(x).real() ); - } - template - inline std::complex fp_sqrt(const std::complex& x) - { - if(FP_ProbablyHasFastLibcComplex::result) - return std::sqrt(x); - return fp_polar (fp_sqrt(fp_abs(x).real()), - T(0.5)*fp_arg(x).real()); - } - template - inline std::complex fp_acos(const std::complex& x) - { - // -i * log(x + i * sqrt(1 - x^2)) - const std::complex i (T(), T(1)); - return -i * fp_log(x + i * fp_sqrt(T(1) - x*x)); - // Note: Real version of acos() cannot handle |x| > 1, - // because it would cause sqrt(negative value). - } - template - inline std::complex fp_asin(const std::complex& x) - { - // -i * log(i*x + sqrt(1 - x^2)) - const std::complex i (T(), T(1)); - return -i * fp_log(i*x + fp_sqrt(T(1) - x*x)); - // Note: Real version of asin() cannot handle |x| > 1, - // because it would cause sqrt(negative value). - } - template - inline std::complex fp_atan(const std::complex& x) - { - // 0.5i * (log(1-i*x) - log(1+i*x)) - // -0.5i * log( (1+i*x) / (1-i*x) ) - const std::complex i (T(), T(1)); - return (T(-0.5)*i) * fp_log( (T(1)+i*x) / (T(1)-i*x) ); - // Note: x = -1i causes division by zero - // x = +1i causes log(0) - // Thus, x must not be +-1i - } - template - inline std::complex fp_cos(const std::complex& x) - { - return std::cos(x); - // // (exp(i*x) + exp(-i*x)) / (2) - // //const std::complex i (T(), T(1)); - // //return (fp_exp(i*x) + fp_exp(-i*x)) * T(0.5); - // // Also: cos(Xr)*cosh(Xi) - i*sin(Xr)*sinh(Xi) - // return std::complex ( - // fp_cos(x.real())*fp_cosh(x.imag()), - // -fp_sin(x.real())*fp_sinh(x.imag())); - } - template - inline std::complex fp_sin(const std::complex& x) - { - return std::sin(x); - // // (exp(i*x) - exp(-i*x)) / (2i) - // //const std::complex i (T(), T(1)); - // //return (fp_exp(i*x) - fp_exp(-i*x)) * (T(-0.5)*i); - // // Also: sin(Xr)*cosh(Xi) + cos(Xr)*sinh(Xi) - // return std::complex ( - // fp_sin(x.real())*fp_cosh(x.imag()), - // fp_cos(x.real())*fp_sinh(x.imag())); - } - template - inline void fp_sinCos( - std::complex& sinvalue, - std::complex& cosvalue, - const std::complex& x) - { - //const std::complex i (T(), T(1)), expix(fp_exp(i*x)), expmix(fp_exp((-i)*x)); - //cosvalue = (expix + expmix) * T(0.5); - //sinvalue = (expix - expmix) * (i*T(-0.5)); - // The above expands to the following: - T srx, crx; fp_sinCos(srx, crx, x.real()); - T six, cix; fp_sinhCosh(six, cix, x.imag()); - sinvalue = std::complex(srx*cix, crx*six); - cosvalue = std::complex(crx*cix, -srx*six); - } - template - inline void fp_sinhCosh( - std::complex& sinhvalue, - std::complex& coshvalue, - const std::complex& x) - { - T srx, crx; fp_sinhCosh(srx, crx, x.real()); - T six, cix; fp_sinCos(six, cix, x.imag()); - sinhvalue = std::complex(srx*cix, crx*six); - coshvalue = std::complex(crx*cix, srx*six); - } - template - inline std::complex fp_tan(const std::complex& x) - { - return std::tan(x); - //std::complex si, co; - //fp_sinCos(si, co, x); - //return si/co; - // // (i-i*exp(2i*x)) / (exp(2i*x)+1) - // const std::complex i (T(), T(1)), exp2ix=fp_exp((2*i)*x); - // return (i-i*exp2ix) / (exp2ix+T(1)); - // // Also: sin(x)/cos(y) - // // return fp_sin(x)/fp_cos(x); - } - template - inline std::complex fp_cosh(const std::complex& x) - { - return std::cosh(x); - // // (exp(x) + exp(-x)) * 0.5 - // // Also: cosh(Xr)*cos(Xi) + i*sinh(Xr)*sin(Xi) - // return std::complex ( - // fp_cosh(x.real())*fp_cos(x.imag()), - // fp_sinh(x.real())*fp_sin(x.imag())); - } - template - inline std::complex fp_sinh(const std::complex& x) - { - return std::sinh(x); - // // (exp(x) - exp(-x)) * 0.5 - // // Also: sinh(Xr)*cos(Xi) + i*cosh(Xr)*sin(Xi) - // return std::complex ( - // fp_sinh(x.real())*fp_cos(x.imag()), - // fp_cosh(x.real())*fp_sin(x.imag())); - } - template - inline std::complex fp_tanh(const std::complex& x) - { - return std::tanh(x); - //std::complex si, co; - //fp_sinhCosh(si, co, x); - //return si/co; - // // (exp(2*x)-1) / (exp(2*x)+1) - // // Also: sinh(x)/tanh(x) - // const std::complex exp2x=fp_exp(x+x); - // return (exp2x-T(1)) / (exp2x+T(1)); - } - -#ifdef FP_SUPPORT_CPLUSPLUS11_MATH_FUNCS - template - inline std::complex fp_acosh(const std::complex& x) - { return fp_log(x + fp_sqrt(x*x - std::complex(1))); } - template - inline std::complex fp_asinh(const std::complex& x) - { return fp_log(x + fp_sqrt(x*x + std::complex(1))); } - template - inline std::complex fp_atanh(const std::complex& x) - { return fp_log( (std::complex(1)+x) / (std::complex(1)-x)) - * std::complex(0.5); } -#endif - template - inline std::complex fp_pow(const std::complex& x, const std::complex& y) - { - // return std::pow(x,y); - - // With complex numbers, pow(x,y) can be solved with - // the general formula: exp(y*log(x)). It handles - // all special cases gracefully. - // It expands to the following: - // A) - // t1 = log(x) - // t2 = y * t1 - // res = exp(t2) - // B) - // t1.r = log(x.r * x.r + x.i * x.i) * 0.5 \ fp_log() - // t1.i = atan2(x.i, x.r) / - // t2.r = y.r*t1.r - y.i*t1.i \ multiplication - // t2.i = y.r*t1.i + y.i*t1.r / - // rho = exp(t2.r) \ fp_exp() - // theta = t2.i / - // res.r = rho * cos(theta) \ fp_polar(), called from - // res.i = rho * sin(theta) / fp_exp(). Uses sincos(). - // Aside from the common "norm" calculation in atan2() - // and in the log parameter, both of which are part of fp_log(), - // there does not seem to be any incentive to break this - // function down further; it would not help optimizing it. - // However, we do handle the following special cases: - // - // When x is real (positive or negative): - // t1.r = log(abs(x.r)) - // t1.i = x.r<0 ? -pi : 0 - // When y is real: - // t2.r = y.r * t1.r - // t2.i = y.r * t1.i - const std::complex t = - (x.imag() != T()) - ? fp_log(x) - : std::complex (fp_log(fp_abs(x.real())), - fp_arg(x.real())); // Note: Uses real-value fp_arg() here! - return y.imag() != T() - ? fp_exp(y * t) - : fp_polar (fp_exp(y.real()*t.real()), y.real()*t.imag()); - } - template - inline std::complex fp_cbrt(const std::complex& x) - { - // For real numbers, prefer giving a real solution - // rather than a complex solution. - // For example, cbrt(-3) has the following three solutions: - // A) 0.7211247966535 + 1.2490247864016i - // B) 0.7211247966535 - 1.2490247864016i - // C) -1.442249593307 - // exp(log(x)/3) gives A, but we prefer to give C. - if(x.imag() == T()) return fp_cbrt(x.real()); - const std::complex t(fp_log(x)); - return fp_polar (fp_exp(t.real() / T(3)), t.imag() / T(3)); - } - - template - inline std::complex fp_exp2(const std::complex& x) - { - // pow(2, x) - // polar(2^Xr, Xi*log(2)) - return fp_polar (fp_exp2(x.real()), x.imag()*fp_const_log2()); - } - template - inline std::complex fp_mod(const std::complex& x, const std::complex& y) - { - // Modulo function is probably not defined for complex numbers. - // But we do our best to calculate it the same way as it is done - // with real numbers, so that at least it is in some way "consistent". - if(y.imag() == 0) return fp_mod(x.real(), y.real()); // optimization - std::complex n = fp_trunc(x / y); - return x - n * y; - } - - /* libstdc++ already defines a streaming operator for complex values, - * but we redefine our own that it is compatible with the input - * accepted by fparser. I.e. instead of (5,3) we now get (5+3i), - * and instead of (-4,0) we now get -4. - */ - template - inline std::ostream& operator<<(std::ostream& os, const std::complex& value) - { - if(value.imag() == T()) return os << value.real(); - if(value.real() == T()) return os << value.imag() << 'i'; - if(value.imag() < T()) - return os << '(' << value.real() << "-" << -value.imag() << "i)"; - else - return os << '(' << value.real() << "+" << value.imag() << "i)"; - } - - /* Less-than or greater-than operators are not technically defined - * for Complex types. However, in fparser and its tool set, these - * operators are widely required to be present. - * Our implementation here is based on converting the complex number - * into a scalar and the doing a scalar comparison on the value. - * The means by which the number is changed into a scalar is based - * on the following principles: - * - Does not introduce unjustified amounts of extra inaccuracy - * - Is transparent to purely real values - * (this disqualifies something like x.real() + x.imag()) - * - Does not ignore the imaginary value completely - * (this may be relevant especially in testbed) - * - Is not so complicated that it would slow down a great deal - * - * Basically our formula here is the same as std::abs(), - * except that it keeps the sign of the original real number, - * and it does not do a sqrt() calculation that is not really - * needed because we are only interested in the relative magnitudes. - * - * Equality and nonequality operators must not need to be overloaded. - * They are already implemented in standard, and we must - * not introduce flawed equality assumptions. - */ - template - inline T fp_complexScalarize(const std::complex& x) - { - T res(std::norm(x)); - if(x.real() < T()) res = -res; - return res; - } - template - inline T fp_realComplexScalarize(const T& x) - { - T res(x*x); - if(x < T()) res = -res; - return res; - } - // { return x.real() * (T(1.0) + fp_abs(x.imag())); } - #define d(op) \ - template \ - inline bool operator op (const std::complex& x, T y) \ - { return fp_complexScalarize(x) op fp_realComplexScalarize(y); } \ - template \ - inline bool operator op (const std::complex& x, const std::complex& y) \ - { return fp_complexScalarize(x) op \ - fp_complexScalarize(y); } \ - template \ - inline bool operator op (T x, const std::complex& y) \ - { return fp_realComplexScalarize(x) op fp_complexScalarize(y); } - d( < ) d( <= ) d( > ) d( >= ) - #undef d -#endif - - template - inline Value_t fp_real(const Value_t& x) { return x; } - template - inline Value_t fp_imag(const Value_t& ) { return Value_t(); } - template - inline Value_t fp_arg(const Value_t& x) - { return x < Value_t() ? -fp_const_pi() : Value_t(); } - template - inline Value_t fp_conj(const Value_t& x) { return x; } - template - inline Value_t fp_polar(const Value_t& x, const Value_t& y) - { return x * fp_cos(y); } // This is of course a meaningless function. - - template - inline std::complex fp_atan2(const std::complex& y, - const std::complex& x) - { - if(y == Value_t()) return fp_arg(x); - if(x == Value_t()) return fp_const_pi() * Value_t(-0.5); - // 2*atan(y / (sqrt(x^2+y^2) + x) ) - // 2*atan( (sqrt(x^2+y^2) - x) / y) - std::complex res( fp_atan(y / (fp_hypot(x,y) + x)) ); - return res+res; - } - -// ------------------------------------------------------------------------- -// Comparison -// ------------------------------------------------------------------------- - template - inline bool fp_equal(const Value_t& x, const Value_t& y) - { return IsIntType::result - ? (x == y) - : (fp_abs(x - y) <= Epsilon::value); } - - template - inline bool fp_nequal(const Value_t& x, const Value_t& y) - { return IsIntType::result - ? (x != y) - : (fp_abs(x - y) > Epsilon::value); } - - template - inline bool fp_less(const Value_t& x, const Value_t& y) - { return IsIntType::result - ? (x < y) - : (x < y - Epsilon::value); } - - template - inline bool fp_lessOrEq(const Value_t& x, const Value_t& y) - { return IsIntType::result - ? (x <= y) - : (x <= y + Epsilon::value); } - - - template - inline bool fp_greater(const Value_t& x, const Value_t& y) - { return fp_less(y, x); } - - template - inline bool fp_greaterOrEq(const Value_t& x, const Value_t& y) - { return fp_lessOrEq(y, x); } - - template - inline bool fp_truth(const Value_t& d) - { - return IsIntType::result - ? d != Value_t() - : fp_abs(d) >= Value_t(0.5); - } - - template - inline bool fp_absTruth(const Value_t& abs_d) - { - return IsIntType::result - ? abs_d > Value_t() - : abs_d >= Value_t(0.5); - } - - template - inline const Value_t& fp_min(const Value_t& d1, const Value_t& d2) - { return d1 - inline const Value_t& fp_max(const Value_t& d1, const Value_t& d2) - { return d1>d2 ? d1 : d2; } - - template - inline const Value_t fp_not(const Value_t& b) - { return Value_t(!fp_truth(b)); } - - template - inline const Value_t fp_notNot(const Value_t& b) - { return Value_t(fp_truth(b)); } - - template - inline const Value_t fp_absNot(const Value_t& b) - { return Value_t(!fp_absTruth(b)); } - - template - inline const Value_t fp_absNotNot(const Value_t& b) - { return Value_t(fp_absTruth(b)); } - - template - inline const Value_t fp_and(const Value_t& a, const Value_t& b) - { return Value_t(fp_truth(a) && fp_truth(b)); } - - template - inline const Value_t fp_or(const Value_t& a, const Value_t& b) - { return Value_t(fp_truth(a) || fp_truth(b)); } - - template - inline const Value_t fp_absAnd(const Value_t& a, const Value_t& b) - { return Value_t(fp_absTruth(a) && fp_absTruth(b)); } - - template - inline const Value_t fp_absOr(const Value_t& a, const Value_t& b) - { return Value_t(fp_absTruth(a) || fp_absTruth(b)); } - - template - inline const Value_t fp_make_imag(const Value_t& ) // Imaginary 1. In real mode, always zero. - { - return Value_t(); - } - - ///////////// - /* Opcode analysis functions are used by fp_opcode_add.inc */ - /* Moved here from fparser.cc because fp_opcode_add.inc - * is also now included by fpoptimizer.cc - */ - bool IsLogicalOpcode(unsigned op); - bool IsComparisonOpcode(unsigned op); - unsigned OppositeComparisonOpcode(unsigned op); - bool IsNeverNegativeValueOpcode(unsigned op); - bool IsAlwaysIntegerOpcode(unsigned op); - bool IsUnaryOpcode(unsigned op); - bool IsBinaryOpcode(unsigned op); - bool IsVarOpcode(unsigned op); - bool IsCommutativeOrParamSwappableBinaryOpcode(unsigned op); - unsigned GetParamSwappedBinaryOpcode(unsigned op); - - template - bool HasInvalidRangesOpcode(unsigned op); - - template - inline Value_t DegreesToRadians(const Value_t& degrees) - { - return degrees * fp_const_deg_to_rad(); - } - - template - inline Value_t RadiansToDegrees(const Value_t& radians) - { - return radians * fp_const_rad_to_deg(); - } - - template - inline long makeLongInteger(const Value_t& value) - { - return (long) fp_int(value); - } - -#ifdef FP_SUPPORT_COMPLEX_NUMBERS - template - inline long makeLongInteger(const std::complex& value) - { - return (long) fp_int( std::abs(value) ); - } -#endif - - // Is value an integer that fits in "long" datatype? - template - inline bool isLongInteger(const Value_t& value) - { - return value == Value_t( makeLongInteger(value) ); - } - - template - inline bool isOddInteger(const Value_t& value) - { - const Value_t halfValue = (value + Value_t(1)) * Value_t(0.5); - return fp_equal(halfValue, fp_floor(halfValue)); - } - - template - inline bool isEvenInteger(const Value_t& value) - { - const Value_t halfValue = value * Value_t(0.5); - return fp_equal(halfValue, fp_floor(halfValue)); - } - - template - inline bool isInteger(const Value_t& value) - { - return fp_equal(value, fp_floor(value)); - } - -#ifdef FP_SUPPORT_LONG_INT_TYPE - template<> - inline bool isEvenInteger(const long& value) - { - return value%2 == 0; - } - - template<> - inline bool isInteger(const long&) { return true; } - - template<> - inline bool isLongInteger(const long&) { return true; } - - template<> - inline long makeLongInteger(const long& value) - { - return value; - } -#endif - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE - template<> - inline bool isInteger(const MpfrFloat& value) { return value.isInteger(); } - - template<> - inline bool isEvenInteger(const MpfrFloat& value) - { - return isInteger(value) && value%2 == 0; - } - - template<> - inline long makeLongInteger(const MpfrFloat& value) - { - return (long) value.toInt(); - } -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE - template<> - inline bool isEvenInteger(const GmpInt& value) - { - return value%2 == 0; - } - - template<> - inline bool isInteger(const GmpInt&) { return true; } - - template<> - inline long makeLongInteger(const GmpInt& value) - { - return (long) value.toInt(); - } -#endif - -#ifdef FP_SUPPORT_LONG_INT_TYPE - template<> - inline bool isOddInteger(const long& value) - { - return value%2 != 0; - } -#endif - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE - template<> - inline bool isOddInteger(const MpfrFloat& value) - { - return value.isInteger() && value%2 != 0; - } -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE - template<> - inline bool isOddInteger(const GmpInt& value) - { - return value%2 != 0; - } -#endif - - -// ------------------------------------------------------------------------- -// fp_pow -// ------------------------------------------------------------------------- - // Commented versions in fparser.cc - template - inline Value_t fp_pow_with_exp_log(const Value_t& x, const Value_t& y) - { - return fp_exp(fp_log(x) * y); - } - - template - inline Value_t fp_powi(Value_t x, unsigned long y) - { - Value_t result(1); - while(y != 0) - { - if(y & 1) { result *= x; y -= 1; } - else { x *= x; y /= 2; } - } - return result; - } - - template - Value_t fp_pow(const Value_t& x, const Value_t& y) - { - if(x == Value_t(1)) return Value_t(1); - if(isLongInteger(y)) - { - if(y >= Value_t(0)) - return fp_powi(x, makeLongInteger(y)); - else - return Value_t(1) / fp_powi(x, -makeLongInteger(y)); - } - if(y >= Value_t(0)) - { - if(x > Value_t(0)) return fp_pow_with_exp_log(x, y); - if(x == Value_t(0)) return Value_t(0); - if(!isInteger(y*Value_t(16))) - return -fp_pow_with_exp_log(-x, y); - } - else - { - if(x > Value_t(0)) return fp_pow_with_exp_log(Value_t(1) / x, -y); - if(x < Value_t(0)) - { - if(!isInteger(y*Value_t(-16))) - return -fp_pow_with_exp_log(Value_t(-1) / x, -y); - } - } - return fp_pow_base(x, y); - } - - template - inline Value_t fp_exp2(const Value_t& x) - { - return fp_pow(Value_t(2), x); - } -} // namespace FUNCTIONPARSERTYPES - -#endif // ONCE_FPARSER_H_ -#endif // ONCE_FPARSER_AUX_H_ diff --git a/fparser/extrasrc/fptypes.hh b/fparser/extrasrc/fptypes.hh deleted file mode 100644 index 159903b..0000000 --- a/fparser/extrasrc/fptypes.hh +++ /dev/null @@ -1,288 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.5.1 *| -|*-------------------------------------------------------------------------*| -|* Copyright: Juha Nieminen, Joel Yliluoma *| -|* *| -|* This library is distributed under the terms of the *| -|* GNU Lesser General Public License version 3. *| -|* (See lgpl.txt and gpl.txt for the license text.) *| -\***************************************************************************/ - -// NOTE: -// This file contains only internal types for the function parser library. -// You don't need to include this file in your code. Include "fparser.hh" -// only. - -#ifndef ONCE_FPARSER_TYPES_H_ -#define ONCE_FPARSER_TYPES_H_ - -#include "../fpconfig.hh" -#include - -#ifdef ONCE_FPARSER_H_ -#include -#endif - -namespace FUNCTIONPARSERTYPES -{ - enum OPCODE - { -// The order of opcodes in the function list must -// match that which is in the Functions[] array. - cAbs, - cAcos, cAcosh, - cArg, /* get the phase angle of a complex value */ - cAsin, cAsinh, - cAtan, cAtan2, cAtanh, - cCbrt, cCeil, - cConj, /* get the complex conjugate of a complex value */ - cCos, cCosh, cCot, cCsc, - cExp, cExp2, cFloor, cHypot, - cIf, - cImag, /* get imaginary part of a complex value */ - cInt, cLog, cLog10, cLog2, cMax, cMin, - cPolar, /* create a complex number from polar coordinates */ - cPow, - cReal, /* get real part of a complex value */ - cSec, cSin, cSinh, cSqrt, cTan, cTanh, - cTrunc, - -// These do not need any ordering: -// Except that if you change the order of {eq,neq,lt,le,gt,ge}, you -// must also change the order in ConstantFolding_ComparisonOperations(). - cImmed, cJump, - cNeg, cAdd, cSub, cMul, cDiv, cMod, - cEqual, cNEqual, cLess, cLessOrEq, cGreater, cGreaterOrEq, - cNot, cAnd, cOr, - cNotNot, /* Protects the double-not sequence from optimizations */ - - cDeg, cRad, /* Multiplication and division by 180 / pi */ - - cFCall, cPCall, - -#ifdef FP_SUPPORT_OPTIMIZER - cPopNMov, /* cPopNMov(x,y) moves [y] to [x] and deletes anything - * above [x]. Used for disposing of temporaries. - */ - cLog2by, /* log2by(x,y) = log2(x) * y */ - cNop, /* Used by fpoptimizer internally; should not occur in bytecode */ -#endif - cSinCos, /* sin(x) followed by cos(x) (two values are pushed to stack) */ - cSinhCosh, /* hyperbolic equivalent of sincos */ - cAbsAnd, /* As cAnd, but assume both operands are absolute values */ - cAbsOr, /* As cOr, but assume both operands are absolute values */ - cAbsNot, /* As cAbsNot, but assume the operand is an absolute value */ - cAbsNotNot, /* As cAbsNotNot, but assume the operand is an absolute value */ - cAbsIf, /* As cAbsIf, but assume the 1st operand is an absolute value */ - - cDup, /* Duplicates the last value in the stack: Push [Stacktop] */ - cFetch, /* Same as Dup, except with absolute index - * (next value is index) */ - cInv, /* Inverts the last value in the stack (x = 1/x) */ - cSqr, /* squares the last operand in the stack, no push/pop */ - cRDiv, /* reverse division (not x/y, but y/x) */ - cRSub, /* reverse subtraction (not x-y, but y-x) */ - cRSqrt, /* inverse square-root (1/sqrt(x)) */ - - VarBegin - }; - -#ifdef ONCE_FPARSER_H_ - struct FuncDefinition - { - enum FunctionFlags - { - Enabled = 0x01, - AngleIn = 0x02, - AngleOut = 0x04, - OkForInt = 0x08, - ComplexOnly = 0x10 - }; - -#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING - const char name[8]; -#else - struct name { } name; -#endif - unsigned params : 8; - unsigned flags : 8; - - inline bool okForInt() const { return (flags & OkForInt) != 0; } - inline bool complexOnly() const { return (flags & ComplexOnly) != 0; } - }; - -#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING -# define FP_FNAME(n) n -#else -# define FP_FNAME(n) {} -#endif -// This list must be in the same order as that in OPCODE enum, -// because the opcode value is used to index this array, and -// the pointer to array element is used for generating the opcode. - const FuncDefinition Functions[]= - { - /*cAbs */ { FP_FNAME("abs"), 1, FuncDefinition::OkForInt }, - /*cAcos */ { FP_FNAME("acos"), 1, FuncDefinition::AngleOut }, - /*cAcosh*/ { FP_FNAME("acosh"), 1, FuncDefinition::AngleOut }, - /*cArg */ { FP_FNAME("arg"), 1, FuncDefinition::AngleOut | FuncDefinition::ComplexOnly }, - /*cAsin */ { FP_FNAME("asin"), 1, FuncDefinition::AngleOut }, - /*cAsinh*/ { FP_FNAME("asinh"), 1, FuncDefinition::AngleOut }, - /*cAtan */ { FP_FNAME("atan"), 1, FuncDefinition::AngleOut }, - /*cAtan2*/ { FP_FNAME("atan2"), 2, FuncDefinition::AngleOut }, - /*cAtanh*/ { FP_FNAME("atanh"), 1, 0 }, - /*cCbrt */ { FP_FNAME("cbrt"), 1, 0 }, - /*cCeil */ { FP_FNAME("ceil"), 1, 0 }, - /*cConj */ { FP_FNAME("conj"), 1, FuncDefinition::ComplexOnly }, - /*cCos */ { FP_FNAME("cos"), 1, FuncDefinition::AngleIn }, - /*cCosh */ { FP_FNAME("cosh"), 1, FuncDefinition::AngleIn }, - /*cCot */ { FP_FNAME("cot"), 1, FuncDefinition::AngleIn }, - /*cCsc */ { FP_FNAME("csc"), 1, FuncDefinition::AngleIn }, - /*cExp */ { FP_FNAME("exp"), 1, 0 }, - /*cExp2 */ { FP_FNAME("exp2"), 1, 0 }, - /*cFloor*/ { FP_FNAME("floor"), 1, 0 }, - /*cHypot*/ { FP_FNAME("hypot"), 2, 0 }, - /*cIf */ { FP_FNAME("if"), 0, FuncDefinition::OkForInt }, - /*cImag */ { FP_FNAME("imag"), 1, FuncDefinition::ComplexOnly }, - /*cInt */ { FP_FNAME("int"), 1, 0 }, - /*cLog */ { FP_FNAME("log"), 1, 0 }, - /*cLog10*/ { FP_FNAME("log10"), 1, 0 }, - /*cLog2 */ { FP_FNAME("log2"), 1, 0 }, - /*cMax */ { FP_FNAME("max"), 2, FuncDefinition::OkForInt }, - /*cMin */ { FP_FNAME("min"), 2, FuncDefinition::OkForInt }, - /*cPolar */{ FP_FNAME("polar"), 2, FuncDefinition::ComplexOnly | FuncDefinition::AngleIn }, - /*cPow */ { FP_FNAME("pow"), 2, 0 }, - /*cReal */ { FP_FNAME("real"), 1, FuncDefinition::ComplexOnly }, - /*cSec */ { FP_FNAME("sec"), 1, FuncDefinition::AngleIn }, - /*cSin */ { FP_FNAME("sin"), 1, FuncDefinition::AngleIn }, - /*cSinh */ { FP_FNAME("sinh"), 1, FuncDefinition::AngleIn }, - /*cSqrt */ { FP_FNAME("sqrt"), 1, 0 }, - /*cTan */ { FP_FNAME("tan"), 1, FuncDefinition::AngleIn }, - /*cTanh */ { FP_FNAME("tanh"), 1, FuncDefinition::AngleIn }, - /*cTrunc*/ { FP_FNAME("trunc"), 1, 0 } - }; -#undef FP_FNAME - - struct NamePtr - { - const char* name; - unsigned nameLength; - - NamePtr(const char* n, unsigned l): name(n), nameLength(l) {} - - inline bool operator==(const NamePtr& rhs) const - { - return nameLength == rhs.nameLength - && std::memcmp(name, rhs.name, nameLength) == 0; - } - inline bool operator<(const NamePtr& rhs) const - { - for(unsigned i = 0; i < nameLength; ++i) - { - if(i == rhs.nameLength) return false; - const char c1 = name[i], c2 = rhs.name[i]; - if(c1 < c2) return true; - if(c2 < c1) return false; - } - return nameLength < rhs.nameLength; - } - }; - - template - struct NameData - { - enum DataType { CONSTANT, UNIT, FUNC_PTR, PARSER_PTR, VARIABLE }; - DataType type; - unsigned index; - Value_t value; - - NameData(DataType t, unsigned v) : type(t), index(v), value() { } - NameData(DataType t, Value_t v) : type(t), index(), value(v) { } - NameData() { } - }; - - template - class NamePtrsMap: public - std::map > - { - }; - - const unsigned FUNC_AMOUNT = sizeof(Functions)/sizeof(Functions[0]); -#endif // ONCE_FPARSER_H_ -} - -#ifdef ONCE_FPARSER_H_ -#include - -template -struct FunctionParserBase::Data -{ - unsigned mReferenceCounter; - - char mDelimiterChar; - ParseErrorType mParseErrorType; - int mEvalErrorType; - bool mUseDegreeConversion; - bool mHasByteCodeFlags; - const char* mErrorLocation; - - unsigned mVariablesAmount; - std::string mVariablesString; - FUNCTIONPARSERTYPES::NamePtrsMap mNamePtrs; - - struct InlineVariable - { - FUNCTIONPARSERTYPES::NamePtr mName; - unsigned mFetchIndex; - }; - - typedef std::vector InlineVarNamesContainer; - InlineVarNamesContainer mInlineVarNames; - - struct FuncWrapperPtrData - { - /* Only one of the pointers will point to a function, the other - will be null. (The raw function pointer could be implemented - as a FunctionWrapper specialization, but it's done like this - for efficiency.) */ - FunctionPtr mRawFuncPtr; - FunctionWrapper* mFuncWrapperPtr; - unsigned mParams; - - FuncWrapperPtrData(); - ~FuncWrapperPtrData(); - FuncWrapperPtrData(const FuncWrapperPtrData&); - FuncWrapperPtrData& operator=(const FuncWrapperPtrData&); - }; - - struct FuncParserPtrData - { - FunctionParserBase* mParserPtr; - unsigned mParams; - }; - - std::vector mFuncPtrs; - std::vector mFuncParsers; - - std::vector mByteCode; - std::vector mImmed; - -#if !defined(FP_USE_THREAD_SAFE_EVAL) && \ - !defined(FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA) - std::vector mStack; - // Note: When mStack exists, - // mStack.size() and mStackSize are mutually redundant. -#endif - - unsigned mStackSize; - - Data(); - Data(const Data&); - Data& operator=(const Data&); // not implemented on purpose - ~Data(); -}; -#endif - -//#include "fpaux.hh" - -#endif diff --git a/fparser/fparser.cc b/fparser/fparser.cc deleted file mode 100644 index 11fa09e..0000000 --- a/fparser/fparser.cc +++ /dev/null @@ -1,3800 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.5.1 *| -|*-------------------------------------------------------------------------*| -|* Copyright: Juha Nieminen, Joel Yliluoma *| -|* *| -|* This library is distributed under the terms of the *| -|* GNU Lesser General Public License version 3. *| -|* (See lgpl.txt and gpl.txt for the license text.) *| -\***************************************************************************/ - -#include "fpconfig.hh" -#include "fparser.hh" - -#include -#include -#include -#include -#include -#include -#include - -#include "extrasrc/fptypes.hh" -#include "extrasrc/fpaux.hh" -using namespace FUNCTIONPARSERTYPES; - -#ifdef FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA -#ifndef FP_USE_THREAD_SAFE_EVAL -#define FP_USE_THREAD_SAFE_EVAL -#endif -#endif - -#ifdef __GNUC__ -# define likely(x) __builtin_expect(!!(x), 1) -# define unlikely(x) __builtin_expect(!!(x), 0) -#else -# define likely(x) (x) -# define unlikely(x) (x) -#endif - -//========================================================================= -// Opcode analysis functions -//========================================================================= -// These functions are used by the Parse() bytecode optimizer (mostly from -// code in fp_opcode_add.inc). - -bool FUNCTIONPARSERTYPES::IsLogicalOpcode(unsigned op) -{ - switch(op) - { - case cAnd: case cAbsAnd: - case cOr: case cAbsOr: - case cNot: case cAbsNot: - case cNotNot: case cAbsNotNot: - case cEqual: case cNEqual: - case cLess: case cLessOrEq: - case cGreater: case cGreaterOrEq: - return true; - default: break; - } - return false; -} - -bool FUNCTIONPARSERTYPES::IsComparisonOpcode(unsigned op) -{ - switch(op) - { - case cEqual: case cNEqual: - case cLess: case cLessOrEq: - case cGreater: case cGreaterOrEq: - return true; - default: break; - } - return false; -} - -unsigned FUNCTIONPARSERTYPES::OppositeComparisonOpcode(unsigned op) -{ - switch(op) - { - case cLess: return cGreater; - case cGreater: return cLess; - case cLessOrEq: return cGreaterOrEq; - case cGreaterOrEq: return cLessOrEq; - } - return op; -} - -bool FUNCTIONPARSERTYPES::IsNeverNegativeValueOpcode(unsigned op) -{ - switch(op) - { - case cAnd: case cAbsAnd: - case cOr: case cAbsOr: - case cNot: case cAbsNot: - case cNotNot: case cAbsNotNot: - case cEqual: case cNEqual: - case cLess: case cLessOrEq: - case cGreater: case cGreaterOrEq: - case cSqrt: case cRSqrt: case cSqr: - case cHypot: - case cAbs: - case cAcos: case cCosh: - return true; - default: break; - } - return false; -} - -bool FUNCTIONPARSERTYPES::IsAlwaysIntegerOpcode(unsigned op) -{ - switch(op) - { - case cAnd: case cAbsAnd: - case cOr: case cAbsOr: - case cNot: case cAbsNot: - case cNotNot: case cAbsNotNot: - case cEqual: case cNEqual: - case cLess: case cLessOrEq: - case cGreater: case cGreaterOrEq: - case cInt: case cFloor: case cCeil: case cTrunc: - return true; - default: break; - } - return false; -} - -bool FUNCTIONPARSERTYPES::IsUnaryOpcode(unsigned op) -{ - switch(op) - { - case cInv: case cNeg: - case cNot: case cAbsNot: - case cNotNot: case cAbsNotNot: - case cSqr: case cRSqrt: - case cDeg: case cRad: - return true; - } - return (op < FUNC_AMOUNT && Functions[op].params == 1); -} - -bool FUNCTIONPARSERTYPES::IsBinaryOpcode(unsigned op) -{ - switch(op) - { - case cAdd: case cSub: case cRSub: - case cMul: case cDiv: case cRDiv: - case cMod: - case cEqual: case cNEqual: case cLess: - case cLessOrEq: case cGreater: case cGreaterOrEq: - case cAnd: case cAbsAnd: - case cOr: case cAbsOr: - return true; - } - return (op < FUNC_AMOUNT && Functions[op].params == 2); -} - -bool FUNCTIONPARSERTYPES::IsVarOpcode(unsigned op) -{ - // See comment in declaration of FP_ParamGuardMask - return int(op) >= VarBegin; -} - -bool FUNCTIONPARSERTYPES::IsCommutativeOrParamSwappableBinaryOpcode(unsigned op) -{ - switch(op) - { - case cAdd: - case cMul: - case cEqual: case cNEqual: - case cAnd: case cAbsAnd: - case cOr: case cAbsOr: - case cMin: case cMax: case cHypot: - return true; - case cDiv: case cSub: case cRDiv: case cRSub: - return true; - case cLess: case cGreater: - case cLessOrEq: case cGreaterOrEq: return true; - } - return false; -} - -unsigned FUNCTIONPARSERTYPES::GetParamSwappedBinaryOpcode(unsigned op) -{ - switch(op) - { - case cAdd: - case cMul: - case cEqual: case cNEqual: - case cAnd: case cAbsAnd: - case cOr: case cAbsOr: - case cMin: case cMax: case cHypot: - return op; - case cDiv: return cRDiv; - case cSub: return cRSub; - case cRDiv: return cDiv; - case cRSub: return cSub; - case cLess: return cGreater; - case cGreater: return cLess; - case cLessOrEq: return cGreaterOrEq; - case cGreaterOrEq: return cLessOrEq; - } - return op; // Error -} - -template -bool FUNCTIONPARSERTYPES::HasInvalidRangesOpcode(unsigned op) -{ - // Returns true, if the given opcode has a range of - // input values that gives an error. - if(ComplexType) - { - // COMPLEX: - switch(op) - { - case cAtan: // allowed range: x != +-1i - case cAtanh: // allowed range: x != +-1 - //case cCot: // allowed range: tan(x) != 0 - //case cCsc: // allowed range: sin(x) != 0 - case cLog: // allowed range: x != 0 - case cLog2: // allowed range: x != 0 - case cLog10: // allowed range: x != 0 - #ifdef FP_SUPPORT_OPTIMIZER - case cLog2by:// allowed range: x != 0 - #endif - //case cPow: // allowed when: x != 0 or y != 0 - //case cSec: // allowed range: cos(x) != 0 - //case cTan: // allowed range: cos(x) != 0 --> x != +-(pi/2) - //case cTanh: // allowed range: log(x) != -1 --> x != +-(pi/2)i - case cRSqrt: // allowed range: x != 0 - //case cDiv: // allowed range: y != 0 - //case cRDiv: // allowed range: x != 0 - //case cInv: // allowed range: x != 0 - return true; - } - } - else - { - // REAL: - switch(op) - { - case cAcos: // allowed range: |x| <= 1 - case cAsin: // allowed range: |x| <= 1 - case cAcosh: // allowed range: x >= 1 - case cAtanh: // allowed range: |x| < 1 - //case cCot: // allowed range: tan(x) != 0 - //case cCsc: // allowed range: sin(x) != 0 - case cLog: // allowed range: x > 0 - case cLog2: // allowed range: x > 0 - case cLog10: // allowed range: x > 0 - #ifdef FP_SUPPORT_OPTIMIZER - case cLog2by:// allowed range: x > 0 - #endif - //case cPow: // allowed when: x > 0 or (x = 0 and y != 0) or (x<0) - // Technically, when (x<0 and y is not integer), - // it is not allowed, but we allow it anyway - // in order to make nontrivial roots work. - //case cSec: // allowed range: cos(x) != 0 - case cSqrt: // allowed range: x >= 0 - case cRSqrt: // allowed range: x > 0 - //case cTan: // allowed range: cos(x) != 0 --> x != +-(pi/2) - //case cDiv: // allowed range: y != 0 - //case cRDiv: // allowed range: x != 0 - //case cInv: // allowed range: x != 0 - return true; - } - } - return false; -} - -template bool FUNCTIONPARSERTYPES::HasInvalidRangesOpcode(unsigned op); -template bool FUNCTIONPARSERTYPES::HasInvalidRangesOpcode(unsigned op); - - -#if(0) // Implementation moved to fpaux.hh due to linker problems -//========================================================================= -// Mathematical template functions -//========================================================================= -/* fp_pow() is a wrapper for std::pow() - * that produces an identical value for - * exp(1) ^ 2.0 (0x4000000000000000) - * as exp(2.0) (0x4000000000000000) - * - std::pow() on x86_64 - * produces 2.0 (0x3FFFFFFFFFFFFFFF) instead! - * See comments below for other special traits. - */ -namespace -{ - template - inline ValueT fp_pow_with_exp_log(const ValueT& x, const ValueT& y) - { - // Exponentiation using exp(log(x)*y). - // See http://en.wikipedia.org/wiki/Exponentiation#Real_powers - // Requirements: x > 0. - return fp_exp(fp_log(x) * y); - } - - template - inline ValueT fp_powi(ValueT x, unsigned long y) - { - // Fast binary exponentiation algorithm - // See http://en.wikipedia.org/wiki/Exponentiation_by_squaring - // Requirements: y is non-negative integer. - ValueT result(1); - while(y != 0) - { - if(y & 1) { result *= x; y -= 1; } - else { x *= x; y /= 2; } - } - return result; - } -} - -template -ValueT FUNCTIONPARSERTYPES::fp_pow(const ValueT& x, const ValueT& y) -{ - if(x == ValueT(1)) return ValueT(1); - // y is now zero or positive - if(isLongInteger(y)) - { - // Use fast binary exponentiation algorithm - if(y >= ValueT(0)) - return fp_powi(x, makeLongInteger(y)); - else - return ValueT(1) / fp_powi(x, -makeLongInteger(y)); - } - if(y >= ValueT(0)) - { - // y is now positive. Calculate using exp(log(x)*y). - if(x > ValueT(0)) return fp_pow_with_exp_log(x, y); - if(x == ValueT(0)) return ValueT(0); - // At this point, y > 0.0 and x is known to be < 0.0, - // because positive and zero cases are already handled. - if(!isInteger(y*ValueT(16))) - return -fp_pow_with_exp_log(-x, y); - // ^This is not technically correct, but it allows - // functions such as cbrt(x^5), that is, x^(5/3), - // to be evaluated when x is negative. - // It is too complicated (and slow) to test whether y - // is a formed from a ratio of an integer to an odd integer. - // (And due to floating point inaccuracy, pointless too.) - // For example, x^1.30769230769... is - // actually x^(17/13), i.e. (x^17) ^ (1/13). - // (-5)^(17/13) gives us now -8.204227562330453. - // To see whether the result is right, we can test the given - // root: (-8.204227562330453)^13 gives us the value of (-5)^17, - // which proves that the expression was correct. - // - // The y*16 check prevents e.g. (-4)^(3/2) from being calculated, - // as it would confuse functioninfo when pow() returns no error - // but sqrt() does when the formula is converted into sqrt(x)*x. - // - // The errors in this approach are: - // (-2)^sqrt(2) should produce NaN - // or actually sqrt(2)I + 2^sqrt(2), - // produces -(2^sqrt(2)) instead. - // (Impact: Neglible) - // Thus, at worst, we're changing a NaN (or complex) - // result into a negative real number result. - } - else - { - // y is negative. Utilize the x^y = 1/(x^-y) identity. - if(x > ValueT(0)) return fp_pow_with_exp_log(ValueT(1) / x, -y); - if(x < ValueT(0)) - { - if(!isInteger(y*ValueT(-16))) - return -fp_pow_with_exp_log(ValueT(-1) / x, -y); - // ^ See comment above. - } - // Remaining case: 0.0 ^ negative number - } - // This is reached when: - // x=0, and y<0 - // x<0, and y*16 is either positive or negative integer - // It is used for producing error values and as a safe fallback. - return fp_pow_base(x, y); -} -#endif - - -//========================================================================= -// Elementary (atom) parsing functions -//========================================================================= -namespace -{ - const unsigned FP_ParamGuardMask = 1U << (sizeof(unsigned) * 8u - 1u); - // ^ This mask is used to prevent cFetch/other opcode's parameters - // from being confused into opcodes or variable indices within the - // bytecode optimizer. Because the way it is tested in bytecoderules.dat - // for speed reasons, it must also be the sign-bit of the "int" datatype. - // Perhaps an "assert(IsVarOpcode(X | FP_ParamGuardMask) == false)" - // might be justified to put somewhere in the code, just in case? - - - /* Reads an UTF8-encoded sequence which forms a valid identifier name from - the given input string and returns its length. If bit 31 is set, the - return value also contains the internal function opcode (defined in - fptypes.hh) that matches the name. - */ - unsigned readIdentifierCommon(const char* input) - { - /* Assuming unsigned = 32 bits: - 76543210 76543210 76543210 76543210 - Return value if built-in function: - 1PPPPPPP PPPPPPPP LLLLLLLL LLLLLLLL - P = function opcode (15 bits) - L = function name length (16 bits) - Return value if not built-in function: - 0LLLLLLL LLLLLLLL LLLLLLLL LLLLLLLL - L = identifier length (31 bits) - If unsigned has more than 32 bits, the other - higher order bits are to be assumed zero. - */ -#include "extrasrc/fp_identifier_parser.inc" - return 0; - } - - template - inline unsigned readIdentifier(const char* input) - { - const unsigned value = readIdentifierCommon(input); - if( (value & 0x80000000U) != 0) // Function? - { - // Verify that the function actually exists for this datatype - if(IsIntType::result - && !Functions[(value >> 16) & 0x7FFF].okForInt()) - { - // If it does not exist, return it as an identifier instead - return value & 0xFFFFu; - } - if(!IsComplexType::result - && Functions[(value >> 16) & 0x7FFF].complexOnly()) - { - // If it does not exist, return it as an identifier instead - return value & 0xFFFFu; - } - } - return value; - } - - // Returns true if the entire string is a valid identifier - template - bool containsOnlyValidIdentifierChars(const std::string& name) - { - if(name.empty()) return false; - return readIdentifier(name.c_str()) == (unsigned) name.size(); - } - - - // ----------------------------------------------------------------------- - // Wrappers for strto... functions - // ----------------------------------------------------------------------- - template - inline Value_t fp_parseLiteral(const char* str, char** endptr) - { - return std::strtod(str, endptr); - } - -#if defined(FP_USE_STRTOLD) || defined(FP_SUPPORT_CPLUSPLUS11_MATH_FUNCS) - template<> - inline long double fp_parseLiteral(const char* str, - char** endptr) - { - using namespace std; // Just in case strtold() is not inside std:: - return strtold(str, endptr); - } -#endif - -#ifdef FP_SUPPORT_LONG_INT_TYPE - template<> - inline long fp_parseLiteral(const char* str, char** endptr) - { - return std::strtol(str, endptr, 10); - } -#endif - -#ifdef FP_SUPPORT_COMPLEX_NUMBERS - template - inline std::complex fp_parseComplexLiteral(const char* str, - char** endptr) - { - T result = fp_parseLiteral (str,endptr); - const char* end = *endptr; - if( (*end == 'i' || *end == 'I') - && !std::isalnum(end[1]) ) - { - ++*endptr; - return std::complex (T(), result); - } - return std::complex (result, T()); - } -#endif - -#ifdef FP_SUPPORT_COMPLEX_DOUBLE_TYPE - template<> - inline std::complex fp_parseLiteral > - (const char* str, char** endptr) - { - return fp_parseComplexLiteral (str,endptr); - } -#endif - -#ifdef FP_SUPPORT_COMPLEX_FLOAT_TYPE - template<> - inline std::complex fp_parseLiteral > - (const char* str, char** endptr) - { - return fp_parseComplexLiteral (str,endptr); - } -#endif - -#ifdef FP_SUPPORT_COMPLEX_LONG_DOUBLE_TYPE - template<> - inline std::complex fp_parseLiteral > - (const char* str, char** endptr) - { - return fp_parseComplexLiteral (str,endptr); - } -#endif - - // ----------------------------------------------------------------------- - // Hexadecimal floating point literal parsing - // ----------------------------------------------------------------------- - inline int testXdigit(unsigned c) - { - if((c-'0') < 10u) return c&15; // 0..9 - if(((c|0x20)-'a') < 6u) return 9+(c&15); // A..F or a..f - return -1; // Not a hex digit - } - - template - inline void addXdigit(elem_t* buffer, unsigned nibble) - { - for(unsigned p=0; p> (elem_t)(limb_bits-4) ); - buffer[p] = (buffer[p] << 4) | nibble; - nibble = carry; - } - } - - template - Value_t parseHexLiteral(const char* str, char** endptr) - { - const unsigned bits_per_char = 8; - - const int MantissaBits = - std::numeric_limits::radix == 2 - ? std::numeric_limits::digits - : (((sizeof(Value_t) * bits_per_char) &~ 3) - 4); - - typedef unsigned long elem_t; - const int ExtraMantissaBits = 4 + ((MantissaBits+3)&~3); // Store one digit more for correct rounding - const unsigned limb_bits = sizeof(elem_t) * bits_per_char; - const unsigned n_limbs = (ExtraMantissaBits + limb_bits-1) / limb_bits; - elem_t mantissa_buffer[n_limbs] = { 0 }; - - int n_mantissa_bits = 0; // Track the number of bits - int exponent = 0; // The exponent that will be used to multiply the mantissa - // Read integer portion - while(true) - { - int xdigit = testXdigit(*str); - if(xdigit < 0) break; - addXdigit (mantissa_buffer, xdigit); - ++str; - - n_mantissa_bits += 4; - if(n_mantissa_bits >= ExtraMantissaBits) - { - // Exhausted the precision. Parse the rest (until exponent) - // normally but ignore the actual digits. - for(; testXdigit(*str) >= 0; ++str) - exponent += 4; - // Read but ignore decimals - if(*str == '.') - for(++str; testXdigit(*str) >= 0; ++str) - {} - goto read_exponent; - } - } - // Read decimals - if(*str == '.') - for(++str; ; ) - { - int xdigit = testXdigit(*str); - if(xdigit < 0) break; - addXdigit (mantissa_buffer, xdigit); - ++str; - - exponent -= 4; - n_mantissa_bits += 4; - if(n_mantissa_bits >= ExtraMantissaBits) - { - // Exhausted the precision. Skip the rest - // of the decimals, until the exponent. - while(testXdigit(*str) >= 0) - ++str; - break; - } - } - - // Read exponent - read_exponent: - if(*str == 'p' || *str == 'P') - { - const char* str2 = str+1; - long p_exponent = strtol(str2, const_cast (&str2), 10); - if(str2 != str+1 && p_exponent == (long)(int)p_exponent) - { - exponent += (int)p_exponent; - str = str2; - } - } - - if(endptr) *endptr = const_cast (str); - - Value_t result = std::ldexp(Value_t(mantissa_buffer[0]), exponent); - for(unsigned p=1; p - long parseHexLiteral(const char* str, char** endptr) - { - return std::strtol(str, endptr, 16); - } -#endif - -#ifdef FP_SUPPORT_COMPLEX_DOUBLE_TYPE - template<> - std::complex - parseHexLiteral >(const char* str, char** endptr) - { - return parseHexLiteral (str, endptr); - } -#endif - -#ifdef FP_SUPPORT_COMPLEX_FLOAT_TYPE - template<> - std::complex - parseHexLiteral >(const char* str, char** endptr) - { - return parseHexLiteral (str, endptr); - } -#endif - -#ifdef FP_SUPPORT_COMPLEX_LONG_DOUBLE_TYPE - template<> - std::complex - parseHexLiteral >(const char* str, char** endptr) - { - return parseHexLiteral (str, endptr); - } -#endif -} - -//========================================================================= -// Utility functions -//========================================================================= -namespace -{ - // ----------------------------------------------------------------------- - // Add a new identifier to the specified identifier map - // ----------------------------------------------------------------------- - // Return value will be false if the name already existed - template - bool addNewNameData(NamePtrsMap& namePtrs, - std::pair >& newName, - bool isVar) - { - typename NamePtrsMap::iterator nameIter = - namePtrs.lower_bound(newName.first); - - if(nameIter != namePtrs.end() && newName.first == nameIter->first) - { - // redefining a var is not allowed. - if(isVar) return false; - - // redefining other tokens is allowed, if the type stays the same. - if(nameIter->second.type != newName.second.type) - return false; - - // update the data - nameIter->second = newName.second; - return true; - } - - if(!isVar) - { - // Allocate a copy of the name (pointer stored in the map key) - // However, for VARIABLEs, the pointer points to VariableString, - // which is managed separately. Thusly, only done when !IsVar. - char* namebuf = new char[newName.first.nameLength]; - memcpy(namebuf, newName.first.name, newName.first.nameLength); - newName.first.name = namebuf; - } - - namePtrs.insert(nameIter, newName); - return true; - } -} - - -//========================================================================= -// Data struct implementation -//========================================================================= -template -FunctionParserBase::Data::Data(): - mReferenceCounter(1), - mDelimiterChar(0), - mParseErrorType(NO_FUNCTION_PARSED_YET), - mEvalErrorType(0), - mUseDegreeConversion(false), - mErrorLocation(0), - mVariablesAmount(0), - mStackSize(0) -{} - -template -FunctionParserBase::Data::Data(const Data& rhs): - mReferenceCounter(0), - mDelimiterChar(rhs.mDelimiterChar), - mParseErrorType(rhs.mParseErrorType), - mEvalErrorType(rhs.mEvalErrorType), - mUseDegreeConversion(rhs.mUseDegreeConversion), - mErrorLocation(rhs.mErrorLocation), - mVariablesAmount(rhs.mVariablesAmount), - mVariablesString(rhs.mVariablesString), - mNamePtrs(), - mFuncPtrs(rhs.mFuncPtrs), - mFuncParsers(rhs.mFuncParsers), - mByteCode(rhs.mByteCode), - mImmed(rhs.mImmed), -#ifndef FP_USE_THREAD_SAFE_EVAL - mStack(rhs.mStackSize), -#endif - mStackSize(rhs.mStackSize) -{ - for(typename NamePtrsMap::const_iterator i = rhs.mNamePtrs.begin(); - i != rhs.mNamePtrs.end(); - ++i) - { - if(i->second.type == NameData::VARIABLE) - { - const std::size_t variableStringOffset = - i->first.name - rhs.mVariablesString.c_str(); - std::pair > tmp - (NamePtr(&mVariablesString[variableStringOffset], - i->first.nameLength), - i->second); - mNamePtrs.insert(mNamePtrs.end(), tmp); - } - else - { - std::pair > tmp - (NamePtr(new char[i->first.nameLength], i->first.nameLength), - i->second ); - memcpy(const_cast(tmp.first.name), i->first.name, - tmp.first.nameLength); - mNamePtrs.insert(mNamePtrs.end(), tmp); - } - } -} - -template -FunctionParserBase::Data::~Data() -{ - for(typename NamePtrsMap::iterator i = mNamePtrs.begin(); - i != mNamePtrs.end(); - ++i) - { - if(i->second.type != NameData::VARIABLE) - delete[] i->first.name; - } -} - -template -void FunctionParserBase::incFuncWrapperRefCount -(FunctionWrapper* wrapper) -{ - ++wrapper->mReferenceCount; -} - -template -unsigned FunctionParserBase::decFuncWrapperRefCount -(FunctionWrapper* wrapper) -{ - return --wrapper->mReferenceCount; -} - -template -FunctionParserBase::Data::FuncWrapperPtrData::FuncWrapperPtrData(): - mRawFuncPtr(0), mFuncWrapperPtr(0), mParams(0) -{} - -template -FunctionParserBase::Data::FuncWrapperPtrData::~FuncWrapperPtrData() -{ - if(mFuncWrapperPtr && - FunctionParserBase::decFuncWrapperRefCount(mFuncWrapperPtr) == 0) - delete mFuncWrapperPtr; -} - -template -FunctionParserBase::Data::FuncWrapperPtrData::FuncWrapperPtrData -(const FuncWrapperPtrData& rhs): - mRawFuncPtr(rhs.mRawFuncPtr), - mFuncWrapperPtr(rhs.mFuncWrapperPtr), - mParams(rhs.mParams) -{ - if(mFuncWrapperPtr) - FunctionParserBase::incFuncWrapperRefCount(mFuncWrapperPtr); -} - -template -typename FunctionParserBase::Data::FuncWrapperPtrData& -FunctionParserBase::Data::FuncWrapperPtrData::operator= -(const FuncWrapperPtrData& rhs) -{ - if(&rhs != this) - { - if(mFuncWrapperPtr && - FunctionParserBase::decFuncWrapperRefCount(mFuncWrapperPtr) == 0) - delete mFuncWrapperPtr; - mRawFuncPtr = rhs.mRawFuncPtr; - mFuncWrapperPtr = rhs.mFuncWrapperPtr; - mParams = rhs.mParams; - if(mFuncWrapperPtr) - FunctionParserBase::incFuncWrapperRefCount(mFuncWrapperPtr); - } - return *this; -} - - -//========================================================================= -// FunctionParser constructors, destructor and assignment -//========================================================================= -template -FunctionParserBase::FunctionParserBase(): - mData(new Data), - mStackPtr(0) -{ -} - -template -FunctionParserBase::~FunctionParserBase() -{ - if(--(mData->mReferenceCounter) == 0) - delete mData; -} - -template -FunctionParserBase::FunctionParserBase(const FunctionParserBase& cpy): - mData(cpy.mData), - mStackPtr(0) -{ - ++(mData->mReferenceCounter); -} - -template -FunctionParserBase& -FunctionParserBase::operator=(const FunctionParserBase& cpy) -{ - if(mData != cpy.mData) - { - if(--(mData->mReferenceCounter) == 0) delete mData; - - mData = cpy.mData; - ++(mData->mReferenceCounter); - } - return *this; -} - -template -typename FunctionParserBase::Data* -FunctionParserBase::getParserData() -{ - return mData; -} - -template -void FunctionParserBase::setDelimiterChar(char c) -{ - mData->mDelimiterChar = c; -} - - -//--------------------------------------------------------------------------- -// Copy-on-write method -//--------------------------------------------------------------------------- -template -void FunctionParserBase::CopyOnWrite() -{ - if(mData->mReferenceCounter > 1) - { - Data* oldData = mData; - mData = new Data(*oldData); - --(oldData->mReferenceCounter); - mData->mReferenceCounter = 1; - } -} - -template -void FunctionParserBase::ForceDeepCopy() -{ - CopyOnWrite(); -} - - -//========================================================================= -// Epsilon -//========================================================================= -template -Value_t FunctionParserBase::epsilon() -{ - return Epsilon::value; -} - -template -void FunctionParserBase::setEpsilon(Value_t value) -{ - Epsilon::value = value; -} - - -//========================================================================= -// User-defined identifier addition functions -//========================================================================= -template -bool FunctionParserBase::AddConstant(const std::string& name, - Value_t value) -{ - if(!containsOnlyValidIdentifierChars(name)) return false; - - CopyOnWrite(); - std::pair > newName - (NamePtr(name.data(), unsigned(name.size())), - NameData(NameData::CONSTANT, value)); - - return addNewNameData(mData->mNamePtrs, newName, false); -} - -template -bool FunctionParserBase::AddUnit(const std::string& name, - Value_t value) -{ - if(!containsOnlyValidIdentifierChars(name)) return false; - - CopyOnWrite(); - std::pair > newName - (NamePtr(name.data(), unsigned(name.size())), - NameData(NameData::UNIT, value)); - return addNewNameData(mData->mNamePtrs, newName, false); -} - -template -bool FunctionParserBase::AddFunction -(const std::string& name, FunctionPtr ptr, unsigned paramsAmount) -{ - if(!containsOnlyValidIdentifierChars(name)) return false; - - CopyOnWrite(); - std::pair > newName - (NamePtr(name.data(), unsigned(name.size())), - NameData(NameData::FUNC_PTR, - unsigned(mData->mFuncPtrs.size()))); - - const bool success = addNewNameData(mData->mNamePtrs, newName, false); - if(success) - { - mData->mFuncPtrs.push_back(typename Data::FuncWrapperPtrData()); - mData->mFuncPtrs.back().mRawFuncPtr = ptr; - mData->mFuncPtrs.back().mParams = paramsAmount; - } - return success; -} - -template -bool FunctionParserBase::addFunctionWrapperPtr -(const std::string& name, FunctionWrapper* wrapper, unsigned paramsAmount) -{ - if(!AddFunction(name, FunctionPtr(0), paramsAmount)) return false; - mData->mFuncPtrs.back().mFuncWrapperPtr = wrapper; - return true; -} - -template -typename FunctionParserBase::FunctionWrapper* -FunctionParserBase::GetFunctionWrapper(const std::string& name) -{ - CopyOnWrite(); - NamePtr namePtr(name.data(), unsigned(name.size())); - - typename NamePtrsMap::iterator nameIter = - mData->mNamePtrs.find(namePtr); - - if(nameIter != mData->mNamePtrs.end() && - nameIter->second.type == NameData::FUNC_PTR) - { - return mData->mFuncPtrs[nameIter->second.index].mFuncWrapperPtr; - } - return 0; -} - -template -bool FunctionParserBase::CheckRecursiveLinking -(const FunctionParserBase* fp) const -{ - if(fp == this) return true; - for(unsigned i = 0; i < fp->mData->mFuncParsers.size(); ++i) - if(CheckRecursiveLinking(fp->mData->mFuncParsers[i].mParserPtr)) - return true; - return false; -} - -template -bool FunctionParserBase::AddFunction(const std::string& name, - FunctionParserBase& fp) -{ - if(!containsOnlyValidIdentifierChars(name) || - CheckRecursiveLinking(&fp)) - return false; - - CopyOnWrite(); - std::pair > newName - (NamePtr(name.data(), unsigned(name.size())), - NameData(NameData::PARSER_PTR, - unsigned(mData->mFuncParsers.size()))); - - const bool success = addNewNameData(mData->mNamePtrs, newName, false); - if(success) - { - mData->mFuncParsers.push_back(typename Data::FuncParserPtrData()); - mData->mFuncParsers.back().mParserPtr = &fp; - mData->mFuncParsers.back().mParams = fp.mData->mVariablesAmount; - } - return success; -} - -template -bool FunctionParserBase::RemoveIdentifier(const std::string& name) -{ - CopyOnWrite(); - - NamePtr namePtr(name.data(), unsigned(name.size())); - - typename NamePtrsMap::iterator nameIter = - mData->mNamePtrs.find(namePtr); - - if(nameIter != mData->mNamePtrs.end()) - { - if(nameIter->second.type == NameData::VARIABLE) - { - // Illegal attempt to delete variables - return false; - } - delete[] nameIter->first.name; - mData->mNamePtrs.erase(nameIter); - return true; - } - return false; -} - - -//========================================================================= -// Function parsing -//========================================================================= -namespace -{ - // Error messages returned by ErrorMsg(): - const char* const ParseErrorMessage[]= - { - "Syntax error", // 0 - "Mismatched parenthesis", // 1 - "Missing ')'", // 2 - "Empty parentheses", // 3 - "Syntax error: Operator expected", // 4 - "Not enough memory", // 5 - "An unexpected error occurred. Please make a full bug report " - "to the author", // 6 - "Syntax error in parameter 'Vars' given to " - "FunctionParser::Parse()", // 7 - "Illegal number of parameters to function", // 8 - "Syntax error: Premature end of string", // 9 - "Syntax error: Expecting ( after function", // 10 - "Syntax error: Unknown identifier", // 11 - "(No function has been parsed yet)", - "" - }; - - template - inline typename FunctionParserBase::ParseErrorType - noCommaError(char c) - { - return c == ')' ? - FunctionParserBase::ILL_PARAMS_AMOUNT : - FunctionParserBase::SYNTAX_ERROR; - } - - template - inline typename FunctionParserBase::ParseErrorType - noParenthError(char c) - { - return c == ',' ? - FunctionParserBase::ILL_PARAMS_AMOUNT : - FunctionParserBase::MISSING_PARENTH; - } - - template - struct IntLiteralMask - { - enum { mask = - // ( 1UL << ('-'-offset)) | - (0x3FFUL << ('0'-offset)) }; /* 0x3FF = 10 bits worth "1" */ - // Note: If you change fparser to support negative numbers parsing - // (as opposed to parsing them as cNeg followed by literal), - // enable the '-' line above, and change the offset value - // in BeginsLiteral() to '-' instead of '.'. - }; - - template - struct LiteralMask - { - enum { mask = - ( 1UL << ('.'-offset)) | - IntLiteralMask::mask }; - }; -#ifdef FP_SUPPORT_LONG_INT_TYPE - template - struct LiteralMask: public IntLiteralMask - { - }; -#endif -#ifdef FP_SUPPORT_GMP_INT_TYPE - template - struct LiteralMask: public IntLiteralMask - { - }; -#endif - - template - struct SimpleSpaceMask - { - enum { mask = - (1UL << ('\r'-offset)) | - (1UL << ('\n'-offset)) | - (1UL << ('\v'-offset)) | - (1UL << ('\t'-offset)) | - (1UL << (' ' -offset)) }; - }; - - template - inline bool BeginsLiteral(unsigned byte) - { - enum { n = sizeof(unsigned long)>=8 ? 0 : '.' }; - byte -= n; - if(byte > (unsigned char)('9'-n)) return false; - unsigned long shifted = 1UL << byte; - const unsigned long mask = LiteralMask::mask; - return (mask & shifted) != 0; - } - - template - inline void SkipSpace(CharPtr& function) - { -/* - Space characters in unicode: -U+0020 SPACE Depends on font, often adjusted (see below) -U+00A0 NO-BREAK SPACE As a space, but often not adjusted -U+2000 EN QUAD 1 en (= 1/2 em) -U+2001 EM QUAD 1 em (nominally, the height of the font) -U+2002 EN SPACE 1 en (= 1/2 em) -U+2003 EM SPACE 1 em -U+2004 THREE-PER-EM SPACE 1/3 em -U+2005 FOUR-PER-EM SPACE 1/4 em -U+2006 SIX-PER-EM SPACE 1/6 em -U+2007 FIGURE SPACE Tabular width, the width of digits -U+2008 PUNCTUATION SPACE The width of a period . -U+2009 THIN SPACE 1/5 em (or sometimes 1/6 em) -U+200A HAIR SPACE Narrower than THIN SPACE -U+200B ZERO WIDTH SPACE Nominally no width, but may expand -U+202F NARROW NO-BREAK SPACE Narrower than NO-BREAK SPACE (or SPACE) -U+205F MEDIUM MATHEMATICAL SPACE 4/18 em -U+3000 IDEOGRAPHIC SPACE The width of ideographic (CJK) characters. - Also: -U+000A \n -U+000D \r -U+0009 \t -U+000B \v - As UTF-8 sequences: - 09 - 0A - 0B - 0D - 20 - C2 A0 - E2 80 80-8B - E2 80 AF - E2 81 9F - E3 80 80 -*/ - while(true) - { - enum { n = sizeof(unsigned long)>=8 ? 0 : '\t' }; - typedef signed char schar; - unsigned byte = (unsigned char)*function; - byte -= n; - // ^Note: values smaller than n intentionally become - // big values here due to integer wrap. The - // comparison below thus excludes them, making - // the effective range 0x09..0x20 (32-bit) - // or 0x00..0x20 (64-bit) within the if-clause. - if(byte <= (unsigned char)(' '-n)) - { - unsigned long shifted = 1UL << byte; - const unsigned long mask = SimpleSpaceMask::mask; - if(mask & shifted) - { ++function; continue; } // \r, \n, \t, \v and space - break; - } - if(likely(byte < 0xC2-n)) break; - - if(byte == 0xC2-n && function[1] == char(0xA0)) - { function += 2; continue; } // U+00A0 - if(byte == 0xE3-n && - function[1] == char(0x80) && function[2] == char(0x80)) - { function += 3; continue; } // U+3000 - if(byte == 0xE2-n) - { - if(function[1] == char(0x81)) - { - if(function[2] != char(0x9F)) break; - function += 3; // U+205F - continue; - } - if(function[1] == char(0x80)) - if(function[2] == char(0xAF) || // U+202F - schar(function[2]) <= schar(0x8B) // U+2000..U+200B - ) - { - function += 3; - continue; - } - } - break; - } // while(true) - } // SkipSpace(CharPtr& function) -} - -// --------------------------------------------------------------------------- -// Return parse error message -// --------------------------------------------------------------------------- -template -const char* FunctionParserBase::ErrorMsg() const -{ - return ParseErrorMessage[mData->mParseErrorType]; -} - -template -typename FunctionParserBase::ParseErrorType -FunctionParserBase::GetParseErrorType() const -{ - return mData->mParseErrorType; -} - -template -int FunctionParserBase::EvalError() const -{ - return mData->mEvalErrorType; -} - - -// --------------------------------------------------------------------------- -// Parse variables -// --------------------------------------------------------------------------- -template -bool FunctionParserBase::ParseVariables -(const std::string& inputVarString) -{ - if(mData->mVariablesString == inputVarString) return true; - - /* Delete existing variables from mNamePtrs */ - for(typename NamePtrsMap::iterator i = - mData->mNamePtrs.begin(); - i != mData->mNamePtrs.end(); ) - { - if(i->second.type == NameData::VARIABLE) - { - typename NamePtrsMap::iterator j (i); - ++i; - mData->mNamePtrs.erase(j); - } - else ++i; - } - mData->mVariablesString = inputVarString; - - const std::string& vars = mData->mVariablesString; - const unsigned len = unsigned(vars.size()); - - unsigned varNumber = VarBegin; - - const char* beginPtr = vars.c_str(); - const char* finalPtr = beginPtr + len; - while(beginPtr < finalPtr) - { - SkipSpace(beginPtr); - unsigned nameLength = readIdentifier(beginPtr); - if(nameLength == 0 || (nameLength & 0x80000000U)) return false; - const char* endPtr = beginPtr + nameLength; - SkipSpace(endPtr); - if(endPtr != finalPtr && *endPtr != ',') return false; - - std::pair > newName - (NamePtr(beginPtr, nameLength), - NameData(NameData::VARIABLE, varNumber++)); - - if(!addNewNameData(mData->mNamePtrs, newName, true)) - { - return false; - } - - beginPtr = endPtr + 1; - } - - mData->mVariablesAmount = varNumber - VarBegin; - return true; -} - -// --------------------------------------------------------------------------- -// Parse() public interface functions -// --------------------------------------------------------------------------- -template -int FunctionParserBase::Parse(const char* Function, - const std::string& Vars, - bool useDegrees) -{ - CopyOnWrite(); - - if(!ParseVariables(Vars)) - { - mData->mParseErrorType = INVALID_VARS; - return int(strlen(Function)); - } - - return ParseFunction(Function, useDegrees); -} - -template -int FunctionParserBase::Parse(const std::string& Function, - const std::string& Vars, - bool useDegrees) -{ - CopyOnWrite(); - - if(!ParseVariables(Vars)) - { - mData->mParseErrorType = INVALID_VARS; - return int(Function.size()); - } - - return ParseFunction(Function.c_str(), useDegrees); -} - - -// --------------------------------------------------------------------------- -// Main parsing function -// --------------------------------------------------------------------------- -template -int FunctionParserBase::ParseFunction(const char* function, - bool useDegrees) -{ - mData->mUseDegreeConversion = useDegrees; - mData->mParseErrorType = FP_NO_ERROR; - - mData->mInlineVarNames.clear(); - mData->mByteCode.clear(); mData->mByteCode.reserve(128); - mData->mImmed.clear(); mData->mImmed.reserve(128); - mData->mStackSize = mStackPtr = 0; - - mData->mHasByteCodeFlags = false; - - const char* ptr = Compile(function); - mData->mInlineVarNames.clear(); - - if(mData->mHasByteCodeFlags) - { - for(unsigned i = unsigned(mData->mByteCode.size()); i-- > 0; ) - mData->mByteCode[i] &= ~FP_ParamGuardMask; - } - - if(mData->mParseErrorType != FP_NO_ERROR) - return int(mData->mErrorLocation - function); - - assert(ptr); // Should never be null at this point. It's a bug otherwise. - if(*ptr) - { - if(mData->mDelimiterChar == 0 || *ptr != mData->mDelimiterChar) - mData->mParseErrorType = EXPECT_OPERATOR; - return int(ptr - function); - } - -#ifndef FP_USE_THREAD_SAFE_EVAL - mData->mStack.resize(mData->mStackSize); -#endif - - return -1; -} - - -//========================================================================= -// Parsing and bytecode compiling functions -//========================================================================= -template -inline const char* FunctionParserBase::SetErrorType(ParseErrorType t, - const char* pos) -{ - mData->mParseErrorType = t; - mData->mErrorLocation = pos; - return 0; -} - -template -inline void FunctionParserBase::incStackPtr() -{ - if(++mStackPtr > mData->mStackSize) ++(mData->mStackSize); -} - -namespace -{ - const unsigned char powi_factor_table[128] = - { - 0,1,0,0,0,0,0,0, 0, 0,0,0,0,0,0,3,/* 0 - 15 */ - 0,0,0,0,0,0,0,0, 0, 5,0,3,0,0,3,0,/* 16 - 31 */ - 0,0,0,0,0,0,0,3, 0, 0,0,0,0,5,0,0,/* 32 - 47 */ - 0,0,5,3,0,0,3,5, 0, 3,0,0,3,0,0,3,/* 48 - 63 */ - 0,0,0,0,0,0,0,0, 0, 0,0,3,0,0,3,0,/* 64 - 79 */ - 0,9,0,0,0,5,0,3, 0, 0,5,7,0,0,0,5,/* 80 - 95 */ - 0,0,0,3,5,0,3,0, 0, 3,0,0,3,0,5,3,/* 96 - 111 */ - 0,0,3,5,0,9,0,7, 3,11,0,3,0,5,3,0,/* 112 - 127 */ - }; - - inline int get_powi_factor(long abs_int_exponent) - { - if(abs_int_exponent >= int(sizeof(powi_factor_table))) return 0; - return powi_factor_table[abs_int_exponent]; - } - -#if 0 - int EstimatePowiComplexity(int abs_int_exponent) - { - int cost = 0; - while(abs_int_exponent > 1) - { - int factor = get_powi_factor(abs_int_exponent); - if(factor) - { - cost += EstimatePowiComplexity(factor); - abs_int_exponent /= factor; - continue; - } - if(!(abs_int_exponent & 1)) - { - abs_int_exponent /= 2; - cost += 3; // sqr - } - else - { - cost += 4; // dup+mul - abs_int_exponent -= 1; - } - } - return cost; - } -#endif - - bool IsEligibleIntPowiExponent(long int_exponent) - { - if(int_exponent == 0) return false; - long abs_int_exponent = int_exponent; - #if 0 - int cost = 0; - - if(abs_int_exponent < 0) - { - cost += 11; - abs_int_exponent = -abs_int_exponent; - } - - cost += EstimatePowiComplexity(abs_int_exponent); - - return cost < (10*3 + 4*4); - #else - if(abs_int_exponent < 0) abs_int_exponent = -abs_int_exponent; - - return (abs_int_exponent >= 1) - && (abs_int_exponent <= 46 || - (abs_int_exponent <= 1024 && - (abs_int_exponent & (abs_int_exponent - 1)) == 0)); - #endif - } - - /* Needed by fp_opcode_add.inc if tracing is enabled */ - template - std::string findName(const NamePtrsMap& nameMap, - unsigned index, - typename NameData::DataType type) - { - for(typename NamePtrsMap::const_iterator - iter = nameMap.begin(); - iter != nameMap.end(); - ++iter) - { - if(iter->second.type == type && iter->second.index == index) - return std::string(iter->first.name, - iter->first.name + iter->first.nameLength); - } - return "?"; - } -} - -template -inline void FunctionParserBase::AddImmedOpcode(Value_t value) -{ - mData->mImmed.push_back(value); - mData->mByteCode.push_back(cImmed); -} - -template -inline void FunctionParserBase::CompilePowi(long abs_int_exponent) -{ - int num_muls=0; - while(abs_int_exponent > 1) - { - long factor = get_powi_factor(abs_int_exponent); - if(factor) - { - CompilePowi(factor); - abs_int_exponent /= factor; - continue; - } - if(!(abs_int_exponent & 1)) - { - abs_int_exponent /= 2; - mData->mByteCode.push_back(cSqr); - // ^ Don't put AddFunctionOpcode here, - // it would slow down a great deal. - } - else - { - mData->mByteCode.push_back(cDup); - incStackPtr(); - abs_int_exponent -= 1; - ++num_muls; - } - } - if(num_muls > 0) - { - mData->mByteCode.resize(mData->mByteCode.size()+num_muls, cMul); - mStackPtr -= num_muls; - } -} - -template -inline bool FunctionParserBase::TryCompilePowi(Value_t original_immed) -{ - Value_t changed_immed = original_immed; - for(int sqrt_count=0; /**/; ++sqrt_count) - { - long int_exponent = makeLongInteger(changed_immed); - if(isLongInteger(changed_immed) && - IsEligibleIntPowiExponent(int_exponent)) - { - long abs_int_exponent = int_exponent; - if(abs_int_exponent < 0) - abs_int_exponent = -abs_int_exponent; - - mData->mImmed.pop_back(); mData->mByteCode.pop_back(); - --mStackPtr; - // ^Though the above is accounted for by the procedure - // that generates cPow, we need it for correct cFetch - // indexes in CompilePowi(). - - while(sqrt_count > 0) - { - int opcode = cSqrt; - if(sqrt_count == 1 && int_exponent < 0) - { - opcode = cRSqrt; - int_exponent = -int_exponent; - } - mData->mByteCode.push_back(opcode); - --sqrt_count; - } - if((abs_int_exponent & 1) == 0) - { - // This special rule fixes the optimization - // shortcoming of (-x)^2 with minimal overhead. - AddFunctionOpcode(cSqr); - abs_int_exponent >>= 1; - } - CompilePowi(abs_int_exponent); - if(int_exponent < 0) mData->mByteCode.push_back(cInv); - ++mStackPtr; // Needed because cPow adding will assume this. - return true; - } - if(sqrt_count >= 4) break; - changed_immed += changed_immed; - } - - // When we don't know whether x >= 0, we still know that - // x^y can be safely converted into exp(y * log(x)) - // when y is _not_ integer, because we know that x >= 0. - // Otherwise either expression will give a NaN. - if(/*!isInteger(original_immed) ||*/ - IsNeverNegativeValueOpcode(mData->mByteCode[mData->mByteCode.size()-2])) - { - mData->mImmed.pop_back(); - mData->mByteCode.pop_back(); - //--mStackPtr; - accounted for by the procedure that generates cPow - AddFunctionOpcode(cLog); - AddImmedOpcode(original_immed); - //incStackPtr(); - this and the next are redundant because... - AddFunctionOpcode(cMul); - //--mStackPtr; - ...because the cImmed was popped earlier. - AddFunctionOpcode(cExp); - return true; - } - return false; -} - -//#include "fpoptimizer/opcodename.hh" -// ^ needed only if FP_TRACE_BYTECODE_OPTIMIZATION() is used - -template -inline void FunctionParserBase::AddFunctionOpcode(unsigned opcode) -{ -#define FP_FLOAT_VERSION 1 -#define FP_COMPLEX_VERSION 0 -#include "extrasrc/fp_opcode_add.inc" -#undef FP_COMPLEX_VERSION -#undef FP_FLOAT_VERSION -} - -#ifdef FP_SUPPORT_LONG_INT_TYPE -template<> -inline void FunctionParserBase::AddFunctionOpcode(unsigned opcode) -{ - typedef long Value_t; -#define FP_FLOAT_VERSION 0 -#define FP_COMPLEX_VERSION 0 -#include "extrasrc/fp_opcode_add.inc" -#undef FP_COMPLEX_VERSION -#undef FP_FLOAT_VERSION -} -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE -template<> -inline void FunctionParserBase::AddFunctionOpcode(unsigned opcode) -{ - typedef GmpInt Value_t; -#define FP_FLOAT_VERSION 0 -#define FP_COMPLEX_VERSION 0 -#include "extrasrc/fp_opcode_add.inc" -#undef FP_COMPLEX_VERSION -#undef FP_FLOAT_VERSION -} -#endif - -#ifdef FP_SUPPORT_COMPLEX_DOUBLE_TYPE -template<> -inline void FunctionParserBase >::AddFunctionOpcode(unsigned opcode) -{ - typedef std::complex Value_t; -#define FP_FLOAT_VERSION 1 -#define FP_COMPLEX_VERSION 1 -#include "extrasrc/fp_opcode_add.inc" -#undef FP_COMPLEX_VERSION -#undef FP_FLOAT_VERSION -} -#endif - -#ifdef FP_SUPPORT_COMPLEX_FLOAT_TYPE -template<> -inline void FunctionParserBase >::AddFunctionOpcode(unsigned opcode) -{ - typedef std::complex Value_t; -#define FP_FLOAT_VERSION 1 -#define FP_COMPLEX_VERSION 1 -#include "extrasrc/fp_opcode_add.inc" -#undef FP_COMPLEX_VERSION -#undef FP_FLOAT_VERSION -} -#endif - -#ifdef FP_SUPPORT_COMPLEX_LONG_DOUBLE_TYPE -template<> -inline void FunctionParserBase >::AddFunctionOpcode(unsigned opcode) -{ - typedef std::complex Value_t; -#define FP_FLOAT_VERSION 1 -#define FP_COMPLEX_VERSION 1 -#include "extrasrc/fp_opcode_add.inc" -#undef FP_COMPLEX_VERSION -#undef FP_FLOAT_VERSION -} -#endif - -template -unsigned -FunctionParserBase::ParseIdentifier(const char* function) -{ - return readIdentifier(function); -} - -template -std::pair -FunctionParserBase::ParseLiteral(const char* function) -{ - char* endptr; -#if 0 /* Profile the hex literal parser */ - if(function[0]=='0' && function[1]=='x') - { - // Parse hexadecimal literal if fp_parseLiteral didn't already - Value_t val = parseHexLiteral(function+2, &endptr); - if(endptr == function+2) - return std::pair (function, Value_t()); - return std::pair (endptr, val); - } -#endif - Value_t val = fp_parseLiteral(function, &endptr); - - if(endptr == function+1 && function[0] == '0' && function[1] == 'x') - { - // Parse hexadecimal literal if fp_parseLiteral didn't already - val = parseHexLiteral(function+2, &endptr); - if(endptr == function+2) - return std::pair (function, Value_t()); - } - else if(endptr == function) - return std::pair (function, Value_t()); - - return std::pair (endptr, val); -} - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE -template<> -std::pair -FunctionParserBase::ParseLiteral(const char* function) -{ - char* endPtr; - const MpfrFloat val = MpfrFloat::parseString(function, &endPtr); - if(endPtr == function) - return std::pair (function, MpfrFloat()); - return std::pair (endPtr, val); -} -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE -template<> -std::pair -FunctionParserBase::ParseLiteral(const char* function) -{ - char* endPtr; - const GmpInt val = GmpInt::parseString(function, &endPtr); - if(endPtr == function) - return std::pair (function, GmpInt()); - return std::pair (endPtr, val); -} -#endif - - -template -inline const char* -FunctionParserBase::CompileLiteral(const char* function) -{ - std::pair result = ParseLiteral(function); - - if(result.first == function) - return SetErrorType(SYNTAX_ERROR, result.first); - - AddImmedOpcode(result.second); - incStackPtr(); - SkipSpace(result.first); - return result.first; -} - -template -const char* FunctionParserBase::CompileIf(const char* function) -{ - if(*function != '(') return SetErrorType(EXPECT_PARENTH_FUNC, function); - - function = CompileExpression(function+1); - if(!function) return 0; - if(*function != ',') - return SetErrorType(noCommaError(*function), function); - - OPCODE opcode = cIf; - if(mData->mByteCode.back() == cNotNot) mData->mByteCode.pop_back(); - if(IsNeverNegativeValueOpcode(mData->mByteCode.back())) - { - // If we know that the condition to be tested is always - // a positive value (such as when produced by "x= 0.5, - // cAbsIf simply tests whether cond >= 0.5. - opcode = cAbsIf; - } - - mData->mByteCode.push_back(opcode); - const unsigned curByteCodeSize = unsigned(mData->mByteCode.size()); - PushOpcodeParam(0); // Jump index; to be set later - PushOpcodeParam (0); // Immed jump index; to be set later - - --mStackPtr; - - function = CompileExpression(function + 1); - if(!function) return 0; - if(*function != ',') - return SetErrorType(noCommaError(*function), function); - - mData->mByteCode.push_back(cJump); - const unsigned curByteCodeSize2 = unsigned(mData->mByteCode.size()); - const unsigned curImmedSize2 = unsigned(mData->mImmed.size()); - PushOpcodeParam(0); // Jump index; to be set later - PushOpcodeParam (0); // Immed jump index; to be set later - - --mStackPtr; - - function = CompileExpression(function + 1); - if(!function) return 0; - if(*function != ')') - return SetErrorType(noParenthError(*function), function); - - PutOpcodeParamAt ( mData->mByteCode.back(), unsigned(mData->mByteCode.size()-1) ); - // ^Necessary for guarding against if(x,1,2)+1 being changed - // into if(x,1,3) by fp_opcode_add.inc - - // Set jump indices - PutOpcodeParamAt( curByteCodeSize2+1, curByteCodeSize ); - PutOpcodeParamAt( curImmedSize2, curByteCodeSize+1 ); - PutOpcodeParamAt( unsigned(mData->mByteCode.size())-1, curByteCodeSize2); - PutOpcodeParamAt( unsigned(mData->mImmed.size()), curByteCodeSize2+1); - - ++function; - SkipSpace(function); - return function; -} - -template -const char* FunctionParserBase::CompileFunctionParams -(const char* function, unsigned requiredParams) -{ - if(*function != '(') return SetErrorType(EXPECT_PARENTH_FUNC, function); - - if(requiredParams > 0) - { - const char* function_end = CompileExpression(function+1); - if(!function_end) - { - // If an error occurred, verify whether it was caused by () - ++function; - SkipSpace(function); - if(*function == ')') - return SetErrorType(ILL_PARAMS_AMOUNT, function); - // Not caused by (), use the error message given by CompileExpression() - return 0; - } - function = function_end; - - for(unsigned i = 1; i < requiredParams; ++i) - { - if(*function != ',') - return SetErrorType(noCommaError(*function), function); - - function = CompileExpression(function+1); - if(!function) return 0; - } - // No need for incStackPtr() because each parse parameter calls it - mStackPtr -= requiredParams-1; - } - else - { - incStackPtr(); // return value of function is pushed onto the stack - ++function; - SkipSpace(function); - } - - if(*function != ')') - return SetErrorType(noParenthError(*function), function); - ++function; - SkipSpace(function); - return function; -} - -template -const char* FunctionParserBase::CompileElement(const char* function) -{ - if(BeginsLiteral( (unsigned char) *function)) - return CompileLiteral(function); - - unsigned nameLength = readIdentifier(function); - if(nameLength == 0) - { - // No identifier found - if(*function == '(') return CompileParenthesis(function); - if(*function == ')') return SetErrorType(MISM_PARENTH, function); - return SetErrorType(SYNTAX_ERROR, function); - } - - // Function, variable or constant - if(nameLength & 0x80000000U) // Function - { - OPCODE func_opcode = OPCODE( (nameLength >> 16) & 0x7FFF ); - return CompileFunction(function + (nameLength & 0xFFFF), func_opcode); - } - - NamePtr name(function, nameLength); - const char* endPtr = function + nameLength; - SkipSpace(endPtr); - - typename NamePtrsMap::iterator nameIter = - mData->mNamePtrs.find(name); - if(nameIter == mData->mNamePtrs.end()) - { - // Check if it's an inline variable: - for(typename Data::InlineVarNamesContainer::reverse_iterator iter = - mData->mInlineVarNames.rbegin(); - iter != mData->mInlineVarNames.rend(); - ++iter) - { - if(name == iter->mName) - { - if( iter->mFetchIndex+1 == mStackPtr) - { - mData->mByteCode.push_back(cDup); - } - else - { - mData->mByteCode.push_back(cFetch); - PushOpcodeParam(iter->mFetchIndex); - } - incStackPtr(); - return endPtr; - } - } - - return SetErrorType(UNKNOWN_IDENTIFIER, function); - } - - const NameData* nameData = &nameIter->second; - switch(nameData->type) - { - case NameData::VARIABLE: // is variable - if(unlikely(!mData->mByteCode.empty() && - mData->mByteCode.back() == nameData->index)) - mData->mByteCode.push_back(cDup); - else - mData->mByteCode.push_back(nameData->index); - incStackPtr(); - return endPtr; - - case NameData::CONSTANT: // is constant - AddImmedOpcode(nameData->value); - incStackPtr(); - return endPtr; - - case NameData::UNIT: // is unit (error if appears here) - break; - - case NameData::FUNC_PTR: // is C++ function - function = CompileFunctionParams - (endPtr, mData->mFuncPtrs[nameData->index].mParams); - //if(!function) return 0; - mData->mByteCode.push_back(cFCall); - PushOpcodeParam(nameData->index); - return function; - - case NameData::PARSER_PTR: // is FunctionParser - function = CompileFunctionParams - (endPtr, mData->mFuncParsers[nameData->index].mParams); - //if(!function) return 0; - mData->mByteCode.push_back(cPCall); - PushOpcodeParam(nameData->index); - return function; - } - - // When it's an unit (or unrecognized type): - return SetErrorType(SYNTAX_ERROR, function); -} - -template -inline const char* FunctionParserBase::CompileFunction -(const char* function, unsigned func_opcode) -{ - SkipSpace(function); - const FuncDefinition& funcDef = Functions[func_opcode]; - - if(func_opcode == cIf) // "if" is a special case - return CompileIf(function); - - unsigned requiredParams = funcDef.params; - - function = CompileFunctionParams(function, requiredParams); - if(!function) return 0; - - if(mData->mUseDegreeConversion) - { - if(funcDef.flags & FuncDefinition::AngleIn) - AddFunctionOpcode(cRad); - - AddFunctionOpcode(func_opcode); - - if(funcDef.flags & FuncDefinition::AngleOut) - AddFunctionOpcode(cDeg); - } - else - { - AddFunctionOpcode(func_opcode); - } - return function; -} - -template -inline const char* -FunctionParserBase::CompileParenthesis(const char* function) -{ - ++function; // Skip '(' - - SkipSpace(function); - if(*function == ')') return SetErrorType(EMPTY_PARENTH, function); - function = CompileExpression(function); - if(!function) return 0; - - if(*function != ')') return SetErrorType(MISSING_PARENTH, function); - ++function; // Skip ')' - - SkipSpace(function); - return function; -} - -template -const char* -FunctionParserBase::CompilePossibleUnit(const char* function) -{ - unsigned nameLength = readIdentifier(function); - if(nameLength & 0x80000000U) return function; // built-in function name - if(nameLength != 0) - { - NamePtr name(function, nameLength); - - typename NamePtrsMap::iterator nameIter = - mData->mNamePtrs.find(name); - if(nameIter != mData->mNamePtrs.end()) - { - const NameData* nameData = &nameIter->second; - if(nameData->type == NameData::UNIT) - { - AddImmedOpcode(nameData->value); - incStackPtr(); - AddFunctionOpcode(cMul); - --mStackPtr; - - const char* endPtr = function + nameLength; - SkipSpace(endPtr); - return endPtr; - } - } - } - - return function; -} - -template -inline const char* -FunctionParserBase::CompilePow(const char* function) -{ - function = CompileElement(function); - if(!function) return 0; - function = CompilePossibleUnit(function); - - if(*function == '^') - { - ++function; - SkipSpace(function); - - unsigned op = cPow; - if(mData->mByteCode.back() == cImmed) - { - if(mData->mImmed.back() == fp_const_e()) - { op = cExp; mData->mByteCode.pop_back(); - mData->mImmed.pop_back(); --mStackPtr; } - else if(mData->mImmed.back() == Value_t(2)) - { op = cExp2; mData->mByteCode.pop_back(); - mData->mImmed.pop_back(); --mStackPtr; } - } - - function = CompileUnaryMinus(function); - if(!function) return 0; - - // add opcode - AddFunctionOpcode(op); - - if(op == cPow) --mStackPtr; - } - return function; -} - -/* Currently the power operator is skipped for integral types because its - usefulness with them is questionable, and in the case of GmpInt, for safety - reasons: - - With long int almost any power, except for very small ones, would - overflow the result, so the usefulness of this is rather questionable. - - With GmpInt the power operator could be easily abused to make the program - run out of memory (think of a function like "10^10^10^10^1000000"). -*/ -#ifdef FP_SUPPORT_LONG_INT_TYPE -template<> -inline const char* -FunctionParserBase::CompilePow(const char* function) -{ - function = CompileElement(function); - if(!function) return 0; - return CompilePossibleUnit(function); -} -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE -template<> -inline const char* -FunctionParserBase::CompilePow(const char* function) -{ - function = CompileElement(function); - if(!function) return 0; - return CompilePossibleUnit(function); -} -#endif - -template -inline const char* -FunctionParserBase::CompileUnaryMinus(const char* function) -{ - char op = *function; - switch(op) - { - case '-': - case '!': - ++function; - SkipSpace(function); - - function = CompileUnaryMinus(function); - if(!function) return 0; - - AddFunctionOpcode(op=='-' ? cNeg : cNot); - - return function; - default: break; - } - return CompilePow(function); -} - -template -inline const char* -FunctionParserBase::CompileMult(const char* function) -{ - function = CompileUnaryMinus(function); - if(!function) return 0; - - Value_t pending_immed(1); - #define FP_FlushImmed(do_reset) \ - if(pending_immed != Value_t(1)) \ - { \ - unsigned op = cMul; \ - if(!IsIntType::result && mData->mByteCode.back() == cInv) \ - { \ - /* (...) cInv 5 cMul -> (...) 5 cRDiv */ \ - /* ^ ^ | */ \ - mData->mByteCode.pop_back(); \ - op = cRDiv; \ - } \ - AddImmedOpcode(pending_immed); \ - incStackPtr(); \ - AddFunctionOpcode(op); \ - --mStackPtr; \ - if(do_reset) pending_immed = Value_t(1); \ - } - while(true) - { - char c = *function; - if(c == '%') - { - FP_FlushImmed(true); - ++function; - SkipSpace(function); - function = CompileUnaryMinus(function); - if(!function) return 0; - AddFunctionOpcode(cMod); - --mStackPtr; - continue; - } - if(c != '*' && c != '/') break; - - bool safe_cumulation = (c == '*' || !IsIntType::result); - if(!safe_cumulation) - { - FP_FlushImmed(true); - } - - ++function; - SkipSpace(function); - if(mData->mByteCode.back() == cImmed - && (safe_cumulation - || mData->mImmed.back() == Value_t(1))) - { - // 5 (...) cMul --> (...) ||| 5 cMul - // 5 (...) cDiv --> (...) cInv ||| 5 cMul - // ^ | ^ - pending_immed *= mData->mImmed.back(); - mData->mImmed.pop_back(); - mData->mByteCode.pop_back(); - --mStackPtr; - function = CompileUnaryMinus(function); - if(!function) return 0; - if(c == '/') - AddFunctionOpcode(cInv); - continue; - } - if(safe_cumulation - && mData->mByteCode.back() == cMul - && mData->mByteCode[mData->mByteCode.size()-2] == cImmed) - { - // (:::) 5 cMul (...) cMul -> (:::) (...) cMul ||| 5 cMul - // (:::) 5 cMul (...) cDiv -> (:::) (...) cDiv ||| 5 cMul - // ^ ^ - pending_immed *= mData->mImmed.back(); - mData->mImmed.pop_back(); - mData->mByteCode.pop_back(); - mData->mByteCode.pop_back(); - } - // cDiv is not tested here because the bytecode - // optimizer will convert this kind of cDivs into cMuls. - bool lhs_inverted = false; - if(!IsIntType::result && c == '*' - && mData->mByteCode.back() == cInv) - { - // (:::) cInv (...) cMul -> (:::) (...) cRDiv - // (:::) cInv (...) cDiv -> (:::) (...) cMul cInv - // ^ ^ | - mData->mByteCode.pop_back(); - lhs_inverted = true; - } - function = CompileUnaryMinus(function); - if(!function) return 0; - if(safe_cumulation - && mData->mByteCode.back() == cMul - && mData->mByteCode[mData->mByteCode.size()-2] == cImmed) - { - // (:::) (...) 5 cMul cMul -> (:::) (...) cMul ||| 5 Mul - // (:::) (...) 5 cMul cDiv -> (:::) (...) cDiv ||| /5 Mul - // ^ ^ - if(c == '*') - pending_immed *= mData->mImmed.back(); - else - pending_immed /= mData->mImmed.back(); - mData->mImmed.pop_back(); - mData->mByteCode.pop_back(); - mData->mByteCode.pop_back(); - } - else - if(safe_cumulation - && mData->mByteCode.back() == cRDiv - && mData->mByteCode[mData->mByteCode.size()-2] == cImmed) - { - // (:::) (...) 5 cRDiv cMul -> (:::) (...) cDiv ||| 5 cMul - // (:::) (...) 5 cRDiv cDiv -> (:::) (...) cMul ||| /5 cMul - // ^ ^ - if(c == '*') - { c = '/'; pending_immed *= mData->mImmed.back(); } - else - { c = '*'; pending_immed /= mData->mImmed.back(); } - mData->mImmed.pop_back(); - mData->mByteCode.pop_back(); - mData->mByteCode.pop_back(); - } - if(!lhs_inverted) // if (/x/y) was changed to /(x*y), add missing cInv - { - AddFunctionOpcode(c == '*' ? cMul : cDiv); - --mStackPtr; - } - else if(c == '*') // (/x)*y -> rdiv(x,y) - { - AddFunctionOpcode(cRDiv); - --mStackPtr; - } - else // (/x)/y -> /(x*y) - { - AddFunctionOpcode(cMul); - --mStackPtr; - AddFunctionOpcode(cInv); - } - } - FP_FlushImmed(false); - #undef FP_FlushImmed - return function; -} - -template -inline const char* -FunctionParserBase::CompileAddition(const char* function) -{ - function = CompileMult(function); - if(!function) return 0; - - Value_t pending_immed(0); - #define FP_FlushImmed(do_reset) \ - if(pending_immed != Value_t(0)) \ - { \ - unsigned op = cAdd; \ - if(mData->mByteCode.back() == cNeg) \ - { \ - /* (...) cNeg 5 cAdd -> (...) 5 cRSub */ \ - /* ^ ^ | */ \ - mData->mByteCode.pop_back(); \ - op = cRSub; \ - } \ - AddImmedOpcode(pending_immed); \ - incStackPtr(); \ - AddFunctionOpcode(op); \ - --mStackPtr; \ - if(do_reset) pending_immed = Value_t(0); \ - } - while(true) - { - char c = *function; - if(c != '+' && c != '-') break; - ++function; - SkipSpace(function); - if(mData->mByteCode.back() == cImmed) - { - // 5 (...) cAdd --> (...) ||| 5 cAdd - // 5 (...) cSub --> (...) cNeg ||| 5 cAdd - // ^ | ^ - pending_immed += mData->mImmed.back(); - mData->mImmed.pop_back(); - mData->mByteCode.pop_back(); - --mStackPtr; - function = CompileMult(function); - if(!function) return 0; - if(c == '-') - AddFunctionOpcode(cNeg); - continue; - } - if(mData->mByteCode.back() == cAdd - && mData->mByteCode[mData->mByteCode.size()-2] == cImmed) - { - // (:::) 5 cAdd (...) cAdd -> (:::) (...) cAdd ||| 5 cAdd - // (:::) 5 cAdd (...) cSub -> (:::) (...) cSub ||| 5 cAdd - // ^ ^ - pending_immed += mData->mImmed.back(); - mData->mImmed.pop_back(); - mData->mByteCode.pop_back(); - mData->mByteCode.pop_back(); - } - // cSub is not tested here because the bytecode - // optimizer will convert this kind of cSubs into cAdds. - bool lhs_negated = false; - if(mData->mByteCode.back() == cNeg) - { - // (:::) cNeg (...) cAdd -> (:::) (...) cRSub - // (:::) cNeg (...) cSub -> (:::) (...) cAdd cNeg - // ^ ^ | - mData->mByteCode.pop_back(); - lhs_negated = true; - } - function = CompileMult(function); - if(!function) return 0; - if(mData->mByteCode.back() == cAdd - && mData->mByteCode[mData->mByteCode.size()-2] == cImmed) - { - // (:::) (...) 5 cAdd cAdd -> (:::) (...) cAdd ||| 5 Add - // (:::) (...) 5 cAdd cSub -> (:::) (...) cSub ||| -5 Add - // ^ ^ - if(c == '+') - pending_immed += mData->mImmed.back(); - else - pending_immed -= mData->mImmed.back(); - mData->mImmed.pop_back(); - mData->mByteCode.pop_back(); - mData->mByteCode.pop_back(); - } - else - if(mData->mByteCode.back() == cRSub - && mData->mByteCode[mData->mByteCode.size()-2] == cImmed) - { - // (:::) (...) 5 cRSub cAdd -> (:::) (...) cSub ||| 5 cAdd - // (:::) (...) 5 cRSub cSub -> (:::) (...) cAdd ||| -5 cAdd - // ^ ^ - if(c == '+') - { c = '-'; pending_immed += mData->mImmed.back(); } - else - { c = '+'; pending_immed -= mData->mImmed.back(); } - mData->mImmed.pop_back(); - mData->mByteCode.pop_back(); - mData->mByteCode.pop_back(); - } - if(!lhs_negated) // if (-x-y) was changed to -(x+y), add missing cNeg - { - AddFunctionOpcode(c == '+' ? cAdd : cSub); - --mStackPtr; - } - else if(c == '+') // (-x)+y -> rsub(x,y) - { - AddFunctionOpcode(cRSub); - --mStackPtr; - } - else // (-x)-y -> -(x+y) - { - AddFunctionOpcode(cAdd); - --mStackPtr; - AddFunctionOpcode(cNeg); - } - } - FP_FlushImmed(false); - #undef FP_FlushImmed - return function; -} - -template -inline const char* -FunctionParserBase::CompileComparison(const char* function) -{ - unsigned op=0; - while(true) - { - function = CompileAddition(function); - if(!function) return 0; - - if(op) - { - AddFunctionOpcode(op); - --mStackPtr; - } - switch(*function) - { - case '=': - ++function; op = cEqual; break; - case '!': - if(function[1] == '=') - { function += 2; op = cNEqual; break; } - // If '=' does not follow '!', a syntax error will - // be generated at the outermost parsing level - return function; - case '<': - if(function[1] == '=') - { function += 2; op = cLessOrEq; break; } - ++function; op = cLess; break; - case '>': - if(function[1] == '=') - { function += 2; op = cGreaterOrEq; break; } - ++function; op = cGreater; break; - default: return function; - } - SkipSpace(function); - } - return function; -} - -template -inline const char* FunctionParserBase::CompileAnd(const char* function) -{ - std::size_t param0end=0; - while(true) - { - function = CompileComparison(function); - if(!function) return 0; - - if(param0end) - { - if(mData->mByteCode.back() == cNotNot) mData->mByteCode.pop_back(); - - AddFunctionOpcode(cAnd); - --mStackPtr; - } - if(*function != '&') break; - ++function; - SkipSpace(function); - param0end = mData->mByteCode.size(); - } - return function; -} - -template -const char* FunctionParserBase::CompileExpression(const char* function) -{ - std::size_t param0end=0; - while(true) - { - SkipSpace(function); - function = CompileAnd(function); - if(!function) return 0; - - if(param0end) - { - if(mData->mByteCode.back() == cNotNot) mData->mByteCode.pop_back(); - - AddFunctionOpcode(cOr); - --mStackPtr; - } - if(*function != '|') break; - ++function; - param0end = mData->mByteCode.size(); - } - return function; -} - -template -const char* FunctionParserBase::Compile(const char* function) -{ - while(true) - { - // Check if an identifier appears as first token: - SkipSpace(function); - unsigned nameLength = readIdentifier(function); - if(nameLength > 0 && !(nameLength & 0x80000000U)) - { - typename Data::InlineVariable inlineVar = - { NamePtr(function, nameLength), 0 }; - - // Check if it's an unknown identifier: - typename NamePtrsMap::iterator nameIter = - mData->mNamePtrs.find(inlineVar.mName); - if(nameIter == mData->mNamePtrs.end()) - { - const char* function2 = function + nameLength; - SkipSpace(function2); - - // Check if ":=" follows the unknown identifier: - if(function2[0] == ':' && function2[1] == '=') - { - // Parse the expression that follows and create the - // inline variable: - function2 = CompileExpression(function2 + 2); - if(!function2) return 0; - if(*function2 != ';') return function2; - - inlineVar.mFetchIndex = mStackPtr - 1; - mData->mInlineVarNames.push_back(inlineVar); - - // Continue with the expression after the ';': - function = function2 + 1; - continue; - } - } - } - break; - } - - return CompileExpression(function); -} - -template template -inline void FunctionParserBase::PushOpcodeParam - (unsigned value) -{ - mData->mByteCode.push_back(value | (PutFlag ? FP_ParamGuardMask : 0u)); - if(PutFlag) mData->mHasByteCodeFlags = true; -} - -template template -inline void FunctionParserBase::PutOpcodeParamAt - (unsigned value, unsigned offset) -{ - mData->mByteCode[offset] = value | (PutFlag ? FP_ParamGuardMask : 0u); - if(PutFlag) mData->mHasByteCodeFlags = true; -} - -//=========================================================================== -// Function evaluation -//=========================================================================== -template -Value_t FunctionParserBase::Eval(const Value_t* Vars) -{ - if(mData->mParseErrorType != FP_NO_ERROR) return Value_t(0); - - const unsigned* const byteCode = &(mData->mByteCode[0]); - const Value_t* const immed = mData->mImmed.empty() ? 0 : &(mData->mImmed[0]); - const unsigned byteCodeSize = unsigned(mData->mByteCode.size()); - unsigned IP, DP=0; - int SP=-1; - -#ifdef FP_USE_THREAD_SAFE_EVAL - /* If Eval() may be called by multiple threads simultaneously, - * then Eval() must allocate its own stack. - */ -#ifdef FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA - /* alloca() allocates room from the hardware stack. - * It is automatically freed when the function returns. - */ - Value_t* const Stack = (Value_t*)alloca(mData->mStackSize*sizeof(Value_t)); -#else - /* Allocate from the heap. Ensure that it is freed - * automatically no matter which exit path is taken. - */ - struct AutoDealloc - { - Value_t* ptr; - ~AutoDealloc() { delete[] ptr; } - } AutoDeallocStack = { new Value_t[mData->mStackSize] }; - Value_t*& Stack = AutoDeallocStack.ptr; -#endif -#else - /* No thread safety, so use a global stack. */ - std::vector& Stack = mData->mStack; -#endif - - for(IP=0; IP::result == false - && (Stack[SP] < Value_t(-1) || Stack[SP] > Value_t(1))) - { mData->mEvalErrorType=4; return Value_t(0); } - Stack[SP] = fp_acos(Stack[SP]); break; - - case cAcosh: - if(IsComplexType::result == false - && Stack[SP] < Value_t(1)) - { mData->mEvalErrorType=4; return Value_t(0); } - Stack[SP] = fp_acosh(Stack[SP]); break; - - case cAsin: - if(IsComplexType::result == false - && (Stack[SP] < Value_t(-1) || Stack[SP] > Value_t(1))) - { mData->mEvalErrorType=4; return Value_t(0); } - Stack[SP] = fp_asin(Stack[SP]); break; - - case cAsinh: Stack[SP] = fp_asinh(Stack[SP]); break; - - case cAtan: Stack[SP] = fp_atan(Stack[SP]); break; - - case cAtan2: Stack[SP-1] = fp_atan2(Stack[SP-1], Stack[SP]); - --SP; break; - - case cAtanh: - if(IsComplexType::result - ? (Stack[SP] == Value_t(-1) || Stack[SP] == Value_t(1)) - : (Stack[SP] <= Value_t(-1) || Stack[SP] >= Value_t(1))) - { mData->mEvalErrorType=4; return Value_t(0); } - Stack[SP] = fp_atanh(Stack[SP]); break; - - case cCbrt: Stack[SP] = fp_cbrt(Stack[SP]); break; - - case cCeil: Stack[SP] = fp_ceil(Stack[SP]); break; - - case cCos: Stack[SP] = fp_cos(Stack[SP]); break; - - case cCosh: Stack[SP] = fp_cosh(Stack[SP]); break; - - case cCot: - { - const Value_t t = fp_tan(Stack[SP]); - if(t == Value_t(0)) - { mData->mEvalErrorType=1; return Value_t(0); } - Stack[SP] = Value_t(1)/t; break; - } - - case cCsc: - { - const Value_t s = fp_sin(Stack[SP]); - if(s == Value_t(0)) - { mData->mEvalErrorType=1; return Value_t(0); } - Stack[SP] = Value_t(1)/s; break; - } - - - case cExp: Stack[SP] = fp_exp(Stack[SP]); break; - - case cExp2: Stack[SP] = fp_exp2(Stack[SP]); break; - - case cFloor: Stack[SP] = fp_floor(Stack[SP]); break; - - case cHypot: - Stack[SP-1] = fp_hypot(Stack[SP-1], Stack[SP]); - --SP; break; - - case cIf: - if(fp_truth(Stack[SP--])) - IP += 2; - else - { - const unsigned* buf = &byteCode[IP+1]; - IP = buf[0]; - DP = buf[1]; - } - break; - - case cInt: Stack[SP] = fp_int(Stack[SP]); break; - - case cLog: - if(IsComplexType::result - ? Stack[SP] == Value_t(0) - : !(Stack[SP] > Value_t(0))) - { mData->mEvalErrorType=3; return Value_t(0); } - Stack[SP] = fp_log(Stack[SP]); break; - - case cLog10: - if(IsComplexType::result - ? Stack[SP] == Value_t(0) - : !(Stack[SP] > Value_t(0))) - { mData->mEvalErrorType=3; return Value_t(0); } - Stack[SP] = fp_log10(Stack[SP]); - break; - - case cLog2: - if(IsComplexType::result - ? Stack[SP] == Value_t(0) - : !(Stack[SP] > Value_t(0))) - { mData->mEvalErrorType=3; return Value_t(0); } - Stack[SP] = fp_log2(Stack[SP]); - break; - - case cMax: Stack[SP-1] = fp_max(Stack[SP-1], Stack[SP]); - --SP; break; - - case cMin: Stack[SP-1] = fp_min(Stack[SP-1], Stack[SP]); - --SP; break; - - case cPow: - // x:Negative ^ y:NonInteger is failure, - // except when the reciprocal of y forms an integer - /*if(IsComplexType::result == false - && Stack[SP-1] < Value_t(0) && - !isInteger(Stack[SP]) && - !isInteger(1.0 / Stack[SP])) - { mEvalErrorType=3; return Value_t(0); }*/ - // x:0 ^ y:negative is failure - if(Stack[SP-1] == Value_t(0) && - Stack[SP] < Value_t(0)) - { mData->mEvalErrorType=3; return Value_t(0); } - Stack[SP-1] = fp_pow(Stack[SP-1], Stack[SP]); - --SP; break; - - case cTrunc: Stack[SP] = fp_trunc(Stack[SP]); break; - - case cSec: - { - const Value_t c = fp_cos(Stack[SP]); - if(c == Value_t(0)) - { mData->mEvalErrorType=1; return Value_t(0); } - Stack[SP] = Value_t(1)/c; break; - } - - case cSin: Stack[SP] = fp_sin(Stack[SP]); break; - - case cSinh: Stack[SP] = fp_sinh(Stack[SP]); break; - - case cSqrt: - if(IsComplexType::result == false && - Stack[SP] < Value_t(0)) - { mData->mEvalErrorType=2; return Value_t(0); } - Stack[SP] = fp_sqrt(Stack[SP]); break; - - case cTan: Stack[SP] = fp_tan(Stack[SP]); break; - - case cTanh: Stack[SP] = fp_tanh(Stack[SP]); break; - - -// Misc: - case cImmed: Stack[++SP] = immed[DP++]; break; - - case cJump: - { - const unsigned* buf = &byteCode[IP+1]; - IP = buf[0]; - DP = buf[1]; - break; - } - -// Operators: - case cNeg: Stack[SP] = -Stack[SP]; break; - case cAdd: Stack[SP-1] += Stack[SP]; --SP; break; - case cSub: Stack[SP-1] -= Stack[SP]; --SP; break; - case cMul: Stack[SP-1] *= Stack[SP]; --SP; break; - - case cDiv: - if(Stack[SP] == Value_t(0)) - { mData->mEvalErrorType=1; return Value_t(0); } - Stack[SP-1] /= Stack[SP]; --SP; break; - - case cMod: - if(Stack[SP] == Value_t(0)) - { mData->mEvalErrorType=1; return Value_t(0); } - Stack[SP-1] = fp_mod(Stack[SP-1], Stack[SP]); - --SP; break; - - case cEqual: - Stack[SP-1] = fp_equal(Stack[SP-1], Stack[SP]); - --SP; break; - - case cNEqual: - Stack[SP-1] = fp_nequal(Stack[SP-1], Stack[SP]); - --SP; break; - - case cLess: - Stack[SP-1] = fp_less(Stack[SP-1], Stack[SP]); - --SP; break; - - case cLessOrEq: - Stack[SP-1] = fp_lessOrEq(Stack[SP-1], Stack[SP]); - --SP; break; - - case cGreater: - Stack[SP-1] = fp_less(Stack[SP], Stack[SP-1]); - --SP; break; - - case cGreaterOrEq: - Stack[SP-1] = fp_lessOrEq(Stack[SP], Stack[SP-1]); - --SP; break; - - case cNot: Stack[SP] = fp_not(Stack[SP]); break; - - case cNotNot: Stack[SP] = fp_notNot(Stack[SP]); break; - - case cAnd: - Stack[SP-1] = fp_and(Stack[SP-1], Stack[SP]); - --SP; break; - - case cOr: - Stack[SP-1] = fp_or(Stack[SP-1], Stack[SP]); - --SP; break; - -// Degrees-radians conversion: - case cDeg: Stack[SP] = RadiansToDegrees(Stack[SP]); break; - case cRad: Stack[SP] = DegreesToRadians(Stack[SP]); break; - -// User-defined function calls: - case cFCall: - { - const unsigned index = byteCode[++IP]; - const unsigned params = mData->mFuncPtrs[index].mParams; - const Value_t retVal = - mData->mFuncPtrs[index].mRawFuncPtr ? - mData->mFuncPtrs[index].mRawFuncPtr(&Stack[SP-params+1]) : - mData->mFuncPtrs[index].mFuncWrapperPtr->callFunction - (&Stack[SP-params+1]); - SP -= int(params)-1; - Stack[SP] = retVal; - break; - } - - case cPCall: - { - unsigned index = byteCode[++IP]; - unsigned params = mData->mFuncParsers[index].mParams; - Value_t retVal = - mData->mFuncParsers[index].mParserPtr->Eval - (&Stack[SP-params+1]); - SP -= int(params)-1; - Stack[SP] = retVal; - const int error = - mData->mFuncParsers[index].mParserPtr->EvalError(); - if(error) - { - mData->mEvalErrorType = error; - return 0; - } - break; - } - - - case cFetch: - { - unsigned stackOffs = byteCode[++IP]; - Stack[SP+1] = Stack[stackOffs]; ++SP; - break; - } - -#ifdef FP_SUPPORT_OPTIMIZER - case cPopNMov: - { - unsigned stackOffs_target = byteCode[++IP]; - unsigned stackOffs_source = byteCode[++IP]; - Stack[stackOffs_target] = Stack[stackOffs_source]; - SP = stackOffs_target; - break; - } - - case cLog2by: - if(IsComplexType::result - ? Stack[SP-1] == Value_t(0) - : !(Stack[SP-1] > Value_t(0))) - { mData->mEvalErrorType=3; return Value_t(0); } - Stack[SP-1] = fp_log2(Stack[SP-1]) * Stack[SP]; - --SP; - break; - - case cNop: break; -#endif // FP_SUPPORT_OPTIMIZER - - case cSinCos: - fp_sinCos(Stack[SP], Stack[SP+1], Stack[SP]); - ++SP; - break; - case cSinhCosh: - fp_sinhCosh(Stack[SP], Stack[SP+1], Stack[SP]); - ++SP; - break; - - case cAbsNot: - Stack[SP] = fp_absNot(Stack[SP]); break; - case cAbsNotNot: - Stack[SP] = fp_absNotNot(Stack[SP]); break; - case cAbsAnd: - Stack[SP-1] = fp_absAnd(Stack[SP-1], Stack[SP]); - --SP; break; - case cAbsOr: - Stack[SP-1] = fp_absOr(Stack[SP-1], Stack[SP]); - --SP; break; - case cAbsIf: - if(fp_absTruth(Stack[SP--])) - IP += 2; - else - { - const unsigned* buf = &byteCode[IP+1]; - IP = buf[0]; - DP = buf[1]; - } - break; - - case cDup: Stack[SP+1] = Stack[SP]; ++SP; break; - - case cInv: - if(Stack[SP] == Value_t(0)) - { mData->mEvalErrorType=1; return Value_t(0); } - Stack[SP] = Value_t(1)/Stack[SP]; - break; - - case cSqr: - Stack[SP] = Stack[SP]*Stack[SP]; - break; - - case cRDiv: - if(Stack[SP-1] == Value_t(0)) - { mData->mEvalErrorType=1; return Value_t(0); } - Stack[SP-1] = Stack[SP] / Stack[SP-1]; --SP; break; - - case cRSub: Stack[SP-1] = Stack[SP] - Stack[SP-1]; --SP; break; - - case cRSqrt: - if(Stack[SP] == Value_t(0)) - { mData->mEvalErrorType=1; return Value_t(0); } - Stack[SP] = Value_t(1) / fp_sqrt(Stack[SP]); break; - -#ifdef FP_SUPPORT_COMPLEX_NUMBERS - case cReal: Stack[SP] = fp_real(Stack[SP]); break; - case cImag: Stack[SP] = fp_imag(Stack[SP]); break; - case cArg: Stack[SP] = fp_arg(Stack[SP]); break; - case cConj: Stack[SP] = fp_conj(Stack[SP]); break; - case cPolar: - Stack[SP-1] = fp_polar(Stack[SP-1], Stack[SP]); - --SP; break; -#endif - - -// Variables: - default: - Stack[++SP] = Vars[byteCode[IP]-VarBegin]; - } - } - - mData->mEvalErrorType=0; - return Stack[SP]; -} - - -//=========================================================================== -// Variable deduction -//=========================================================================== -namespace -{ - template - int deduceVariables(FunctionParserBase& fParser, - const char* funcStr, - std::string& destVarString, - int* amountOfVariablesFound, - std::vector* destVarNames, - bool useDegrees) - { - typedef std::set StrSet; - StrSet varNames; - - int oldIndex = -1; - - while(true) - { - destVarString.clear(); - for(StrSet::iterator iter = varNames.begin(); - iter != varNames.end(); - ++iter) - { - if(iter != varNames.begin()) destVarString += ","; - destVarString += *iter; - } - - const int index = - fParser.Parse(funcStr, destVarString, useDegrees); - if(index < 0) break; - if(index == oldIndex) return index; - - unsigned nameLength = readIdentifier(funcStr + index); - if(nameLength & 0x80000000U) return index; - if(nameLength == 0) return index; - - varNames.insert(std::string(funcStr + index, nameLength)); - oldIndex = index; - } - - if(amountOfVariablesFound) - *amountOfVariablesFound = int(varNames.size()); - - if(destVarNames) - destVarNames->assign(varNames.begin(), varNames.end()); - - return -1; - } -} - -template -int FunctionParserBase::ParseAndDeduceVariables -(const std::string& function, - int* amountOfVariablesFound, - bool useDegrees) -{ - std::string varString; - return deduceVariables(*this, function.c_str(), varString, - amountOfVariablesFound, 0, useDegrees); -} - -template -int FunctionParserBase::ParseAndDeduceVariables -(const std::string& function, - std::string& resultVarString, - int* amountOfVariablesFound, - bool useDegrees) -{ - std::string varString; - const int index = - deduceVariables(*this, function.c_str(), varString, - amountOfVariablesFound, 0, useDegrees); - if(index < 0) resultVarString = varString; - return index; -} - -template -int FunctionParserBase::ParseAndDeduceVariables -(const std::string& function, - std::vector& resultVars, - bool useDegrees) -{ - std::string varString; - std::vector vars; - const int index = - deduceVariables(*this, function.c_str(), varString, - 0, &vars, useDegrees); - if(index < 0) resultVars.swap(vars); - return index; -} - - -#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING -//=========================================================================== -// Bytecode injection -//=========================================================================== -template -void FunctionParserBase::InjectRawByteCode -(const unsigned* bytecode, unsigned bytecodeAmount, - const Value_t* immed, unsigned immedAmount, unsigned stackSize) -{ - CopyOnWrite(); - - mData->mByteCode.assign(bytecode, bytecode + bytecodeAmount); - mData->mImmed.assign(immed, immed + immedAmount); - mData->mStackSize = stackSize; - -#ifndef FP_USE_THREAD_SAFE_EVAL - mData->mStack.resize(stackSize); -#endif -} - -//=========================================================================== -// Debug output -//=========================================================================== -#include -#include -namespace -{ - inline void printHex(std::ostream& dest, unsigned n) - { - std::ios::fmtflags flags = dest.flags(); - dest.width(4); dest.fill('0'); std::hex(dest); //uppercase(dest); - dest << n; - dest.flags(flags); - } - - void padLine(std::ostringstream& dest, unsigned destLength) - { - for(std::size_t currentLength = dest.str().length(); - currentLength < destLength; - ++currentLength) - { - dest << ' '; - } - } - - const struct PowiMuliType - { - unsigned opcode_square; - unsigned opcode_cumulate; - unsigned opcode_invert; - unsigned opcode_half; - unsigned opcode_invhalf; - } iseq_powi = {cSqr,cMul,cInv,cSqrt,cRSqrt}, - iseq_muli = {~unsigned(0), cAdd,cNeg, ~unsigned(0),~unsigned(0) }; - - template - Value_t ParsePowiMuli( - const PowiMuliType& opcodes, - const std::vector& ByteCode, unsigned& IP, - unsigned limit, - std::size_t factor_stack_base, - std::vector& stack, - bool IgnoreExcess) - { - Value_t result = Value_t(1); - while(IP < limit) - { - if(ByteCode[IP] == opcodes.opcode_square) - { - if(!isInteger(result)) break; - result *= Value_t(2); - ++IP; - continue; - } - if(ByteCode[IP] == opcodes.opcode_invert) - { - if(result < Value_t(0)) break; - result = -result; - ++IP; - continue; - } - if(ByteCode[IP] == opcodes.opcode_half) - { - if(result > Value_t(0) && isEvenInteger(result)) - break; - if(isInteger(result * Value_t(0.5))) break; - result *= Value_t(0.5); - ++IP; - continue; - } - if(ByteCode[IP] == opcodes.opcode_invhalf) - { - if(result > Value_t(0) && isEvenInteger(result)) - break; - if(isInteger(result * Value_t(-0.5))) break; - result *= Value_t(-0.5); - ++IP; - continue; - } - - unsigned dup_fetch_pos = IP; - Value_t lhs = Value_t(1); - - if(ByteCode[IP] == cFetch) - { - unsigned index = ByteCode[++IP]; - if(index < factor_stack_base - || std::size_t(index-factor_stack_base) >= stack.size()) - { - // It wasn't a powi-fetch after all - IP = dup_fetch_pos; - break; - } - lhs = stack[index - factor_stack_base]; - // Note: ^This assumes that cFetch of recentmost - // is always converted into cDup. - goto dup_or_fetch; - } - - if(ByteCode[IP] == cDup) - { - lhs = result; - goto dup_or_fetch; - - dup_or_fetch: - stack.push_back(result); - ++IP; - Value_t subexponent = ParsePowiMuli - (opcodes, - ByteCode, IP, limit, - factor_stack_base, stack, - IgnoreExcess); - if(IP >= limit && IgnoreExcess) - return lhs*subexponent; - if(IP >= limit || ByteCode[IP] != opcodes.opcode_cumulate) - { - // It wasn't a powi-dup after all - IP = dup_fetch_pos; - break; - } - ++IP; // skip opcode_cumulate - stack.pop_back(); - result += lhs*subexponent; - continue; - } - break; - } - return result; - } - - template - Value_t ParsePowiSequence(const std::vector& ByteCode, - unsigned& IP, unsigned limit, - std::size_t factor_stack_base, - bool IgnoreExcess = false) - { - std::vector stack; - stack.push_back(Value_t(1)); - return ParsePowiMuli(iseq_powi, ByteCode, IP, limit, - factor_stack_base, stack, - IgnoreExcess); - } - - template - Value_t ParseMuliSequence(const std::vector& ByteCode, - unsigned& IP, unsigned limit, - std::size_t factor_stack_base, - bool IgnoreExcess = false) - { - std::vector stack; - stack.push_back(Value_t(1)); - return ParsePowiMuli(iseq_muli, ByteCode, IP, limit, - factor_stack_base, stack, - IgnoreExcess); - } - - struct IfInfo - { - std::pair condition; - std::pair thenbranch; - unsigned endif_location; - - IfInfo() : condition(), thenbranch(), endif_location() { } - }; -} - -template -void FunctionParserBase::PrintByteCode(std::ostream& dest, - bool showExpression) const -{ - dest << "Size of stack: " << mData->mStackSize << "\n"; - - std::ostringstream outputBuffer; - std::ostream& output = (showExpression ? outputBuffer : dest); - - const std::vector& ByteCode = mData->mByteCode; - const std::vector& Immed = mData->mImmed; - - std::vector > stack; - std::vector if_stack; - - for(unsigned IP = 0, DP = 0; IP <= ByteCode.size(); ++IP) - { - after_powi_or_muli:; - std::string n; - bool out_params = false; - unsigned params = 2, produces = 1, opcode = 0; - - if(showExpression && !if_stack.empty() && - ( // Normal If termination rule: - if_stack.back().endif_location == IP - // This rule matches when cJumps are threaded: - || (IP < ByteCode.size() && ByteCode[IP] == cJump - && !if_stack.back().thenbranch.second.empty()) - )) - { - printHex(output, IP); - if(if_stack.back().endif_location == IP) - output << ": ----- (phi)"; - else - output << ": ----- (phi+)"; - - stack.resize(stack.size()+2); - std::swap(stack[stack.size()-3], stack[stack.size()-1]); - std::swap(if_stack.back().condition, stack[stack.size()-3]); - std::swap(if_stack.back().thenbranch, stack[stack.size()-2]); - opcode = cIf; - params = 3; - --IP; - if_stack.pop_back(); - } - else - { - if(IP >= ByteCode.size()) break; - opcode = ByteCode[IP]; - - if(showExpression && ( - opcode == cSqr || opcode == cDup - || opcode == cInv - || opcode == cSqrt || opcode == cRSqrt - || opcode == cFetch - )) - { - unsigned changed_ip = IP; - Value_t exponent = - ParsePowiSequence - (ByteCode, changed_ip, - if_stack.empty() - ? (unsigned)ByteCode.size() - : if_stack.back().endif_location, - stack.size()-1); - std::string operation_prefix; - std::ostringstream operation_value; - int prio = 0; - if(exponent == Value_t(1.0)) - { - if(opcode != cDup) goto not_powi_or_muli; - Value_t factor = - ParseMuliSequence - (ByteCode, changed_ip, - if_stack.empty() - ? (unsigned)ByteCode.size() - : if_stack.back().endif_location, - stack.size()-1); - if(factor == Value_t(1) || factor == Value_t(-1)) - goto not_powi_or_muli; - operation_prefix = "*"; - operation_value << factor; - prio = 3; - } - else - { - prio = 2; - operation_prefix = "^"; - operation_value << exponent; - } - - //unsigned explanation_before = changed_ip-2; - unsigned explanation_before = changed_ip-1; - - const char* explanation_prefix = "_"; - for(const unsigned first_ip = IP; IP < changed_ip; ++IP) - { - printHex(output, IP); - output << ": "; - - const char* sep = "|"; - if(first_ip+1 == changed_ip) - { sep = "="; explanation_prefix = " "; } - else if(IP == first_ip) sep = "\\"; - else if(IP+1 == changed_ip) sep = "/"; - else explanation_prefix = "="; - - switch(ByteCode[IP]) - { - case cInv: output << "inv"; break; - case cNeg: output << "neg"; break; - case cDup: output << "dup"; break; - case cSqr: output << "sqr"; break; - case cMul: output << "mul"; break; - case cAdd: output << "add"; break; - case cCbrt: output << "cbrt"; break; - case cSqrt: output << "sqrt"; break; - case cRSqrt: output << "rsqrt"; break; - case cFetch: - { - unsigned index = ByteCode[++IP]; - output << "cFetch(" << index << ")"; - break; - } - default: break; - } - padLine(outputBuffer, 20); - output << sep; - if(IP >= explanation_before) - { - explanation_before = (unsigned)ByteCode.size(); - output << explanation_prefix - << '[' << (stack.size()-1) << ']'; - std::string last = stack.back().second; - if(stack.back().first >= prio) - last = "(" + last + ")"; - output << last; - output << operation_prefix; - output << operation_value.str(); - } - else - { - unsigned p = first_ip; - Value_t exp = operation_prefix=="^" ? - ParsePowiSequence - (ByteCode, p, IP+1, stack.size()-1, true) : - ParseMuliSequence - (ByteCode, p, IP+1, stack.size()-1, true); - std::string last = stack.back().second; - if(stack.back().first >= prio) - last = "(" + last + ")"; - output << " ..." << last; - output << operation_prefix; - output << exp; - } - dest << outputBuffer.str() << std::endl; - outputBuffer.str(""); - } - - std::string& last = stack.back().second; - if(stack.back().first >= prio) - last = "(" + last + ")"; - last += operation_prefix; - last += operation_value.str(); - stack.back().first = prio; - - goto after_powi_or_muli; - } - not_powi_or_muli:; - printHex(output, IP); - output << ": "; - - switch(opcode) - { - case cIf: - { - unsigned label = ByteCode[IP+1]+1; - output << "jz "; - printHex(output, label); - params = 1; - produces = 0; - IP += 2; - - if_stack.resize(if_stack.size() + 1); - std::swap( if_stack.back().condition, stack.back() ); - if_stack.back().endif_location = (unsigned) ByteCode.size(); - stack.pop_back(); - break; - } - case cAbsIf: - { - unsigned dp = ByteCode[IP+2]; - unsigned label = ByteCode[IP+1]+1; - output << "jz_abs " << dp << ","; - printHex(output, label); - params = 1; - produces = 0; - IP += 2; - - if_stack.resize(if_stack.size() + 1); - std::swap( if_stack.back().condition, stack.back() ); - if_stack.back().endif_location = (unsigned) ByteCode.size(); - stack.pop_back(); - break; - } - - case cJump: - { - unsigned dp = ByteCode[IP+2]; - unsigned label = ByteCode[IP+1]+1; - - if(!if_stack.empty() && !stack.empty()) - { - std::swap(if_stack.back().thenbranch, stack.back()); - if_stack.back().endif_location = label; - stack.pop_back(); - } - - output << "jump " << dp << ","; - printHex(output, label); - params = 0; - produces = 0; - IP += 2; - break; - } - case cImmed: - { - if(showExpression) - { - std::ostringstream buf; - buf.precision(8); - buf << Immed[DP]; - stack.push_back( std::make_pair(0, buf.str()) ); - } - output.precision(8); - output << "push " << Immed[DP]; - ++DP; - produces = 0; - break; - } - - case cFCall: - { - const unsigned index = ByteCode[++IP]; - params = mData->mFuncPtrs[index].mParams; - static std::string name; - name = "f:" + findName(mData->mNamePtrs, index, - NameData::FUNC_PTR); - n = name.c_str(); - out_params = true; - break; - } - - case cPCall: - { - const unsigned index = ByteCode[++IP]; - params = mData->mFuncParsers[index].mParams; - static std::string name; - name = "p:" + findName(mData->mNamePtrs, index, - NameData::PARSER_PTR); - n = name.c_str(); - out_params = true; - break; - } - - default: - if(IsVarOpcode(opcode)) - { - if(showExpression) - { - stack.push_back(std::make_pair(0, - (findName(mData->mNamePtrs, opcode, - NameData::VARIABLE)))); - } - output << "push Var" << opcode-VarBegin; - produces = 0; - } - else - { - switch(OPCODE(opcode)) - { - case cNeg: n = "neg"; params = 1; break; - case cAdd: n = "add"; break; - case cSub: n = "sub"; break; - case cMul: n = "mul"; break; - case cDiv: n = "div"; break; - case cMod: n = "mod"; break; - case cPow: n = "pow"; break; - case cEqual: n = "eq"; break; - case cNEqual: n = "neq"; break; - case cLess: n = "lt"; break; - case cLessOrEq: n = "le"; break; - case cGreater: n = "gt"; break; - case cGreaterOrEq: n = "ge"; break; - case cAnd: n = "and"; break; - case cOr: n = "or"; break; - case cNot: n = "not"; params = 1; break; - case cNotNot: n = "notnot"; params = 1; break; - case cDeg: n = "deg"; params = 1; break; - case cRad: n = "rad"; params = 1; break; - - case cFetch: - { - unsigned index = ByteCode[++IP]; - if(showExpression && index < stack.size()) - stack.push_back(stack[index]); - output << "cFetch(" << index << ")"; - produces = 0; - break; - } - #ifdef FP_SUPPORT_OPTIMIZER - case cLog2by: n = "log2by"; params = 2; out_params = 1; break; - case cPopNMov: - { - std::size_t a = ByteCode[++IP]; - std::size_t b = ByteCode[++IP]; - if(showExpression && b < stack.size()) - { - std::pair stacktop(0, "?"); - if(b < stack.size()) stacktop = stack[b]; - stack.resize(a); - stack.push_back(stacktop); - } - output << "cPopNMov(" << a << ", " << b << ")"; - produces = 0; - break; - } - case cNop: - output << "nop"; params = 0; produces = 0; - break; - #endif - case cSinCos: - { - if(showExpression) - { - std::pair sin = stack.back(); - std::pair cos( - 0, "cos(" + sin.second + ")"); - sin.first = 0; - sin.second = "sin(" + sin.second + ")"; - stack.back() = sin; - stack.push_back(cos); - } - output << "sincos"; - produces = 0; - break; - } - case cSinhCosh: - { - if(showExpression) - { - std::pair sinh = stack.back(); - std::pair cosh( - 0, "cosh(" + sinh.second + ")"); - sinh.first = 0; - sinh.second = "sinh(" + sinh.second + ")"; - stack.back() = sinh; - stack.push_back(cosh); - } - output << "sinhcosh"; - produces = 0; - break; - } - case cAbsAnd: n = "abs_and"; break; - case cAbsOr: n = "abs_or"; break; - case cAbsNot: n = "abs_not"; params = 1; break; - case cAbsNotNot: n = "abs_notnot"; params = 1; break; - case cDup: - { - if(showExpression) - stack.push_back(stack.back()); - output << "dup"; - produces = 0; - break; - } - case cInv: n = "inv"; params = 1; break; - case cSqr: n = "sqr"; params = 1; break; - case cRDiv: n = "rdiv"; break; - case cRSub: n = "rsub"; break; - case cRSqrt: n = "rsqrt"; params = 1; break; - - default: - n = Functions[opcode-cAbs].name; - params = Functions[opcode-cAbs].params; - out_params = params != 1; - } - } - } - } - if(produces) output << n; - if(out_params) output << " (" << params << ")"; - if(showExpression) - { - padLine(outputBuffer, 20); - - if(produces > 0) - { - std::ostringstream buf; - const char *paramsep = ",", *suff = ""; - int prio = 0; bool commutative = false; - switch(opcode) - { - case cIf: buf << "if("; suff = ")"; - break; - case cAbsIf: buf << "if("; suff = ")"; - break; - case cOr: prio = 6; paramsep = "|"; commutative = true; - break; - case cAnd: prio = 5; paramsep = "&"; commutative = true; - break; - case cAdd: prio = 4; paramsep = "+"; commutative = true; - break; - case cSub: prio = 4; paramsep = "-"; - break; - case cMul: prio = 3; paramsep = "*"; commutative = true; - break; - case cDiv: prio = 3; paramsep = "/"; - break; - case cPow: prio = 2; paramsep = "^"; - break; - case cAbsOr: prio = 6; paramsep = "|"; commutative = true; - break; - case cAbsAnd: prio = 5; paramsep = "&"; commutative = true; - break; - case cSqr: prio = 2; suff = "^2"; - break; - case cNeg: buf << "(-("; suff = "))"; - break; - case cNot: buf << "(!("; suff = "))"; - break; - default: buf << n << '('; suff = ")"; - } - - const char* sep = ""; - for(unsigned a=0; a& prev = - stack[stack.size() - params + a]; - if(prio > 0 && (prev.first > prio || - (prev.first==prio && !commutative))) - buf << '(' << prev.second << ')'; - else - buf << prev.second; - } - sep = paramsep; - } - if(stack.size() >= params) - stack.resize(stack.size() - params); - else - stack.clear(); - buf << suff; - stack.push_back(std::make_pair(prio, buf.str())); - //if(n.size() <= 4 && !out_params) padLine(outputBuffer, 20); - } - //padLine(outputBuffer, 20); - output << "= "; - if(((opcode == cIf || opcode == cAbsIf) && params != 3) - || opcode == cJump - #ifdef FP_SUPPORT_OPTIMIZER - || opcode == cNop - #endif - ) - output << "(void)"; - else if(stack.empty()) - output << "[?] ?"; - else - output << '[' << (stack.size()-1) << ']' - << stack.back().second; - } - - if(showExpression) - { - dest << outputBuffer.str() << std::endl; - outputBuffer.str(""); - } - else - output << std::endl; - } - dest << std::flush; -} -#endif - - -#ifndef FP_SUPPORT_OPTIMIZER -template -void FunctionParserBase::Optimize() -{ - // Do nothing if no optimizations are supported. -} -#endif - - -#define FUNCTIONPARSER_INSTANTIATE_CLASS(type) \ - template class FunctionParserBase< type >; - -#ifndef FP_DISABLE_DOUBLE_TYPE -FUNCTIONPARSER_INSTANTIATE_CLASS(double) -#endif - -#ifdef FP_SUPPORT_FLOAT_TYPE -FUNCTIONPARSER_INSTANTIATE_CLASS(float) -#endif - -#ifdef FP_SUPPORT_LONG_DOUBLE_TYPE -FUNCTIONPARSER_INSTANTIATE_CLASS(long double) -#endif - -#ifdef FP_SUPPORT_LONG_INT_TYPE -FUNCTIONPARSER_INSTANTIATE_CLASS(long) -#endif - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE -FUNCTIONPARSER_INSTANTIATE_CLASS(MpfrFloat) -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE -FUNCTIONPARSER_INSTANTIATE_CLASS(GmpInt) -#endif - -#ifdef FP_SUPPORT_COMPLEX_DOUBLE_TYPE -FUNCTIONPARSER_INSTANTIATE_CLASS(std::complex) -#endif - -#ifdef FP_SUPPORT_COMPLEX_FLOAT_TYPE -FUNCTIONPARSER_INSTANTIATE_CLASS(std::complex) -#endif - -#ifdef FP_SUPPORT_COMPLEX_LONG_DOUBLE_TYPE -FUNCTIONPARSER_INSTANTIATE_CLASS(std::complex) -#endif diff --git a/fparser/fparser.hh b/fparser/fparser.hh deleted file mode 100644 index 282e9b5..0000000 --- a/fparser/fparser.hh +++ /dev/null @@ -1,223 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.5.1 *| -|*-------------------------------------------------------------------------*| -|* Copyright: Juha Nieminen, Joel Yliluoma *| -|* *| -|* This library is distributed under the terms of the *| -|* GNU Lesser General Public License version 3. *| -|* (See lgpl.txt and gpl.txt for the license text.) *| -\***************************************************************************/ - -#ifndef ONCE_FPARSER_H_ -#define ONCE_FPARSER_H_ - -#include -#include - -#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING -#include -#endif - -#ifdef _MSC_VER -// Visual Studio's warning about missing definitions for the explicit -// FunctionParserBase instantiations is irrelevant here. -#pragma warning(disable : 4661) -#endif - -namespace FPoptimizer_CodeTree { template class CodeTree; } - -template -class FunctionParserBase -{ - public: - enum ParseErrorType - { - SYNTAX_ERROR=0, MISM_PARENTH, MISSING_PARENTH, EMPTY_PARENTH, - EXPECT_OPERATOR, OUT_OF_MEMORY, UNEXPECTED_ERROR, INVALID_VARS, - ILL_PARAMS_AMOUNT, PREMATURE_EOS, EXPECT_PARENTH_FUNC, - UNKNOWN_IDENTIFIER, - NO_FUNCTION_PARSED_YET, - FP_NO_ERROR - }; - - typedef Value_t value_type; - - - int Parse(const char* Function, const std::string& Vars, - bool useDegrees = false); - int Parse(const std::string& Function, const std::string& Vars, - bool useDegrees = false); - - void setDelimiterChar(char); - - static Value_t epsilon(); - static void setEpsilon(Value_t); - - const char* ErrorMsg() const; - ParseErrorType GetParseErrorType() const; - - Value_t Eval(const Value_t* Vars); - int EvalError() const; - - bool AddConstant(const std::string& name, Value_t value); - bool AddUnit(const std::string& name, Value_t value); - - typedef Value_t (*FunctionPtr)(const Value_t*); - - bool AddFunction(const std::string& name, - FunctionPtr, unsigned paramsAmount); - bool AddFunction(const std::string& name, FunctionParserBase&); - - class FunctionWrapper; - - template - bool AddFunctionWrapper(const std::string& name, const DerivedWrapper&, - unsigned paramsAmount); - - FunctionWrapper* GetFunctionWrapper(const std::string& name); - - bool RemoveIdentifier(const std::string& name); - - void Optimize(); - - - int ParseAndDeduceVariables(const std::string& function, - int* amountOfVariablesFound = 0, - bool useDegrees = false); - int ParseAndDeduceVariables(const std::string& function, - std::string& resultVarString, - int* amountOfVariablesFound = 0, - bool useDegrees = false); - int ParseAndDeduceVariables(const std::string& function, - std::vector& resultVars, - bool useDegrees = false); - - - FunctionParserBase(); - ~FunctionParserBase(); - - // Copy constructor and assignment operator (implemented using the - // copy-on-write technique for efficiency): - FunctionParserBase(const FunctionParserBase&); - FunctionParserBase& operator=(const FunctionParserBase&); - - - void ForceDeepCopy(); - - - -#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING - // For debugging purposes only. - // Performs no sanity checks or anything. If the values are wrong, the - // library will crash. Do not use unless you know what you are doing. - void InjectRawByteCode(const unsigned* bytecode, unsigned bytecodeAmount, - const Value_t* immed, unsigned immedAmount, - unsigned stackSize); - - void PrintByteCode(std::ostream& dest, bool showExpression = true) const; -#endif - - - -//======================================================================== - protected: -//======================================================================== - // A derived class can implement its own evaluation logic by using - // the parser data (found in fptypes.hh). - struct Data; - Data* getParserData(); - - -//======================================================================== - private: -//======================================================================== - - friend class FPoptimizer_CodeTree::CodeTree; - -// Private data: -// ------------ - Data* mData; - unsigned mStackPtr; - - -// Private methods: -// --------------- - void CopyOnWrite(); - bool CheckRecursiveLinking(const FunctionParserBase*) const; - bool NameExists(const char*, unsigned); - bool ParseVariables(const std::string&); - int ParseFunction(const char*, bool); - const char* SetErrorType(ParseErrorType, const char*); - - void AddFunctionOpcode(unsigned); - void AddImmedOpcode(Value_t v); - void incStackPtr(); - void CompilePowi(long); - bool TryCompilePowi(Value_t); - - const char* CompileIf(const char*); - const char* CompileFunctionParams(const char*, unsigned); - const char* CompileElement(const char*); - const char* CompilePossibleUnit(const char*); - const char* CompilePow(const char*); - const char* CompileUnaryMinus(const char*); - const char* CompileMult(const char*); - const char* CompileAddition(const char*); - const char* CompileComparison(const char*); - const char* CompileAnd(const char*); - const char* CompileExpression(const char*); - inline const char* CompileFunction(const char*, unsigned); - inline const char* CompileParenthesis(const char*); - inline const char* CompileLiteral(const char*); - template - inline void PushOpcodeParam(unsigned); - template - inline void PutOpcodeParamAt(unsigned, unsigned offset); - const char* Compile(const char*); - - bool addFunctionWrapperPtr(const std::string&, FunctionWrapper*, unsigned); - static void incFuncWrapperRefCount(FunctionWrapper*); - static unsigned decFuncWrapperRefCount(FunctionWrapper*); - -protected: - // Parsing utility functions - static std::pair ParseLiteral(const char*); - static unsigned ParseIdentifier(const char*); -}; - -class FunctionParser: public FunctionParserBase {}; -class FunctionParser_f: public FunctionParserBase {}; -class FunctionParser_ld: public FunctionParserBase {}; -class FunctionParser_li: public FunctionParserBase {}; - -#include -class FunctionParser_cd: public FunctionParserBase > {}; -class FunctionParser_cf: public FunctionParserBase > {}; -class FunctionParser_cld: public FunctionParserBase > {}; - - - -template -class FunctionParserBase::FunctionWrapper -{ - unsigned mReferenceCount; - friend class FunctionParserBase; - - public: - FunctionWrapper(): mReferenceCount(1) {} - FunctionWrapper(const FunctionWrapper&): mReferenceCount(1) {} - virtual ~FunctionWrapper() {} - FunctionWrapper& operator=(const FunctionWrapper&) { return *this; } - - virtual Value_t callFunction(const Value_t*) = 0; -}; - -template -template -bool FunctionParserBase::AddFunctionWrapper -(const std::string& name, const DerivedWrapper& wrapper, unsigned paramsAmount) -{ - return addFunctionWrapperPtr - (name, new DerivedWrapper(wrapper), paramsAmount); -} -#endif diff --git a/fparser/fparser.pro b/fparser/fparser.pro deleted file mode 100644 index 3b2e7b7..0000000 --- a/fparser/fparser.pro +++ /dev/null @@ -1,35 +0,0 @@ -###################################################################### -# Automatically generated by qmake (2.01a) Tue Mar 10 07:42:54 2009 -###################################################################### - -CONFIG -= qt -TEMPLATE = lib -TARGET = -DEPENDPATH += . -INCLUDEPATH += . -VERSION = 4.5.1 - -# Input -HEADERS += fparser.hh fpconfig.hh fptypes.hh -SOURCES += fparser.cc fpoptimizer.cc - -# -# INSTALL -# -isEmpty(PREFIX) { - PREFIX = /usr/local -} -install.target = install -install.commands = mkdir -p \"$$PREFIX/lib$$LIB_SUFFIX\" -install.commands += && mkdir -p \"$$PREFIX/include\" -unix:!macx { - install.commands += && cp -at \"$$PREFIX/include/\" fparser.hh - install.commands += && cp -at \"$$PREFIX/lib$$LIB_SUFFIX/\" libfparser.so* -} -win32:install.commands += && cp -at \"$$PREFIX/lib$$LIB_SUFFIX/\" release/fparser4.dll -macx { - install.commands += && cp fparser.hh \"$$PREFIX/include/\" - install.commands += && cp libfparser*.dylib \"$$PREFIX/lib$$LIB_SUFFIX/\" -} - -QMAKE_EXTRA_TARGETS += install diff --git a/fparser/fparser_gmpint.hh b/fparser/fparser_gmpint.hh deleted file mode 100644 index 6254a4e..0000000 --- a/fparser/fparser_gmpint.hh +++ /dev/null @@ -1,15 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.5.1 *| -|*-------------------------------------------------------------------------*| -|* Copyright: Juha Nieminen *| -\***************************************************************************/ - -#ifndef ONCE_FPARSER_GMPINT_H_ -#define ONCE_FPARSER_GMPINT_H_ - -#include "fparser.hh" -#include "mpfr/GmpInt.hh" - -class FunctionParser_gmpint: public FunctionParserBase {}; - -#endif diff --git a/fparser/fparser_mpfr.hh b/fparser/fparser_mpfr.hh deleted file mode 100644 index 1eb772f..0000000 --- a/fparser/fparser_mpfr.hh +++ /dev/null @@ -1,15 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.5.1 *| -|*-------------------------------------------------------------------------*| -|* Copyright: Juha Nieminen *| -\***************************************************************************/ - -#ifndef ONCE_FPARSER_MPFR_H_ -#define ONCE_FPARSER_MPFR_H_ - -#include "fparser.hh" -#include "mpfr/MpfrFloat.hh" - -class FunctionParser_mpfr: public FunctionParserBase {}; - -#endif diff --git a/fparser/fpconfig.hh b/fparser/fpconfig.hh deleted file mode 100644 index 1a8a55f..0000000 --- a/fparser/fpconfig.hh +++ /dev/null @@ -1,88 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.5.1 *| -|*-------------------------------------------------------------------------*| -|* Copyright: Juha Nieminen *| -|* *| -|* This library is distributed under the terms of the *| -|* GNU Lesser General Public License version 3. *| -|* (See lgpl.txt and gpl.txt for the license text.) *| -\***************************************************************************/ - -// Configuration file -// ------------------ - -/* NOTE: - This file is for the internal use of the function parser only. - You don't need to include this file in your source files, just - include "fparser.hh". -*/ - - -/* Uncomment any of these lines or define them in your compiler settings - to enable the correspondent version of the parser. (These are disabled - by default because they rely on C99 functions, and non-standard libraries - in the case pf MPFR and GMP, and they make compiling needlessly slower - and the resulting binary needlessly larger if they are not used in the - program.) -*/ -//#define FP_SUPPORT_FLOAT_TYPE -//#define FP_SUPPORT_LONG_DOUBLE_TYPE -//#define FP_SUPPORT_LONG_INT_TYPE -//#define FP_SUPPORT_MPFR_FLOAT_TYPE -//#define FP_SUPPORT_GMP_INT_TYPE -//#define FP_SUPPORT_COMPLEX_DOUBLE_TYPE -//#define FP_SUPPORT_COMPLEX_FLOAT_TYPE -//#define FP_SUPPORT_COMPLEX_LONG_DOUBLE_TYPE - -/* If you are using FunctionParser_ld or FunctionParser_cld and your compiler - supports the strtold() function, you should uncomment the following line. - */ -//#define FP_USE_STRTOLD - - -/* Uncomment this line or define it in your compiler settings if you want - to disable compiling the basic double version of the library, in case - one of the above types is used but not the double type. (If the double - type is not used, then disabling it makes compiling faster and the - resulting binary smaller.) - */ -//#define FP_DISABLE_DOUBLE_TYPE - -/* Uncomment this line or define it in your compiler settings to make the - parser use C++11 math functions. (Note that these may not be supported - by all compilers.) -*/ -//#define FP_SUPPORT_CPLUSPLUS11_MATH_FUNCS - -/* - Whether to use shortcut evaluation for the & and | operators: -*/ -#ifndef FP_DISABLE_SHORTCUT_LOGICAL_EVALUATION -#define FP_ENABLE_SHORTCUT_LOGICAL_EVALUATION -#endif - -/* - Comment out the following lines out if you are not going to use the - optimizer and want a slightly smaller library. The Optimize() method - can still be called, but it will not do anything. - If you are unsure, just leave it. It won't slow down the other parts of - the library. -*/ -#ifndef FP_NO_SUPPORT_OPTIMIZER -#define FP_SUPPORT_OPTIMIZER -#endif - -#if defined(FP_SUPPORT_COMPLEX_DOUBLE_TYPE) || defined(FP_SUPPORT_COMPLEX_FLOAT_TYPE) || defined(FP_SUPPORT_COMPLEX_LONG_DOUBLE_TYPE) -#define FP_SUPPORT_COMPLEX_NUMBERS -#endif - - -/* - No member function of FunctionParser is thread-safe. Most prominently, - Eval() is not thread-safe. By uncommenting one of these lines the Eval() - function can be made thread-safe at the cost of a possible small overhead. - The second version requires that the compiler supports the alloca() function, - which is not standard, but is faster. - */ -//#define FP_USE_THREAD_SAFE_EVAL -//#define FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA diff --git a/fparser/fpoptimizer.cc b/fparser/fpoptimizer.cc deleted file mode 100644 index 4eab746..0000000 --- a/fparser/fpoptimizer.cc +++ /dev/null @@ -1,11745 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.5.1 *| -|*-------------------------------------------------------------------------*| -|* Function optimizer *| -|*-------------------------------------------------------------------------*| -|* Copyright: Joel Yliluoma *| -|* *| -|* This library is distributed under the terms of the *| -|* GNU Lesser General Public License version 3. *| -|* (See lgpl.txt and gpl.txt for the license text.) *| -\***************************************************************************/ - -/* NOTE: - This file contains generated code (from the optimizer sources) and is - not intended to be modified by hand. If you want to modify the optimizer, - download the development version of the library. -*/ - -#include "fpconfig.hh" -#ifdef FP_SUPPORT_OPTIMIZER -#include "fparser.hh" -#include "extrasrc/fptypes.hh" -#include "extrasrc/fpaux.hh" -#define l14 {Value_t -#define l04 ),info, -#define iZ3 {data-> -#define iY3 ==cNot|| -#define iX3 "Found " -#define iW3 info.lQ[b -#define iV3 ;o<<"\n"; -#define iU3 )yR 2,cPow -#define iT3 ;}static yU1 -#define iS3 (tree)!= -#define iR3 ),Value( -#define iQ3 stackpos -#define iP3 minValue0 -#define iO3 "dup(%u) " -#define iN3 =true;iO1 -#define iM3 eR{assert -#define iL3 "%d, cost " -#define iK3 "PUSH " iL2 -#define iJ3 "immed "<< -#define iI3 mFuncParsers -#define iH3 param.data -#define iG3 stderr -#define iF3 sep2=" " -#define iE3 FPHASH_CONST -#define iD3 cache_needed[ -#define iC3 fprintf -#define iB3 "Applying " -#define iA3 FUNCTIONPARSER_INSTANTIATE_OPTIMIZE -#define i93 FUNCTIONPARSER_INSTANTIATE_EMPTY_OPTIMIZE -#define i83 HANDLE_UNARY_CONST_FUNC -#define i73 {if(n11 -#define i63 second; -#define i53 within, -#define i43 AddFrom( -#define i33 tH3== -#define i23 c_count -#define i13 MaxOp -#define i03 else nM -#define tZ3 =tZ cL3 -#define tY3 .nJ 0)); -#define tX3 .nJ 1)); -#define tW3 lD m. -#define tV3 ;a&e71 -#define n93 l8 a)); -#define n83 pos_set -#define n73 goto e1 -#define n63 p1.lT2 p1 -#define n53 [funcno]. -#define n43 eN1[++IP] -#define n33 sim.x2 1, -#define n23 {sim.Eat( -#define n13 eN1[IP]== -#define n03 subtree -#define lZ3 invtree -#define lY3 MakeHash( -#define lX3 parampair -#define lW3 rulenumit -#define lV3 cAnd l3 -#define lU3 ,cMul l3 -#define lT3 cAnd,l6 -#define lS3 x9 lT 2, -#define lR3 },{{1, -#define lQ3 cEqual, -#define lP3 lQ3 lA -#define lO3 t01},{{3, -#define lN3 MakeEqual -#define lM3 nC1,l5:: -#define lL3 nC1,{l5:: -#define lK3 newbase -#define lJ3 fp_equal( -#define lI3 branch1op -#define lH3 branch2op -#define lG3 if(lJ3 -#define lF3 l8 a)xI -#define lE3 overlap -#define lD3 truth_b -#define lC3 truth_a -#define lB3 found_dup -#define lA3 nQ r;r iH -#define l93 void set( -#define l83 {tP1 lE -#define l73 rangeutil -#define l63 Plan_Has( -#define l53 StackMax) -#define l43 i1 true;} -#define l33 namespace -#define l23 (cond yX -#define l13 inverted -#define l03 xX3: -#define iZ2 iftree -#define iY2 depcodes -#define iX2 explicit -#define iW2 cCosh nS -#define iV2 t01 nH -#define iU2 VarBegin -#define iT2 t63 a] -#define iS2 iR2 size() -#define iR2 Params. -#define iQ2 ].data); -#define iP2 i8)));nZ -#define iO2 yQ1.SubTrees -#define iN2 yQ1.Others -#define iM2 );synth -#define iL2 ;DumpTree( -#define iK2 ;Value_t -#define iJ2 begin(), -#define iI2 cond_add -#define iH2 cond_mul -#define iG2 cond_and -#define iF2 IsAlways -#define iE2 func lQ1 -#define iD2 bool eM1 -#define iC2 Forget() -#define iB2 .second); -#define iA2 Optimize() -#define i92 costree -#define i82 sintree -#define i72 leaf_count -#define i62 &&cond eD) -#define i52 .tT1 n] -#define i42 =GetParam( -#define i32 sub_params -#define i22 nC==cLog2&& -#define i12 nC==cPow&& -#define i02 printf( -#define tZ2 cbrt_count -#define tY2 sqrt_count -#define tX2 cPow i7 -#define tW2 ,cPow, -#define tV2 ,cGreater -#define tU2 exponent); -#define tT2 Finite -#define tS2 min.n3 0), -#define tR2 p1 cS ifp1 -#define tQ2 yR 2,cAdd) -#define tP2 pcall_tree -#define tO2 after_powi -#define tN2 GetHash(). -#define tM2 yP t23 -#define tL2 params) -#define tK2 grammar -#define tJ2 cEqual t11 -#define tI2 cLog nS -#define tH2 cNeg,lT 1, -#define tG2 ),0},{ -#define tF2 std::move( -#define tE2 iH cond nC -#define tD2 tree iH -#define tC2 ){eL3 -#define tB2 tree))cJ -#define tA2 );t0=!t0;} -#define t92 tmp c91 tree -#define t82 nQ tmp;tmp iH -#define t72 tree nC -#define t62 MakeNEqual -#define t52 )?0:1))l7 -#define t42 isInteger( -#define t32 Comparison -#define t22 needs_flip -#define t12 (half&63)-1; -#define t02 value] -#define eZ2 lT1 opcode -#define eY2 )lS 3*3*3*2 -#define eX2 cS tree); -#define eW2 mul_item -#define eV2 innersub -#define eU2 cbrt_cost -#define eT2 best_cost -#define eS2 condition -#define eR2 nominator -#define eQ2 per_item -#define eP2 item_type -#define eO2 first2 -#define eN2 l4 18,1, -#define eM2 cIf,iX 3, -#define eL2 lJ 1},0, -#define eK2 tJ 1},0, -#define eJ2 Decision -#define eI2 not_tree -#define eH2 (mulgroup -#define eG2 (lR));nD lC -#define eF2 Become(xW -#define eE2 group_by -#define eD2 exponent= -#define eC2 ->second -#define eB2 targetpos -#define eA2 ParamSpec -#define e92 rhs.hash2;} -#define e82 rhs.hash1 -#define e72 struct -#define e62 Value_t( -#define e52 .n_int_sqrt -#define e42 const std::eP -#define e32 const char* -#define e22 nT 409641, -#define e12 ,xF1);lC -#define e02 );xY3 -#define cZ2 if(t72== -#define cY2 eO3 bool> -#define cX2 ,(long double) -#define cW2 ContainsOtherCandidates -#define cV2 std::cout -#define cU2 source_tree -#define cT2 GetParam eS -#define cS2 -#define cR2 p1_evenness -#define cQ2 isNegative( -#define cP2 neg_set -#define cO2 }else{x8=new -#define cN2 );}void -#define cM2 cNop,cNop}} -#define cL2 cTanh,cNop, -#define cK2 NewHash -#define cJ2 >e72 cB< -#define cI2 matches -#define cH2 {cV2<< -#define cG2 iS1 void*)& -#define cF2 cGreater,cH -#define cE2 cSin i7 -#define cD2 cCos nS -#define cC2 ,t21 0x1 nH -#define cB2 +=1 i1 n91; -#define cA2 negated -#define c92 synth); -#define c82 Specializer -#define c72 ifdata.ofs -#define c62 (IfData&ifdata -#define c52 .push_back( -#define c42 ;}data;data. -#define c32 );sim.x2 2, -#define c22 nP)l14 tmp= -#define c12 (*x8)[0].info -#define c02 CodeTree -#define yZ2 c02 xF -#define yY2 coshtree -#define yX2 sinhtree -#define yW2 best_score -#define yV2 mulvalue -#define yU2 pow_item -#define yT2 subgroup -#define yS2 PowiResult -#define yR2 .match_tree -#define yQ2 )l43 -#define yP2 0));yD3 -#define yO2 maxValue -#define yN2 minValue -#define yM2 yI eW3 if( -#define yL2 fp_min(yL, -#define yK2 div_tree -#define yJ2 pow_tree -#define yI2 preserve -#define yH2 ,cCos i7 -#define yG2 (rule cU3,info -#define yF2 e62 0.5) -#define yE2 PullResult() -#define yD2 dup_or_fetch -#define yC2 e33 false -#define yB2 test_order -#define yA2 lX3, -#define y92 .param_count -#define y82 shift(index) -#define y72 rulenumber -#define y62 cTanh nS -#define y52 cSinh nS -#define y42 cInv,lT 1, -#define y32 constraints= -#define y22 factor_immed -#define y12 changes -#define y02 n81 cS y4 l8 -#define xZ2 cS leaf2 l8 -#define xY2 cS x53 l8 -#define xX2 cS cond l8 -#define xW2 exp_diff -#define xV2 ExponentInfo -#define xU2 lower_bound( -#define xT2 factor -#define xS2 is_logical -#define xR2 newrel_and -#define xQ2 tH[c eE -#define xP2 ;iM.Remember( -#define xO2 i1 Unknown;} -#define xN2 res_stackpos -#define xM2 half_pos -#define xL2 >>1)):( -#define xK2 CodeTreeData -#define xJ2 multiply( -#define xI2 tO known) -#define xH2 var_trees -#define xG2 erase(cs_it); -#define xF2 parent_opcode -#define xE2 log2_exponent -#define xD2 yB swap(tmp); -#define xC2 Value(Value:: -#define xB2 dup_fetch_pos -#define xA2 a;if(eK1){x8= -#define x92 {cZ start_at; -#define x82 xX3 cQ lC -#define x72 cSin nS -#define x62 Value_EvenInt -#define x52 )){data xC -#define x42 MakeFalse,{l5 -#define x32 if(list.first -#define x22 AddCollection -#define x12 ConditionType -#define x02 DUP_ONE(apos) -#define nZ2 SpecialOpcode -#define nY2 =i eC2. -#define nX2 IsDefined() -#define nW2 fp_max(yL); -#define nV2 (tree,cV2 -#define nU2 e62-1) -#define nT2 assimilated -#define nS2 denominator -#define nR2 fraction -#define nQ2 l2 18,2, -#define nP2 .GetDepth() -#define nO2 iH t72) -#define nN2 xI leaf2 l8 -#define nM2 DUP_BOTH(); -#define nL2 x73 lL -#define nK2 -1-offset]. -#define nJ2 tree.GetHash() -#define nI2 TreeCounts -#define nH2 ,e62 1))){ -#define nG2 bool t0 eW3 -#define nF2 found_log2 -#define nE2 div_params -#define nD2 immed_sum -#define nC2 :sim.Eat(1, -#define nB2 OPCODE(opcode) -#define nA2 ;sim.Push( -#define n92 break;nS3*= -#define n82 FactorStack xF -#define n72 iF2 cQ lC -#define n62 cLessOrEq, -#define n52 282870 nT -#define n42 cNotNot nS -#define n32 cNot nS -#define n22 replacing_slot -#define n12 RefParams -#define n02 if_always[ -#define lZ2 WhatDoWhenCase -#define lY2 exponent_immed -#define lX2 new_base_immed -#define lW2 base_immed -#define lV2 ||op1== -#define lU2 remaining -#define lT2 Rehash t8 -#define lS2 data[a eI3 -#define lR2 lT2 r);} -#define lQ2 if(newrel_or== -#define lP2 .UseGetNeeded( -#define lO2 e7 2,131, -#define lN2 Immed eJ3); -#define lM2 OptimizedUsing -#define lL2 Var_or_Funcno -#define lK2 lL2; -#define lJ2 GetParams( -#define lI2 crc32_t -#define lH2 signed_chain -#define lG2 MinusInf -#define lF2 synth.Find( -#define lE2 );cV2<< -#define lD2 return true; -#define lC2 n_immeds -#define lB2 stack eJ3 -#define lA2 FindClone(xM -#define l92 GetOpcode()) -#define l82 needs_rehash -#define l72 AnyWhere_Rec -#define l62 minimum_need -#define l52 ~x83(0) -#define l42 41,42,43,44, -#define l32 p1_logical_b -#define l22 p0_logical_b -#define l12 p1_logical_a -#define l02 p0_logical_a -#define iZ1 (size_t -#define iY1 )e73 -#define iX1 TopLevel) -#define iW1 .e33) -#define iV1 {pow.CopyOnWrite -#define iU1 nB OPCODE -#define iT1 const yZ2 -#define iS1 (const -#define iR1 iS1 yZ2& -#define iQ1 ,PowiCache&iM, -#define iP1 else if( -#define iO1 iP1!nS3 -#define iN1 synth.DoDup( -#define iM1 cache_needed -#define iL1 e7 2,1,e7 2, -#define iK1 [c72+ -#define iJ1 treelist -#define iI1 IsDescendantOf( -#define iH1 has_bad_balance -#define iG1 )tN mulgroup) -#define iF1 .SetParamsMove( -#define iE1 cO3 xT2 -#define iD1 double)exponent -#define iC1 {if(GetOpcode() -#define iB1 cV2<(e62 1), -#define tG1 nL3) -#define tF1 )lX3.second -#define tE1 e62 0.0)){nU -#define tD1 .IsImmed() -#define tC1 a)tD1) -#define tB1 nB2); -#define tA1 stack[lB2- -#define t91 stack c52 -#define t81 )eX3 iW1; -#define t71 synth.PushImmed( -#define t61 MaxChildDepth -#define t51 repl_param_list, -#define t41 const Rule&rule, -#define t31 std::pair -#define t21 cPow,lA -#define t11 ,l0 2, -#define t01 ,l1 0x12 -#define eZ1 Sign_Negative -#define eY1 Value_Logical -#define eX1 yZ2&b -#define eW1 new_factor_immed -#define eV1 occurance_pos -#define eU1 exponent_hash -#define eT1 exponent_list -#define eS1 CollectionSet xF -#define eR1 CollectMulGroup( -#define eQ1 source_set -#define eP1 exponent,y63 -#define eO1 *const func)( -#define eN1 ByteCode -#define eM1 operator -#define eL1 FindAndDup(tree); -#define eK1 &*start_at -#define eJ1 <first== -#define cW1 return BecomeZero; -#define cV1 =comp.AddItem(atree -#define cU1 return BecomeOne; -#define cT1 if(lQ eJ3<=n1) -#define cS1 addgroup -#define cR1 found_log2by -#define cQ1 nC==cC3) -#define cP1 ParsePowiMuli( -#define cO1 lL2) -#define cN1 eL 529654 nT -#define cM1 branch1_backup -#define cL1 branch2_backup -#define cK1 exponent_map -#define cJ1 plain_set -#define cI1 rangehalf -#define cH1 LightWeight( -#define cG1 xV3 1 -#define cF1 divgroup -#define cE1 ,iM e63 -#define cD1 if(value -#define cC1 tK1 c0 -#define cB1 tK1 static -#define cA1 mulgroup. -#define c91 .AddParamMove( -#define c81 yB AddParamMove( -#define c71 ;n81 cY op1 yB DelParams -#define c61 should_regenerate=true; -#define c51 should_regenerate, -#define c41 Collection -#define c31 RelationshipResult -#define c21 Subdivide_Combine( -#define c11 long value -#define c01 )const yP -#define yZ1 rhs c01 hash1 -#define yY1 for iZ1 a xY -#define yX1 best_sep_factor -#define yW1 SynthesizeParam -#define yV1 needlist_cached -#define yU1 inline x83 -#define yT1 opcode,bool pad -#define yS1 changed=true; -#define yR1 );xM iF1 -#define yQ1 NeedList -#define yP1 tK1 bool -#define yO1 ;tK1 -#define yN1 i91 a);} -#define yM1 MakesInteger( -#define yL1 const Value_t&value -#define yK1 best_sep_cost -#define yJ1 MultiplicationRange -#define yI1 .min.set(fp_floor); -#define yH1 pihalf_limits -#define yG1 yR 2,cMul);lC -#define yF1 n_stacked -#define yE1 cK2.hash1 -#define yD1 AnyParams_Rec -#define yC1 ;synth.StackTopIs( -#define yB1 synth.AddOperation( -#define yA1 continue; -#define y91 Become(value l8 0)) -#define y81 }inline -#define y71 PositionalParams,0} -#define y61 always_sincostan -#define y51 Recheck_RefCount_Div -#define y41 Recheck_RefCount_Mul -#define y31 MultiplyAndMakeLong( -#define y21 covers_plus1 -#define y11 endl;DumpHashes( -#define y01 if(synth.FindAndDup( -#define xZ1 grammar_func -#define xY1 tree tD1 cQ -#define xX1 cOr l3 16,1, -#define xW1 252421 nT 24830, -#define xV1 l2 0,2,165888 nT -#define xU1 Modulo_Radians}, -#define xT1 yB SetParam( -#define xS1 PositionType -#define xR1 CollectionResult -#define xQ1 const_offset -#define xP1 inline TriTruthValue -#define xO1 stacktop_desired -#define xN1 iU3);lC -#define xM1 SetStackTop( -#define xL1 tK1 void -#define xK1 FPoptimizer_ByteCode -#define xJ1 1)?(poly^( -#define xI1 eP3&synth) -#define xH1 e62 0) -#define xG1 xH1) -#define xF1 cond_type -#define xE1 fphash_value_t -#define xD1 Recheck_RefCount_RDiv -#define xC1 cMul);tmp tY3 tmp. -#define xB1 SwapLastTwoInStack(); -#define xA1 SetParams(lJ2) -#define x91 fPExponentIsTooLarge( -#define x81 CollectMulGroup_Item( -#define x71 pair -#define x61 (x53 l8 1)nN2 -#define x51 for iZ1 a=0;a& -#define nN1 tP1 x93 -#define nM1 has_good_balance_found -#define nL1 n_occurrences -#define nK1 found_log2_on_exponent -#define nJ1 covers_minus1 -#define nI1 needs_resynth -#define nH1 immed_product -#define nG1 l33 FPoptimizer_Optimize -#define nF1 (ParamSpec_Extract xF( -#define nE1 yV3 bitmask& -#define nD1 Sign_Positive -#define nC1 ::MakeTrue -#define nB1 SetParamMove( -#define nA1 CodeTreeImmed(e62 -#define n91 Suboptimal -#define n81 changed_if -#define n71 n_as_tanh_param -#define n61 opposite= -#define n51 xE1( -#define n41 eN1 eJ3 -#define n31 MatchResultType -#define n21 yP yZ2( -#define n11 needs_sincos -#define n01 resulting_exponent -#define lZ1 Unknown:yF3;} -#define lY1 GetLogicalValue(xW -#define lX1 GetParam(a) -#define lW1 cMul l3 0,1, -#define lV1 IsImmed())l14 -#define lU1 void FunctionParserBase -#define lT1 (x83 -#define lS1 lT1 a=0;a0;) -#define l31 PositionalParams_Rec -#define l21 DumpTreeWithIndent(*this); -#define l11 e23 type){case cond_or: -#define l01 tP1 x83 Compare> -#define iZ tree.i91 a -#define iY .l91 a-->0;)if( -#define iX lA 0x4},{{ -#define iW lJ 2 i41 1, -#define iV edited_powgroup -#define iU has_unknown_max -#define iT has_unknown_min -#define iS static const yD3 -#define iR if(keep_powi -#define iQ synthed_tree -#define iP 7168 nT 401798, -#define iO SelectedParams,0 i41 -#define iN collections -#define iM cache -#define iL ,cIf,l0 3, -#define iK ,eN1,IP,limit,y2,stack); -#define iJ by_exponent -#define iI );p2.lT2 p2 yB eL3 iZ2 nC);cJ} -#define iH .eL3 -#define iG mulgroup;mulgroup iH -#define iF (p0 e61&&p0 nL3 i2 -#define iE cN3 p0 yM>=e62 0.0)) -#define iD goto ReplaceTreeWithOne t83 -#define iC !=xJ)return n02 -#define iB e01.data -#define iA iX2 xK2( -#define i9 needs_sinhcosh -#define i8 1)x41 -#define i7 ,l4 2,1, -#define i6 cAdd l3 0, -#define i5 tG2 e62 -#define i4 tK1 n9 -#define i3 MakeFalse,l5:: -#define i2 <=fp_const_negativezero xF()) -#define i1 ;return -#define i0 )i1 lH -#define tZ CalculateResultBoundaries(xW -#define tY p0=CalculateResultBoundaries( -#define tX ;yZ2 -#define tW ,2,1 iM2.xR if(found[data. -#define tV 408964 nT 24963, -#define tU 528503 nT 24713, -#define tT matched_params -#define tS [n1 eH3=true;lQ[n1 eI3 -#define tR lA1::Grammar* -#define tQ AddOperation(cInv,1,1 iM2.xR} -#define tP int_exponent_t -#define tO m.max. -#define tN ;AddParamMove( -#define tM nM nU2,e62 1)); -#define tL cG3 eW3 -#define tK return m;}case -#define tJ x9 AnyParams, -#define tI powgroup l8 -#define tH relationships -#define tG ]!=~size_t(0)){synth.yT -#define tF }},{ProduceNewTree,2,1, -#define tE nA1( -#define tD has_mulgroups_remaining -#define tC MatchInfo xF& -#define tB e33);i32 c52 -#define tA best_factor -#define t9 RootPowerTable xF::RootPowers[ -#define t8 (c81 -#define t7 :goto ReplaceTreeWithZero t83 -#define t6 MatchPositionSpec_AnyParams xF -#define t5 l33 FPoptimizer_CodeTree -#define t4 n_as_sinh_param -#define t3 n_as_cosh_param -#define t2 ();pow iH cLog yB eL3 cMul -#define t1 0,tU2 i91 1); -#define t0 is_signed -#define eZ result_positivity -#define eY biggest_minimum -#define eX const l71 -#define eW 122999 nT 139399, -#define eV 142455 nT 141449, -#define eU cond_tree -#define eT then_tree -#define eS (a);bool needs_cow=GetRefCount()>1; -#define eR yZ2&tree) -#define eQ sequencing -#define eP string FP_GetOpcodeName( -#define eO );eN1 c52 0x80000000u -#define eN {if(needs_cow){lD1 goto -#define eM (lJ2));cA1 e33); -#define eL ,nQ2 -#define eK eO3 yZ2> -#define eJ if_stack -#define eI n_as_sin_param -#define eH n_as_cos_param -#define eG PowiResolver:: -#define eF cIf,tG3 -#define eE ].relationship -#define eD .BalanceGood -#define eC AddParamMove(yT2 -#define eB valueType -#define eA back().endif_location -#define e9 xE1 key -#define e8 AddParamMove(mul); -#define e7 130,1, -#define e6 MatchPositionSpecBase -#define e5 iX2 c02( -#define e4 smallest_maximum -#define e3 ]!=~size_t(0)&&found[data. -#define e2 }PACKED_GRAMMAR_ATTRIBUTE; -#define e1 ReplaceTreeWithParam0; -#define e0 factor_needs_rehashing -#define cZ MatchPositionSpecBaseP -#define cY .e33 yB eL3 -#define cX x93 tJ1::y83 -#define cW ParamSpec_Extract xF(nN.param_list, -#define cV }x32 x41==e62 -#define cU 243,244,245,246,249,250,251,253,255,256,257,258,259}};} -#define cT ];};extern"C"{ -#define cS .AddParam( -#define cR iL2 tree lE2"\n"; -#define cQ )return false; -#define cP 79,122,123,160,161,163,164,165,166,167,168,169,178,179,180,200,204,212,216,224,236,237,239,240, -#define cO 27,28,29,30,31,32,33,35,36, -#define cN const ParamSpec_SubFunction -#define cM const ParamSpec_ParamHolder -#define cL otherhalf -#define cK :{AdoptChildrenWithSameOpcode(tree); -#define cJ goto redo; -#define cI StackState -#define cH l2 16,2, -#define cG const SequenceOpCode xF -#define cF MatchPositionSpec_PositionalParams xF -#define cE const nP1 std::ostream&o -#define cD e62 1.5)*fp_const_pi xF() -#define cC CalculatePowiFactorCost( -#define cB ImmedHashGenerator -#define cA paramholder_matches -#define c9 ::map > -#define c8 ComparisonSetBase:: -#define c7 AddParamMove(comp.cJ1[a].value); -#define c6 T1,x93 T2>inline iD2()( -#define c5 has_nonlogical_values -#define c4 from_logical_context) -#define c3 AnyParams,0}},{ProduceNewTree, -#define c2 for iZ1 a=xV.l91 a-->0;) -#define c1 POWI_CACHE_SIZE -#define c0 static inline yZ2 -#define yZ ++IP;yA1}if(n13 c33. -#define yY },{l5::xJ,l5::Never},{l5::xJ,l5::Never}} -#define yX .FoundChild -#define yW BalanceResultType -#define yV {yZ2 tmp;tmp iH -#define yU yB1 GetOpcode(), -#define yT DoDup(found[data. -#define yS xB3(0),Opcode( -#define yR ;sim.Eat( -#define yQ );void nR1 eZ2,c82< -#define yP {return -#define yO const yP data-> -#define yN +=fp_const_twopi xF(); -#define yM .min.val -#define yL fp_sin(min),fp_sin(max)) -#define yK fp_const_twopi xF());if( -#define yJ {yZ2 tmp,tmp2;tmp2 iH -#define yI .min.known -#define yH for iZ1 a=0;aParams -#define y0 (lW3 r=range.first;r!=range.i63++r){ -#define xZ {nI2.erase(i);yA1} -#define xY =0;a -#define xE cE=cV2 -#define xD best_selected_sep -#define xC ->Recalculate_Hash_NoRecursion();} -#define xB l91++a)if(ApplyGrammar(tK2,xW a), -#define xA lU3 2,1, -#define x9 ,cAdd, -#define x8 position -#define x7 x51{yD3 -#define x6 ;tmp2 tY3 tmp iH cInv);tmp c91 tmp2)i1 -#define x5 eO3 c02> -#define x4 SetParam(0,iZ2 l8 0))tX p1;p1 iH -#define x3 TestImmedConstraints yZ3 constraints cU3)cQ -#define x2 SwapLastTwoInStack()yR -#define x1 n23 1,cInv e02 xG-1 xN1 -#define x0 paramholder_index -#define nZ lD2 case -#define nY occurance_counts -#define nX );a-->0;){iT1&powgroup=lX1;if(powgroup -#define nW )){tree.tE3;} -#define nV Value_t>p=tZ a));if(p. -#define nU tree.ReplaceWithImmed( -#define nT ,{2, -#define nS ,l0 1, -#define nR ,cAdd l3 2,1, -#define nQ ){yZ2 -#define nP if(xW 0)tD1 -#define nO const FPoptimizer_CodeTree::yZ2&tree -#define nN model_tree -#define nM return yD3( -#define nL ){using l33 FUNCTIONPARSERTYPES; -#define nK eK&n12 -#define nJ AddParam(xW -#define nI ConstantFolding_LogicCommon(tree,c8 -#define nH },{{2, -#define nG nN1 Ref>inline void xP:: -#define nF AnyParams,1 i41 -#define nE ):data(new xK2 xF( -#define nD goto do_return;} -#define nC .GetOpcode() -#define nB FUNCTIONPARSERTYPES:: -#define nA b;}};tP1>e72 Comp(e62 -#define n2 DumpParams xF yZ3 data.param_list,iH3 y92,o); -#define n1 restholder_index -#define n0 yZ2 exponent eX3 iH cMul)eX3 cS -#define lZ lR);if(fp_nequal(tmp,xG1){nU e62 1)/tmp);nD}lC -#define lY :if(ParamComparer xF()(t63 1],t63 0])){std::swap(t63 0],t63 1]);Opcode= -#define lX -#define lW xF tmp;tmp iH cPow);tmp tY3 tmp.yA e62 -#define lV i01,0x0}, -#define lU AddParamMove(pow l8 1));pow.i91 1);pow.e33 yB nB1 0,pow);goto NowWeAreMulGroup;} -#define lT GroupFunction,0},lV{{ -#define lS ,e62 1)/e62 -#define lR xW 0)x41 -#define lQ restholder_matches -#define lP yE1|=key;xE1 crc=(key>>10)|(key<<(64-10))lL1((~n51 crc))*3)^1234567;}}; -#define lO n81;n81 nO2;n81 c91 xW 0));n81 cS xV l8 -#define lN tK1 yZ2::c02( -#define lM tree.SetParam(0,xW 0)l8 0)xT1 1,CodeTreeImmed( -#define lL lX void eP3::nR1 eZ2,c82< -#define lK cMul,lT 2, -#define lJ cMul,AnyParams, -#define lI (xW 0)tD1&&xW 1)tD1){nU -#define lH CalculateResultBoundaries(tmp);}case -#define lG :cY3=comp.AddRelationship(atree l8 0),atree l8 1),c8 -#define lF cPow,l0 2 -#define lE x93 Value_t>inline iD2()iS1 Value_t&xC3 Value_t&b)yP a -#define lD {yD3 m=tZ 0)); -#define lC break t83 -#define lB xL1 yZ2:: -#define lA y71,0, -#define l9 l1 0x0 nH -#define l8 .GetParam( -#define l7 tX n81;n81 nO2;n81 iF1 tree.lJ2));n81 cY -#define l6 SelectedParams,0},0,0x0 nH -#define l5 RangeComparisonData -#define l4 y71},{ProduceNewTree, -#define l3 ,AnyParams,0}},{ReplaceParams, -#define l2 y71},{ReplaceParams, -#define l1 cMul,SelectedParams,0},0, -#define l0 lA 0x0},{{ -#ifdef _MSC_VER -typedef -x83 -int -lI2; -#else -#include -typedef -uint_least32_t -lI2; -#endif -l33 -crc32{enum{startvalue=0xFFFFFFFFUL,poly=0xEDB88320UL} -;tP1 -lI2 -crc>e72 -b8{enum{b1=(crc&xJ1 -crc -xL2 -crc>>1),b2=(b1&xJ1 -b1 -xL2 -b1>>1),b3=(b2&xJ1 -b2 -xL2 -b2>>1),b4=(b3&xJ1 -b3 -xL2 -b3>>1),b5=(b4&xJ1 -b4 -xL2 -b4>>1),b6=(b5&xJ1 -b5 -xL2 -b5>>1),b7=(b6&xJ1 -b6 -xL2 -b6>>1),res=(b7&xJ1 -b7 -xL2 -b7>>1)} -;} -;inline -lI2 -update(lI2 -crc,x83 -b){ -#define B4(n) b8nP3 n+1>nP3 n+2>nP3 n+3>::res -#define R(n) B4(n),B4(n+4),B4(n+8),B4(n+12) -static -const -lI2 -table[256]={R(0x00),R(0x10),R(0x20),R(0x30),R(0x40),R(0x50),R(0x60),R(0x70),R(0x80),R(0x90),R(0xA0),R(0xB0),R(0xC0),R(0xD0),R(0xE0),R(0xF0)} -; -#undef R -#undef B4 -return((crc>>8))^table[(crc^b)&0xFF];y81 -lI2 -calc_upd(lI2 -c,const -x83 -char*buf,size_t -size){lI2 -value=c -eK3 -p=0;pclass -xP{e43 -xP():p(0){} -xP(Ref*b):p(b){xA3} -xP -iS1 -xP&b):p(b.p){xA3 -y81 -Ref&eM1*(c01*p;y81 -Ref*eM1->(c01 -p;} -xP&eM1=(Ref*b){Set(b)i1*this;} -xP&eM1=iS1 -xP&b){Set(b.p)i1*this;} -#ifdef __GXX_EXPERIMENTAL_CXX0X__ -xP(xP&&b):p(b.p){b.p=0;} -xP&eM1=(xP&&b){if(p!=b.p){iC2;p=b.p;b.p=0;eE3*this;} -#endif -~xP(){Forget(cN2 -UnsafeSetP(Ref*newp){p=newp;} -void -swap(xP&b){Ref*tmp=p;p=b.p;b.p=tmp;} -private:inline -static -void -Have(Ref*p2);inline -void -iC2;inline -void -xA3 -inline -void -Set(Ref*p2);private:Ref*p;} -;nG -iC2{if(!p)return;p->xB3-=1;if(!p->xB3)delete -p;} -nG -Have(Ref*p2){if(p2)++(p2->xB3);} -nG -Birth(){Have(p);} -nG -Set(Ref*p2){Have(p2);iC2;p=p2;} -#endif -#include -e72 -Compare2ndRev{nN1 -T>inline -iD2()iS1 -T&xC3 -T&b -c01 -a.second>b.i63} -} -;e72 -Compare1st{nN1 -c6 -const -nO1 -xC3 -nO1 -b -c01 -a.first -typedef -uint_fast64_t -xE1; -#define FPHASH_CONST(x) x##ULL -#endif -l33 -FUNCTIONPARSERTYPES{e72 -fphash_t{xE1 -hash1,hash2;fphash_t():hash1(0),hash2(0){} -fphash_t -iS1 -xE1&xC3 -xE1&b):hash1(a),hash2(b){} -iD2==iS1 -fphash_t&yZ1==e82&&hash2==e92 -iD2!=iS1 -fphash_t&yZ1!=e82||hash2!=e92 -iD2 -#include -l33 -lA1{e72 -Grammar;} -l33 -xK1{tK1 -class -ByteCodeSynth;} -t5{tK1 -class -c02 -yO1 -e72 -xK2 -yO1 -class -c02{typedef -xPDataP;DataP -data;e43 -c02();~c02();e72 -OpcodeTag{} -;e5 -iU1 -o,OpcodeTag);e72 -FuncOpcodeTag{} -;e5 -iU1 -o,x83 -f,FuncOpcodeTag);e72 -xD3{} -;e5 -tV1,xD3); -#ifdef __GXX_EXPERIMENTAL_CXX0X__ -e5 -Value_t&&v,xD3); -#endif -e72 -VarTag{} -;e5 -x83 -varno,VarTag);e72 -CloneTag{} -;e5 -tW1 -b,CloneTag);void -GenerateFrom -iS1 -x93 -FunctionParserBase -xF::Data&data,bool -keep_powi=false);void -GenerateFrom -iS1 -x93 -FunctionParserBase -xF::Data&data,const -x5&xH2,bool -keep_powi=false);void -SynthesizeByteCode(eO3 -x83>&cT3,std -xM3 -xF&immed,size_t&stacktop_max);void -SynthesizeByteCode(xK1::eP3&synth,bool -MustPopTemps=true)const;size_t -SynthCommonSubExpressions(xK1::xI1 -const;void -SetParams -iS1 -x5&xE3 -SetParamsMove(x5&tO1 -c02 -GetUniqueRef(); -#ifdef __GXX_EXPERIMENTAL_CXX0X__ -void -SetParams(x5&&tO1 -#endif -void -SetParam -iZ1 -which,tW1 -b);void -nB1 -size_t -which,c02&b);void -AddParam(tW1 -param);void -AddParamMove(c02¶m);void -AddParams -iS1 -x5&xE3 -AddParamsMove(x5&xE3 -AddParamsMove(x5&n12,size_t -n22);void -i91 -size_t -index);void -DelParams();void -Become(tW1 -b);inline -size_t -GetParamCount(c01 -lJ2)eJ3;y81 -c02&GetParam -iZ1 -n)yP -lJ2)[n];y81 -tW1 -GetParam -iZ1 -n -c01 -lJ2)[n];y81 -void -eL3 -iU1 -o)iZ3 -Opcode=o;y81 -iU1 -GetOpcode()yO -Opcode;y81 -nB -fphash_t -GetHash()yO -Hash;y81 -const -x5&lJ2 -c01 -y1;y81 -x5&lJ2)yP -y1;y81 -size_t -GetDepth()yO -Depth;y81 -const -Value_t&GetImmed()yO -Value;y81 -x83 -GetVar()yO -lK2 -y81 -x83 -GetFuncNo()yO -lK2 -y81 -bool -IsDefined(c01 -GetOpcode()!=nB -cNop;y81 -bool -IsImmed(c01 -GetOpcode()==nB -cImmed;y81 -bool -IsVar(c01 -GetOpcode()==nB -iU2;y81 -x83 -GetRefCount()yO -xB3;} -void -ReplaceWithImmed(tX1;void -e33 -bool -constantfolding=true);void -Sort();inline -void -Mark_Incompletely_Hashed()iZ3 -Depth=0;y81 -bool -Is_Incompletely_Hashed()yO -Depth==0;y81 -const -tR -GetOptimizedUsing()yO -lM2;y81 -void -SetOptimizedUsing -iS1 -tR -g)iZ3 -lM2=g;} -bool -RecreateInversionsAndNegations(bool -prefer_base2=false);void -tE3;void -swap(c02&b){data.swap(b.data);} -bool -IsIdenticalTo(tW1 -b)const;void -lD1} -yO1 -e72 -xK2{int -xB3;iU1 -Opcode -iK2 -Value;x83 -lK2 -eK -Params;nB -fphash_t -Hash;size_t -Depth;const -tR -lM2;xK2();xK2 -iS1 -xK2&b);iA -iU1 -o);iA -iU1 -o,x83 -f);iA -tX1; -#ifdef __GXX_EXPERIMENTAL_CXX0X__ -iA -Value_t&&i);xK2(xK2&&b); -#endif -bool -IsIdenticalTo -iS1 -xK2&b)const;void -Sort();void -Recalculate_Hash_NoRecursion();private:void -eM1=iS1 -xK2&b);} -yO1 -c0 -CodeTreeImmed(tX1 -n21 -i -y8 -xD3());} -#ifdef __GXX_EXPERIMENTAL_CXX0X__ -cC1 -CodeTreeImmed -cX3&&i)n21 -tF2 -i)y8 -xD3());} -#endif -cC1 -CodeTreeOp(iU1 -opcode)n21 -opcode -y8 -OpcodeTag());} -cC1 -CodeTreeFuncOp(iU1 -opcode,x83 -f)n21 -opcode,f -y8 -FuncOpcodeTag());} -cC1 -CodeTreeVar -lT1 -varno)n21 -varno -y8 -VarTag());} -#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING -xL1 -DumpHashes(xE);xL1 -DumpTree(xE);xL1 -DumpTreeWithIndent(xE,const -eM3&indent="\\" -); -#endif -} -#endif -#endif -#ifndef FPOptimizer_GrammarHH -#define FPOptimizer_GrammarHH -#include -t5{tK1 -class -c02;} -l33 -lA1{enum -ImmedConstraint_Value{ValueMask=0x07,Value_AnyNum=0x0,x62=0x1,Value_OddInt=0x2,i11=0x3,Value_NonInteger=0x4,eY1=0x5} -;enum -ImmedConstraint_Sign{SignMask=0x18,Sign_AnySign=0x00,nD1=0x08,eZ1=0x10,Sign_NoIdea=0x18} -;enum -ImmedConstraint_Oneness{OnenessMask=0x60,Oneness_Any=0x00,Oneness_One=0x20,Oneness_NotOne=0x40} -;enum -ImmedConstraint_Constness{ConstnessMask=0x180,Constness_Any=0x00,i01=0x80,Constness_NotConst=0x100} -;enum -Modulo_Mode{Modulo_None=0,Modulo_Radians=1} -;enum -Situation_Flags{LogicalContextOnly=0x01,NotForIntegers=0x02,OnlyForIntegers=0x04,OnlyForComplex=0x08,NotForComplex=0x10} -;enum -nZ2{NumConstant,ParamHolder,SubFunction} -;enum -ParamMatchingType{PositionalParams,SelectedParams,AnyParams,GroupFunction} -;enum -RuleType{ProduceNewTree,ReplaceParams} -; -#ifdef __GNUC__ -# define PACKED_GRAMMAR_ATTRIBUTE __attribute__((packed)) -#else -# define PACKED_GRAMMAR_ATTRIBUTE -#endif -typedef -std::paireA2 -yO1 -eA2 -ParamSpec_Extract -lT1 -paramlist,lJ1)yO1 -bool -ParamSpec_Compare -iS1 -void*xC3 -void*b,nZ2 -type);x83 -ParamSpec_GetDepCode -iS1 -eA2&b);e72 -ParamSpec_ParamHolder{lJ1:8;x83 -constraints:9;x83 -depcode:15;e2 -tK1 -e72 -ParamSpec_NumConstant -l14 -constvalue;x83 -modulo;} -;e72 -l71{x83 -param_count:2;x83 -param_list:30;iU1 -subfunc_opcode:8;ParamMatchingType -match_type:3;x83 -n1:5;e2 -e72 -ParamSpec_SubFunction{l71 -data;x83 -constraints:9;x83 -depcode:7;e2 -e72 -Rule{RuleType -ruletype:2;x83 -situation_flags:5;x83 -repl_param_count:2+9;x83 -repl_param_list:30;l71 -match_tree;e2 -e72 -Grammar{x83 -rule_count;x83 -short -rule_list[999 -cT -extern -const -Rule -grammar_rules[];} -xL1 -DumpParam -iS1 -eA2&p,std::ostream&o=cV2);xL1 -DumpParams -lT1 -paramlist,x83 -count,std::ostream&o=cV2);} -#endif -#ifndef M_PI -#define M_PI 3.1415926535897932384626433832795 -#endif -#define CONSTANT_POS_INF HUGE_VAL -#define CONSTANT_NEG_INF (-HUGE_VAL) -l33 -FUNCTIONPARSERTYPES{tK1 -inline -Value_t -fp_const_pihalf()yP -fp_const_pi -xF()*yF2;} -tK1 -inline -Value_t -fp_const_twopi()eQ3 -fp_const_pi -xF());nS3 -xO -fp_const_twoe()eQ3 -fp_const_e -xF());nS3 -xO -fp_const_twoeinv()eQ3 -fp_const_einv -xF());nS3 -xO -fp_const_negativezero()yP-Epsilon -xF::value;} -} -#ifdef FP_SUPPORT_OPTIMIZER -#include -#include -#include -nG1{using -l33 -lA1;using -t5;using -l33 -FUNCTIONPARSERTYPES -yO1 -class -MatchInfo{e43 -eO3 -std::pair >lQ;eK -cA;eO3 -x83>tT;e43 -MatchInfo():lQ(),cA(),tT(){} -e43 -bool -SaveOrTestRestHolder -lT1 -n1,eA3&iJ1){cT1{lQ -xF3 -n1+1);lQ -tS=iJ1 -l43 -if(lQ[n1 -eH3==false){lQ -tS=iJ1 -l43 -eA3&found=lQ[n1 -eI3;if(iJ1 -eJ3!=found -eJ3 -cQ -for -iZ1 -a=0;an1&&lQ[n1 -eH3==true;} -eA3&GetRestHolderValues -lT1 -n1)const{static -eA3 -empty_result;cT1 -return -empty_result -i1 -lQ[n1 -eI3;} -const -eO3 -x83>&GetMatchedParamIndexes(c01 -tT;} -void -swap(tC -b){lQ.swap(b.lQ);cA.swap(b.cA);tT.swap(b.tT);} -tC -eM1=iS1 -tC -b){lQ=b.lQ;cA=b.cA;tT=b.tT -i1*this;} -} -;class -e6;typedef -xPcZ;class -e6{e43 -int -xB3;e43 -e6():xB3(0){} -virtual~e6(){} -} -;e72 -n31{bool -found;cZ -specs;n31(bool -f):found(f),specs(){} -n31(bool -f,const -cZ&s):found(f),specs(s){} -} -;xL1 -SynthesizeRule(t41 -nP1 -tC -info)yO1 -n31 -TestParam -iS1 -eA2&yA2 -const -nP1 -const -cZ&start_at,tC -info)yO1 -n31 -TestParams(eX&nN,const -nP1 -const -cZ&start_at,tC -info,bool -iX1 -yO1 -bool -ApplyGrammar -iS1 -Grammar&tK2,FPoptimizer_CodeTree::nP1 -bool -from_logical_context=false);xL1 -ApplyGrammars(FPoptimizer_CodeTree::eR -yO1 -bool -IsLogisticallyPlausibleParamsMatch(eX¶ms,const -eR;} -l33 -lA1{xL1 -DumpMatch(t41 -nO,const -FPoptimizer_Optimize::tC -info,bool -DidMatch,std::ostream&o=cV2);xL1 -DumpMatch(t41 -nO,const -FPoptimizer_Optimize::tC -info,e32 -tO3,std::ostream&o=cV2);} -#endif -#include -e42 -lA1::nZ2 -yT1=false);e42 -iU1 -yT1=false); -#include -#include -#include -#include -using -l33 -lA1;using -l33 -FUNCTIONPARSERTYPES;e42 -lA1::nZ2 -yT1){ -#if 1 -e32 -p=0;e23 -opcode){case -NumConstant:p="NumConstant" -;lC -ParamHolder:p="ParamHolder" -;lC -SubFunction:p="SubFunction" -;xY3 -std::ostringstream -tmp;assert(p);tmp< -#include -#ifndef FP_GENERATING_POWI_TABLE -enum{MAX_POWI_BYTECODE_LENGTH=20} -; -#else -enum{MAX_POWI_BYTECODE_LENGTH=999} -; -#endif -enum{MAX_MULI_BYTECODE_LENGTH=3} -;l33 -xK1{tK1 -class -ByteCodeSynth{e43 -ByteCodeSynth():eN1(),Immed(),cI(),xQ(0),StackMax(0){eN1.xH3 -64);Immed.xH3 -8);cI.xH3 -16 -cN2 -Pull(eO3 -x83>&bc,std -xM3 -xF&imm,size_t&StackTop_max){for -lT1 -a=0;aoffset){cI[xQ -nK2 -first=true;cI[xQ -nK2 -second=tree;} -} -bool -IsStackTop(nO,int -offset=0 -c01(int)xQ>offset&&cI[xQ -nK2 -first&&cI[xQ -nK2 -second -xI -tree);y81 -void -EatNParams -lT1 -eat_count){xQ-=eat_count;} -void -ProducedNParams -lT1 -produce_count){xI3 -produce_count -cN2 -DoPopNMov -iZ1 -eB2,size_t -srcpos -nL -eN1 -c52 -cPopNMov -e53 -eB2 -e53 -srcpos);xM1 -srcpos+1);cI[eB2]=cI[srcpos];xM1 -eB2+1 -cN2 -DoDup -iZ1 -xJ3 -nL -if(xJ3==xQ-1){eN1 -c52 -cDup);} -else{eN1 -c52 -cFetch -e53 -xJ3);} -xI3 -1);cI[xQ-1]=cI[xJ3];} -#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING -tP1 -int>void -Dump(){std::ostream&o=cV2;o<<"Stack state now(" -<0;)if(cI[a -eH3&&cI[a -eI3 -xI -tree -y03 -a -i1~size_t(0);} -bool -Find(nO -c01 -xK3 -tree)!=~size_t(0);} -bool -FindAndDup(nO){size_t -pos=xK3 -tree);if(pos!=~size_t(0)){ -#ifdef DEBUG_SUBSTITUTIONS -cV2<l53{StackMax=xQ;cI -xF3 -l53;} -} -protected:eO3 -x83>eN1;std -xM3 -xF -Immed;eO3 -std::pair >cI;size_t -xQ;size_t -StackMax;private:void -incStackPtr(){if(xQ+2>l53 -cI -xF3 -StackMax=xQ+2);} -tP1 -bool -IsIntType,bool -IsComplexType>e72 -c82{} -;e43 -void -AddOperation -eZ2,x83 -eat_count,x83 -produce_count=1){EatNParams(eat_count);nR1(opcode);ProducedNParams(produce_count -cN2 -nR1 -eZ2,c82yQ -false,true>yQ -true,false>yQ -true,true>);inline -void -nR1 -eZ2){nR1(opcode,c82());} -} -yO1 -e72 -SequenceOpCode -yO1 -e72 -tU1{static -cG -AddSequence;static -cG -MulSequence;} -;xL1 -x01 -long -count,cG&eQ,xI1;} -#endif -#ifdef FP_SUPPORT_OPTIMIZER -using -l33 -FUNCTIONPARSERTYPES;l33 -xK1{tK1 -e72 -SequenceOpCode -l14 -basevalue;x83 -op_flip;x83 -op_normal,op_normal_flip;x83 -op_inverse,op_inverse_flip;} -yO1 -cG -tU1 -xF::AddSequence={xH1,cNeg -x9 -cAdd,cSub,cRSub} -yO1 -cG -tU1 -xF::MulSequence={e62 -1),cInv,cMul,cMul,cDiv,cRDiv} -; -#define findName(a,b,c) "var" -#define TryCompilePowi(o) false -#define mData this -#define mByteCode eN1 -#define mImmed Immed -nL2 -false,false>)x31 -# define FP_FLOAT_VERSION 1 -# define FP_COMPLEX_VERSION 0 -# include "extrasrc/fp_opcode_add.inc" -# undef FP_COMPLEX_VERSION -# undef FP_FLOAT_VERSION -} -nL2 -true,false>)x31 -# define FP_FLOAT_VERSION 0 -# define FP_COMPLEX_VERSION 0 -# include "extrasrc/fp_opcode_add.inc" -# undef FP_COMPLEX_VERSION -# undef FP_FLOAT_VERSION -} -#ifdef FP_SUPPORT_COMPLEX_NUMBERS -nL2 -false,true>)x31 -# define FP_FLOAT_VERSION 1 -# define FP_COMPLEX_VERSION 1 -# include "extrasrc/fp_opcode_add.inc" -# undef FP_COMPLEX_VERSION -# undef FP_FLOAT_VERSION -} -nL2 -true,true>)x31 -# define FP_FLOAT_VERSION 0 -# define FP_COMPLEX_VERSION 1 -# include "extrasrc/fp_opcode_add.inc" -# undef FP_COMPLEX_VERSION -# undef FP_FLOAT_VERSION -} -#endif -#undef findName -#undef mImmed -#undef mByteCode -#undef mData -#undef TryCompilePowi -} -using -l33 -xK1; -#define POWI_TABLE_SIZE 256 -#define POWI_WINDOW_SIZE 3 -l33 -xK1{ -#ifndef FP_GENERATING_POWI_TABLE -extern -const -x83 -char -powi_table[POWI_TABLE_SIZE];const -#endif -x83 -char -powi_table[POWI_TABLE_SIZE]={0,1,1,1,2,1,2,1,xN3 -4,1,2,xP3 -2,1,xN3 -8,cV3 -xQ3 -15,1,16,1,2,1,4,1,2,xP3 -2,1,4,cV3 -1,16,1,25,xQ3 -27,5,8,3,2,1,30,1,31,3,32,1,2,1,xN3 -8,1,2,xQ3 -39,1,16,137,2,1,4,cV3 -xP3 -45,135,4,31,2,5,32,1,2,131,50,1,51,1,8,3,2,1,54,1,55,3,16,1,57,133,4,137,2,135,60,1,61,3,62,133,63,1,iL1 -131,iL1 -139,lO2 -e7 -30,1,130,137,2,31,lO2 -e7 -e7 -130,cV3 -1,e7 -e7 -2,1,130,133,iL1 -61,130,133,62,139,130,137,e7 -lO2 -e7 -e7 -iL1 -131,e7 -e7 -130,131,2,133,lO2 -130,141,e7 -130,cV3 -1,e7 -5,135,e7 -lO2 -e7 -lO2 -130,133,130,141,130,131,e7 -e7 -2,131} -;} -static -x03 -c1=256; -#define FPO(x) -l33{class -PowiCache{private:int -iM[c1];int -iM1[c1];e43 -PowiCache():iM(),iM1(){iM[1]=1;} -bool -Plan_Add(c11,int -count){cD1>=c1 -cQ -iM1[t02+=count -i1 -iM[t02!=0;} -void -l63 -c11){cD1=0){FPO(iC3(iG3,"* I found %ld from cache (%u,%d)\n",value,(unsigned)cache[value],iD3 value]))i1 -iM[t02;} -eE3-1;} -void -Remember(c11,size_t -iQ3){cD1>=c1)return;FPO(iC3(iG3,"* Remembering that %ld can be found at %u (%d uses remain)\n",value,(unsigned)iQ3,iD3 value]));iM[t02=(int)iQ3;} -void -DumpContents()const{FPO(for(int a=1;a=0||iD3 a]>0){iC3(iG3,"== cache: sp=%d, val=%d, needs=%d\n",cache[a],a,iD3 a]);})} -int -UseGetNeeded(c11){cD1>=0&&value32)throw -false; -#endif -if(iM.Plan_Add(value,need_count -y03;long -xR3 -1;cD1cL||half<0)std::swap(half,cL);FPO(iC3(iG3,"value=%ld, half=%ld, otherhalf=%ld\n",value,half,otherhalf))xZ3==cL){lB1 -half,iM,2,lC1+1);} -else{lB1 -half -xO3 -lB1 -cL>0?cL:-cL -xO3} -iM.l63 -value);} -tK1 -size_t -y6 -c11 -iQ1 -cG&eQ,xI1{int -xT3=iM.Find(value);if(xT3>=0)yP -xT3;} -long -xR3 -1;cD10||xM2!=cG1){iN1 -xM2)xP2 -half,cG1);} -x01 -value/half -e63 -size_t -iQ3=cG1 -xP2 -value,iQ3);iM.DumpContents()i1 -iQ3;} -iP1 -half&64){xR3-t12} -} -else -cD1&1)xR3 -value&((1<cL||half<0)std::swap(half,cL);FPO(iC3(iG3,"* I want %ld, my plan is %ld + %ld\n",value,half,value-half))xZ3==cL){size_t -xM2=y6 -half -cE1 -c21 -xM2,half,xM2,half,iM,eQ.op_normal,eQ.op_normal_flip,c92} -else{long -part1=half;long -part2=cL>0?cL:-cL;size_t -part1_pos=y6 -part1 -cE1 -size_t -part2_pos=y6 -part2 -cE1 -FPO(iC3(iG3,"Subdivide(%ld: %ld, %ld)\n",value,half,otherhalf));c21 -part1_pos,part1,part2_pos,part2,iM,cL>0?eQ.op_normal:eQ.op_inverse,cL>0?eQ.op_normal_flip:eQ.op_inverse_flip,c92} -size_t -iQ3=cG1 -xP2 -value,iQ3);iM.DumpContents()i1 -iQ3;} -xL1 -c21 -size_t -apos,long -aval,size_t -bpos,long -bval -iQ1 -x83 -cumulation_opcode,x83 -cumulation_opcode_flip,xI1{int -a_needed=iM -lP2 -aval);int -xU3=iM -lP2 -bval);bool -flipped -eW3 -#define DUP_BOTH() do{if(apos " iO3 iO3"op\n",(unsigned)apos,(unsigned)bpos));iN1 apos);iN1 apos==bpos?cG1:bpos);}while(0) -#define DUP_ONE(p) do{FPO(iC3(iG3,"-> " iO3"op\n",(unsigned)p));iN1 p);}while(0) -if(a_needed>0){if(xU3>0){nM2} -cJ3 -bpos!=cG1)nM2 -else{x02 -e41} -} -iP1 -xU3>0){if(apos!=cG1)nM2 -else -DUP_ONE(bpos);} -cJ3 -apos==bpos&&apos==cG1)x02;iP1 -apos==cG1&&bpos==xV3 -2){FPO(iC3(iG3,"-> op\n"))e41 -iP1 -apos==xV3 -2&&bpos==cG1)FPO(iC3(iG3,"-> op\n"));iP1 -apos==cG1)DUP_ONE(bpos);iP1 -bpos==cG1){x02 -e41 -else -nM2} -yB1 -flipped?cumulation_opcode_flip:cumulation_opcode,2);} -xL1 -cH1 -long -count,cG&eQ,xI1{while -cW3<256){int -xR3 -xK1::powi_table[count]xZ3&128){half&=127;cH1 -half -e63 -count/=half;} -else -xY3 -if -cW3==1)return;if(!cW3&1)){yB1 -cSqr,1);cH1 -count/2 -e63} -else{iN1 -cG1);cH1 -count-1 -e63 -yB1 -cMul,2);} -} -} -l33 -xK1{xL1 -x01 -long -count,cG&eQ,xI1{if -cW3==0)t71 -eQ.basevalue);else{bool -t22 -eW3 -if -cW3<0){t22=true;count=-count;} -if(false)cH1 -count -e63 -iP1 -count>1){PowiCache -iM;lB1 -count,iM,1);size_t -xO1=synth.GetStackTop();iM.Start(cG1);FPO(iC3(iG3,"Calculating result for %ld...\n",count));size_t -xN2=y6 -count -cE1 -size_t -n_excess=xV3 -xO1;if(n_excess>0||xN2!=xO1-1){synth.DoPopNMov(xO1-1,xN2);} -} -if(t22)yB1 -eQ.op_flip,1);} -} -} -#endif -#ifndef FPOptimizer_ValueRangeHH -#define FPOptimizer_ValueRangeHH -t5{l33 -l73{l01 -e72 -Comp{} -;tP1>e72 -Compl83l83<=nA -cGreater>l83>nA -cGreaterOrEq>l83>=nA -cEqual>l83==nA -i51>l83!=b;} -} -;} -tK1 -e72 -cI1 -l14 -val;bool -known;cI1():val(),known(false){} -cI1(tV1):val(v),known(true){y81 -l93 -tV1){known=true;val=v;} -l93 -xW3 -Value_t),cI1 -y7)val=iE2 -l93 -xW3 -const -Value_t&),cI1 -y7)val=iE2 -l01 -void -set_if -cX3 -v,xW3 -Value_t),cI1 -y7&&l73::Comp()(val,v))val=iE2 -l01 -void -set_if(tV1,xW3 -const -Value_t&),cI1 -y7&&l73::Comp()(val,v))val=iE2} -yO1 -e72 -range{cI1 -xF -min,max;range():min(),max(){} -range -cX3 -mi,Value_t -ma):min(mi),max(ma){} -range(bool,Value_t -ma):min(),max(ma){} -range -cX3 -mi,bool):min(mi),max(){} -void -set_abs();void -set_neg();} -yO1 -bool -IsLogicalTrueValue -iS1 -yD3&p,bool -abs)yO1 -bool -IsLogicalFalseValue -iS1 -yD3&p,bool -abs);} -#endif -#ifndef FPOptimizer_RangeEstimationHH -#define FPOptimizer_RangeEstimationHH -t5{enum -TriTruthValue{iF2,xX3,Unknown} -yO1 -yD3 -CalculateResultBoundaries -iS1 -eR -yO1 -bool -IsLogicalValue -iS1 -eR -yO1 -TriTruthValue -GetIntegerInfo -iS1 -eR -yO1 -xP1 -GetEvennessInfo -iS1 -eR{if(!tree -tD1)return -Unknown;yL1=tree -x41;if(nB -isEvenInteger(value -y13 -nB -isOddInteger(value -y23 -tK1 -xP1 -GetPositivityInfo -iS1 -eR{yD3 -p=CalculateResultBoundaries(tree);if(p -yI&&p -yM>=e62 -y13 -p -e61 -l61 -y23 -tK1 -xP1 -GetLogicalValue -iS1 -nP1 -bool -abs){yD3 -p=CalculateResultBoundaries(tree);if(IsLogicalTrueValue(p,abs -y13 -IsLogicalFalseValue(p,abs -y23} -#endif -#ifndef FPOptimizer_ConstantFoldingHH -#define FPOptimizer_ConstantFoldingHH -t5{xL1 -ConstantFolding(eR;} -#endif -l33{using -l33 -FUNCTIONPARSERTYPES;using -t5;e72 -ComparisonSetBase{enum{eB3=0x1,Eq_Mask=0x2,Le_Mask=0x3,eC3=0x4,eD3=0x5,Ge_Mask=0x6} -;static -int -Swap_Mask(int -m)yP(m&Eq_Mask)|((m&eB3)?eC3:0)|((m&eC3)?eB3:0);} -enum -c31{Ok,BecomeZero,BecomeOne,n91} -;enum -x12{cond_or,iG2,iH2,iI2} -;} -yO1 -e72 -ComparisonSet:public -ComparisonSetBase{e72 -t32{yZ2 -a -tX -b;int -relationship;t32():a(),b(),relationship(){} -} -;eO3 -t32>tH;e72 -Item{yZ2 -value;bool -cA2;Item():value(),cA2(false){} -} -;eO3 -Item>cJ1;int -xQ1;ComparisonSet():tH(),cJ1(),xQ1(0){} -c31 -AddItem -iR1 -a,bool -cA2,x12 -type){for -iZ1 -c=0;cbool -ConstantFolding_LogicCommon(nP1 -CondType -xF1,bool -xS2){bool -should_regenerate -eW3 -ComparisonSet -xF -comp;x51{x93 -c8 -c31 -cY3=c8 -Ok;iT1&atree=xW -a);e23 -atree -nC){case -cEqual -lG -Eq_Mask -e12 -i51 -lG -eD3 -e12 -cLess -lG -eB3 -e12 -cLessOrEq -lG -Le_Mask -e12 -cGreater -lG -eC3 -e12 -cGreaterOrEq -lG -Ge_Mask -e12 -cNot:cY3 -cV1 -l8 -0),true -e12 -cNotNot:cY3 -cV1 -l8 -0),false,xF1);break;yF3 -if(xS2||IsLogicalValue(atree))cY3 -cV1,false,xF1);c73(cY3){ReplaceTreeWithZero:nU -0)i1 -true;ReplaceTreeWithOne:nU -1);nZ -c8 -Ok:lC -c8 -BecomeZero -t7 -c8 -BecomeOne:iD -c8 -n91:c61 -xY3} -if(should_regenerate){ -#ifdef DEBUG_SUBSTITUTIONS -cV2<<"Before ConstantFolding_LogicCommon: " -cR -#endif -if(xS2){tree.DelParams();} -else{for -l41{iT1&atree=xW -a);if(IsLogicalValue(atree))iZ);} -} -for -iZ1 -a=0;a -#include -#include -l33{using -l33 -FUNCTIONPARSERTYPES;using -t5;e72 -CollectionSetBase{enum -xR1{Ok,n91} -;} -yO1 -e72 -CollectionSet:public -CollectionSetBase{e72 -c41{yZ2 -value -tX -xT2;bool -e0;c41():value(),xT2(),e0(false){} -c41 -iR1 -v,iT1&f):value(v),xT2(f),e0(false){} -} -;std::multimapiN;typedef -x93 -std::multimap::y83 -xS1;CollectionSet():iN(){} -xS1 -FindIdenticalValueTo -iR1 -value){fphash_t -hash=value.GetHash();for(xS1 -i=iN.xU2 -hash);i!=iN.cX1 -hash;++i){cD1 -xI -i -eC2.value -y03 -i;eE3 -iN.end();} -bool -Found -iS1 -xS1&b)yP -b!=iN.end();} -xR1 -AddCollectionTo -iR1 -xT2,const -xS1&into_which){c41&c=into_which -eC2;if(c.e0)c.xT2 -cS -xT2);else{yZ2 -add;add -iH -cAdd);add -c91 -c.xT2);add -cS -xT2);c.xT2.swap(add);c.e0=true;eE3 -n91;} -xR1 -x22 -iR1 -value,iT1&xT2){const -fphash_t -hash=value.GetHash();xS1 -i=iN.xU2 -hash);for(;i!=iN.cX1 -hash;++i){if(i -eC2.value -xI -value -y03 -AddCollectionTo(xT2,i);} -iN.y43,std::make_pair(hash,c41(value,xT2)))i1 -Ok;} -xR1 -x22 -iR1 -a)yP -x22(a,nA1 -1)));} -} -yO1 -e72 -ConstantExponentCollection{typedef -eK -y63;typedef -std::x71 -xV2;eO3 -xV2>data;ConstantExponentCollection():data(){} -void -MoveToSet_Unique -iS1 -Value_t&eP1&eQ1){data -c52 -std::x71(eP1()));data.back().second.swap(eQ1 -cN2 -MoveToSet_NonUnique -iS1 -Value_t&eP1&eQ1){x93 -eO3 -xV2>::y83 -i=std::xU2 -data.iJ2 -data.end(),exponent,Compare1st());if(i!=data.cX1 -exponent){i -eC2.y43 -eC2.end(),eQ1.iJ2 -eQ1.end());} -else{data.y43,std::x71(exponent,eQ1));} -} -bool -iA2{bool -changed -eW3 -std::sort(data.iJ2 -data.end(),Compare1st());redo:for -iZ1 -a=0;a -eR3 -a)l14 -exp_a=data[a -eH3;lG3 -exp_a,e62 -1)))yA1 -for -iZ1 -b=a+1;b -eR3 -b)l14 -exp_b=data[b -eH3 -iK2 -xW2=exp_b-exp_a;if(xW2>=fp_abs(exp_a))break -iK2 -exp_diff_still_probable_integer=xW2*e62 -16);if(t42 -exp_diff_still_probable_integer)&&!(t42 -exp_b)&&!t42 -xW2))){y63&a_set=lS2;y63&b_set=data[b -eI3; -#ifdef DEBUG_SUBSTITUTIONS -cV2<<"Before ConstantExponentCollection iteration:\n" -;Dump(cV2); -#endif -if(isEvenInteger(exp_b)&&!isEvenInteger(xW2+exp_a)nQ -tmp2;tmp2 -iH -cMul);tmp2 -iF1 -b_set);tmp2 -iW1 -tX -tmp;tmp -iH -cAbs);tmp -c91 -tmp2);tmp -iW1;b_set -xF3 -1);b_set[0 -tQ3 -tmp);} -a_set.insert(a_set.end(),b_set.iJ2 -b_set.end());y63 -b_copy=b_set;data.erase(data.begin()+b);MoveToSet_NonUnique(xW2,b_copy);yS1 -#ifdef DEBUG_SUBSTITUTIONS -cV2<<"After ConstantExponentCollection iteration:\n" -;Dump(cV2); -#endif -cJ} -} -eE3 -changed;} -#ifdef DEBUG_SUBSTITUTIONS -void -Dump(std::ostream&out){for -iZ1 -a=0;a -eR3 -a){out.precision(12);out<0)out<<'*' -iL2 -lS2[b],out);} -out<eT1;typedef -std::multimapcK1;cK1 -iJ;for(x93 -eS1::xS1 -j=mul.iN.y73 -j!=mul.iN.end();++j -nQ&value=j -eC2.value -tX&eD2 -j -eC2.xT2;if(j -eC2.e0)exponent -iW1;const -fphash_t -eU1=exponent.GetHash();x93 -cK1::y83 -i=iJ.xU2 -eU1);for(;i!=iJ.cX1 -eU1;++i)if(i -eC2.first -xI -exponent)){if(!exponent -tD1||!cZ1 -x41,e62 -1)))c61 -i -eC2.second -c52 -value);goto -skip_b;} -iJ.y43,std::make_pair(eU1,std::make_pair(exponent,eK -iZ1(1),value))));skip_b:;} -#ifdef FP_MUL_COMBINE_EXPONENTS -ConstantExponentCollection -xF -e01;for(x93 -cK1::y83 -j,i=iJ.y73 -i!=iJ.end();i=j){j=i;++j;eT1&list=i -eC2;x32.lV1 -eD2 -list.first -x41;if(!(exponent==xG1)e01.MoveToSet_Unique(exponent,list -iB2 -iJ.erase(i);} -} -if(e01.iA2)c61 -#endif -if(should_regenerate -nQ -before=tree;before.lD1 -#ifdef DEBUG_SUBSTITUTIONS -cV2<<"Before ConstantFolding_MulGrouping: " -iL2 -before -lE2"\n" -; -#endif -tree.DelParams();for(x93 -cK1::y83 -i=iJ.y73 -i!=iJ.end();++i){eT1&list=i -eC2; -#ifndef FP_MUL_COMBINE_EXPONENTS -x32.lV1 -eD2 -list.first -x41;if(exponent==xG1 -yA1 -if(cZ1 -nH2 -tree.AddParamsMove(list -iB2 -yA1} -} -#endif -yZ2 -mul;mul -iH -cMul);mul -iF1 -list -iB2 -mul -iW1;if(xK&&list.first -tD1){x32 -x41==e62 -1)/e62 -3)nQ -cbrt;cbrt -iH -cCbrt);cbrt.e8 -cbrt.lT2 -cbrt);yA1 -cV -0.5)nQ -sqrt;sqrt -iH -cSqrt);sqrt.e8 -sqrt.lT2 -sqrt);yA1 -cV-0.5)nQ -rsqrt;rsqrt -iH -cRSqrt);rsqrt.e8 -rsqrt.lT2 -rsqrt);yA1 -cV-1)nQ -inv;inv -iH -cInv);inv.e8 -inv.lT2 -inv);yA1} -} -yZ2 -pow;pow -iH -cPow);pow.e8 -pow -c91 -list.first);pow.lT2 -pow);} -#ifdef FP_MUL_COMBINE_EXPONENTS -iJ.clear(iY1 -0;a0){if(tD>1){eO3 -std::pair >nY;std::multimapeV1;bool -lB3 -eW3 -x51 -if(lU2[a]){e11 -xW -a).eZ3{iT1&p=xW -a)l8 -b);const -fphash_t -p_hash=p.GetHash();for(std::multimap::const_iterator -i=eV1.xU2 -p_hash);i!=eV1.cX1 -p_hash;++i){if(nY[i -eC2 -eH3 -xI -p)){nY[i -eC2 -eI3+=1;lB3=true;goto -found_mulgroup_item_dup;} -} -nY -c52 -std::make_pair(p,size_t(1)));eV1.insert(std::make_pair(p_hash,nY -eJ3-1));found_mulgroup_item_dup:;} -} -if(lB3 -nQ -eE2;{size_t -max=0 -eK3 -p=0;pmax){eE2=nY[p -eH3;max=nY[p -eI3;} -} -} -yZ2 -group_add;group_add -iH -cAdd); -#ifdef DEBUG_SUBSTITUTIONS -cV2<<"Duplicate across some trees: " -iL2 -eE2 -lE2" in " -cR -#endif -x51 -if(lU2[a])e11 -xW -a).eZ3 -if(eE2 -xI -xW -a)l8 -b))nQ -tmp(xW -a)y8 -CloneTag());tmp.i91 -b);tmp -iW1;group_add -c91 -tmp);lU2[a]eW3 -xY3 -group_add -iW1 -tX -group;group -iH -cMul);group -c91 -eE2);group -c91 -group_add);group -iW1;add.x22(group);c61} -} -x51 -if(lU2[a]){if(add.x22(xW -a))==CollectionSetBase::n91)c61} -} -if(should_regenerate){ -#ifdef DEBUG_SUBSTITUTIONS -cV2<<"Before ConstantFolding_AddGrouping: " -cR -#endif -tree.DelParams();for(x93 -eS1::xS1 -j=add.iN.y73 -j!=add.iN.end();++j -nQ&value=j -eC2.value -tX&coeff=j -eC2.xT2;if(j -eC2.e0)coeff -iW1;if(coeff -tD1){lG3 -coeff -x41,xG1)yA1 -lG3 -coeff -x41 -nH2 -tree -c91 -value);yA1} -} -yZ2 -mul;mul -iH -cMul);mul -c91 -value);mul -c91 -coeff);mul.e33 -yB -e8} -#ifdef DEBUG_SUBSTITUTIONS -cV2<<"After ConstantFolding_AddGrouping: " -cR -#endif -lD2 -eE3 -t23} -l33{using -l33 -FUNCTIONPARSERTYPES;using -t5 -yO1 -bool -ConstantFolding_IfOperations(iM3(tree.GetOpcode()==cIf||tree.GetOpcode()==cAbsIf);for(;;){if(c93==cNot){tD2 -cIf);xW -0).eF2 -0)c43 -xW -1).swap(xW -2));} -iP1 -xW -0)cQ1{tD2 -t03;xW -0).eF2 -0)c43 -xW -1).swap(xW -2));} -else -yV3 -lY1 -0),t72==t03 -tN1 -tree.eF2 -1));nZ -l03 -tree.eF2 -2));nZ -lZ1 -if(c93==cIf||c93==cAbsIf -nQ -cond=xW -0)tX -lC3;lC3 -tE2==cIf?cNotNot:cAbsNotNot);lC3 -xX2 -1));ConstantFolding(lC3)tX -lD3;lD3 -tE2==cIf?cNotNot:cAbsNotNot);lD3 -xX2 -2));ConstantFolding(lD3);if(lC3 -tD1||lD3 -tD1 -nQ -eT;eT -tE2);eT -xX2 -1));eT -tX3 -eT.nJ -2));eT -iW1 -tX -else_tree -tS1 -tE2)tS1 -xX2 -2))tS1.nJ -1))tS1.nJ -2))tS1 -cY -cond -nC -xT1 -0,cond -l8 -0)yB -nB1 -1,eT -yB -nB1 -2,else_tree -yQ2} -if(xW -1)nC==xW -2)nC&&(xW -1)nC==cIf||xW -1)nC==t03 -nQ&x53=xW -1)tX&leaf2=xW -2);if(x53 -l8 -0)nN2 -0))&&x61 -1))||x53 -l8 -2)nN2 -2)))nQ -eT;eT -nO2;eT -tY3 -eT -xY2 -1));eT -xZ2 -1));eT -iW1 -tX -else_tree -tS1 -nO2 -tS1.nJ -0))tS1 -xY2 -2))tS1 -xZ2 -2))tS1 -cY -x53 -nC -xT1 -0 -cB3 -0)yB -nB1 -1,eT -yB -nB1 -2,else_tree -yQ2 -if -x61 -1))&&x53 -l8 -2)nN2 -2))nQ -eU;eU -nO2;eU -c91 -xW -0));eU -xY2 -0));eU -xZ2 -0));eU -cY -x53 -nC -yB -nB1 -0,eU -xT1 -2 -cB3 -2)xT1 -1 -cB3 -1)yQ2 -if -x61 -2))&&x53 -l8 -2)nN2 -1))nQ -eI2;eI2 -iH -leaf2 -nC==cIf?cNot:cC3);eI2 -xZ2 -0));eI2 -iW1 -tX -eU;eU -nO2;eU -c91 -xW -0));eU -xY2 -0));eU -c91 -eI2);eU -cY -x53 -nC -yB -nB1 -0,eU -xT1 -2 -cB3 -2)xT1 -1 -cB3 -1)yQ2} -yZ2&xV=xW -1)tX&y4=xW -2);if(xV -xI -y4)){tree.eF2 -1)yQ2 -const -OPCODE -op1=xV -nC;const -OPCODE -op2=y4 -nC;y93 -op2){if(xV.e91 -1 -nQ -lO -0));y02 -0))c71()n4 -if(xV.e91 -2&&y4.e91 -2){if(xV -l8 -0)xI -y4 -l8 -0))nQ -param0=xV -l8 -0)tX -lO -1));y02 -1))c71 -t8 -param0)n4 -if(xV -l8 -1)xI -y4 -l8 -1))nQ -param1=xV -l8 -1)tX -lO -0));y02 -0))c71 -t8 -n81 -c81 -param1 -yQ2} -y93 -yA3 -cMul -lV2 -cAnd -lV2 -cOr -lV2 -cAbsAnd -lV2 -cAbsOr -lV2 -cMin -lV2 -cMax){eK -lE3;c2{for -iZ1 -b=y4.l91 -b-->0;){if(xV -lF3 -y4 -l8 -b))){if(lE3 -eU3){xV.t13 -lD1} -lE3 -c52 -xV -n93 -y4.i91 -b);xV.i91 -a -e02} -} -if(!lE3 -eU3){xV -iW1;y4 -iW1 -l7 -op1 -yB -SetParamsMove(lE3)n4} -} -y93 -yA3 -cMul||(op1==cAnd&&IsLogicalValue(y4))||(op1==cOr&&IsLogicalValue(y4))){c2 -if(xV -lF3 -y4)){xV.lD1 -xV.i91 -a);xV -iW1 -tX -cL1=y4;y4=tE -op1==yA3 -cOr -t52 -op1 -c81 -cL1)n4} -if((op1==cAnd -lV2 -cOr)&&op2==cNotNot -nQ&lH3=y4 -l8 -0);c2 -if(xV -lF3 -lH3)){xV.lD1 -xV.i91 -a);xV -iW1 -tX -cL1=lH3;y4=tE -op1==cOr -t52 -op1 -c81 -cL1)n4} -if(op2==cAdd||op2==cMul||(op2==cAnd&&IsLogicalValue(xV))||(op2==cOr&&IsLogicalValue(xV))){for -iZ1 -a=y4 -iY -y4 -lF3 -xV)){y4.t13 -i91 -a);y4 -iW1 -tX -cM1=xV;xV=tE -op2==cAdd||op2==cOr -t52 -op2 -c81 -cM1)n4} -if((op2==cAnd||op2==cOr)&&op1==cNotNot -nQ&lI3=xV -l8 -0 -iY1 -y4 -iY -y4 -lF3 -lI3)){y4.t13 -i91 -a);y4 -iW1 -tX -cM1=lI3;xV=tE -op2==cOr -t52 -op2 -c81 -cM1)n4 -eE3 -t23} -#include -l33{using -l33 -FUNCTIONPARSERTYPES;using -t5 -yO1 -int -maxFPExponent()yP -std::numeric_limits -xF::max_exponent;} -yP1 -x91 -Value_t -base,Value_t -exponent){if(base=e62 -maxFPExponent -xF())/fp_log2(base);} -yP1 -ConstantFolding_PowOperations(iM3(tree.GetOpcode()==cPow);nP&&xW -1).lV1 -const_value=t33 -lR,xW -i8);nU -const_value)i1 -t23 -if(eI1 -lJ3 -xW -i8 -nH2 -tree.eF2 -0)yQ2 -nP&&lJ3 -lR -nH2 -nU -1)i1 -t23 -nP&&xW -1)nC==cMul){bool -y12=false -iK2 -lW2=lR -tX -mulgroup=xW -1 -iY1 -mulgroup -iY -mulgroup -l8 -a).lV1 -imm=mulgroup -l8 -a)x41;{if(x91 -lW2,imm))break -iK2 -lX2=t33 -lW2,imm);lG3 -lX2,xG1)break;if(!y12){y12=true;cA1 -lD1} -lW2=lX2;cA1 -i91 -a -e02} -if(y12){cA1 -e33); -#ifdef DEBUG_SUBSTITUTIONS -cV2<<"Before pow-mul change: " -cR -#endif -xW -0).Become(eA1 -lW2));xW -1).Become -eH2); -#ifdef DEBUG_SUBSTITUTIONS -cV2<<"After pow-mul change: " -cR -#endif -} -} -if(eI1 -c93==cMul)l14 -lY2=xW -i8 -iK2 -y22=1.0;bool -y12=false -tX&mulgroup=xW -0 -iY1 -mulgroup -iY -mulgroup -l8 -a).lV1 -imm=mulgroup -l8 -a)x41;{if(x91 -imm,lY2))break -iK2 -eW1=t33 -imm,lY2);lG3 -eW1,xG1)break;if(!y12){y12=true;cA1 -lD1} -y22*=eW1;cA1 -i91 -a -e02} -if(y12){cA1 -e33)tX -cZ3;cZ3 -iH -cPow);cZ3 -iF1 -tree.lJ2));cZ3.yC2 -yB -eL3 -cMul -c81 -cZ3 -yB -AddParam(eA1 -y22)yQ2} -if(xW -0)i12 -eI1 -xW -0)l8 -1).lV1 -a=xW -0)l8 -i8 -iK2 -b=xW -i8 -iK2 -c=a*b;if(isEvenInteger(a)&&!isEvenInteger(c)nQ -lK3;lK3 -iH -cAbs);lK3.nJ -0)c43 -lK3.e33 -yB -nB1 -0,lK3);} -else -tree.SetParam(0,xW -0)l8 -0)xT1 -1,eA1 -c));eE3 -t23} -l33{using -l33 -FUNCTIONPARSERTYPES;using -t5;e72 -l5{enum -eJ2{MakeFalse=0,MakeTrue=1,t62=2,lN3=3,MakeNotNotP0=4,MakeNotNotP1=5,MakeNotP0=6,MakeNotP1=7,xJ=8} -;enum -lZ2{Never=0,Eq0=1,Eq1=2,yB3=3,yC3=4} -;eJ2 -if_identical;eJ2 -n02 -4];e72{eJ2 -what:4;lZ2 -when:4;} -l02,l12,l22,l32 -yO1 -eJ2 -Analyze -iR1 -xC3 -eX1)const{if(a -xI -b -y03 -if_identical;yD3 -tY -a);yD3 -p1=CalculateResultBoundaries(b);if(p0 -e61&&p1 -yI){if(p0 -nL3p1 -nL3&&n02 -2]iC -2];if(p0 -yM>=p1 -nL3&&n02 -3]iC -3];} -if(IsLogicalValue(a)){if(l02 -nN3 -l02.when,p1 -y03 -l02.what;if(l22 -nN3 -l22.when,p1 -y03 -l22.what;} -if(IsLogicalValue(b)){if(l12 -nN3 -l12.when,p0 -y03 -l12.what;if(l32 -nN3 -l32.when,p0 -y03 -l32.what;eE3 -xJ;} -cB1 -bool -TestCase(lZ2 -when,const -yD3&p){if(!p -yI||!p -e61 -cQ -e23 -when){case -Eq0:nO3==e62 -0.0)t43==p -yM -t83 -Eq1:nO3==e62 -1.0)t43==p -nL3 -t83 -yB3:nO3>xH1 -t43<=e62 -1)t83 -yC3:nO3>=xH1 -l61 -1);yF3;eE3 -t23} -;l33 -RangeComparisonsData{static -const -l5 -Data[6]={{l5 -lL3 -i3 -xJ,l5::i3 -xJ -lF1 -Eq1 -nT1 -Eq1 -nU1 -Eq0 -nV1 -Eq0} -} -,{l5::x42 -lM3 -xJ,l5 -lM3 -xJ -lF1 -Eq0 -nT1 -Eq0 -nU1 -Eq1 -nV1 -Eq1} -} -,{l5::x42 -lM3 -t62,l5::i3 -MakeFalse -nU1 -yB3 -nT1 -yC3 -yY,{l5 -lL3 -xJ,l5 -lM3 -i3 -lN3 -nU1 -yC3 -nT1 -yB3 -yY,{l5::x42::i3 -i3 -MakeTrue,l5::t62 -lF1 -yC3 -nV1 -yB3 -yY,{l5 -lL3 -i3 -lN3,l5::xJ,l5 -nC1 -lF1 -yB3 -nV1 -yC3 -yY} -;} -yP1 -ConstantFolding_Comparison(eR{using -l33 -RangeComparisonsData;assert(tree.GetOpcode()>=cEqual&&tree.GetOpcode()<=cGreaterOrEq);e23 -Data[t72-cEqual].Analyze(xW -0),xW -1))){case -l5::MakeFalse:nU -0);nZ -l5 -nC1:nU -1 -nY3 -lN3:tD2 -cEqual -nY3 -t62:tD2 -i51 -nY3 -MakeNotNotP0:tD2 -cNotNot -yB -i91 -1 -nY3 -MakeNotNotP1:tD2 -cNotNot -yB -i91 -0 -nY3 -MakeNotP0:tD2 -cNot -yB -i91 -1 -nY3 -MakeNotP1:tD2 -cNot -yB -i91 -0 -nY3 -xJ:;} -if(xW -1)tD1)e23 -c93){case -cAsin:lM -fp_sin(xW -iP2 -cAcos:lM -fp_cos(xW -i8))yB -eL3 -t72==cLess?cGreater:t72==cLessOrEq?cGreaterOrEq:t72==cGreater?cLess:t72==cGreaterOrEq?cLessOrEq:t72);nZ -cAtan:lM -fp_tan(xW -iP2 -cLog:lM -fp_exp(xW -iP2 -cSinh:lM -fp_asinh(xW -iP2 -cTanh:if(fp_less(fp_abs(xW -i8)nH2 -lM -fp_atanh(xW -i8))yQ2 -break;yF3 -xY3 -return -t23} -#include -#include -#ifdef FP_SUPPORT_OPTIMIZER -using -l33 -FUNCTIONPARSERTYPES;l33{ -#ifdef DEBUG_SUBSTITUTIONS -yE -double -d){union{double -d;uint_least64_t -h -c42 -d=d;lR1 -h -nX1 -#ifdef FP_SUPPORT_FLOAT_TYPE -yE -float -f){union{float -f;uint_least32_t -h -c42 -f=f;lR1 -h -nX1 -#endif -#ifdef FP_SUPPORT_LONG_DOUBLE_TYPE -yE -long -double -ld){union{long -double -ld;e72{uint_least64_t -a;x83 -short -b;} -s -c42 -ld=ld;lR1 -s.b<IsIdenticalTo(*b.data);} -yP1 -xK2 -xF::IsIdenticalTo -iS1 -xK2 -xF&b)const{if(Hash!=b.Hash -cQ -if(Opcode!=b.Opcode -cQ -e23 -Opcode){case -cImmed:return -lJ3 -Value,b.Value)t83 -iU2:return -lL2==b.lK2 -case -cFCall:case -cPCall:if(lL2!=b.lL2 -cQ -break;yF3 -xY3 -if(iS2!=b.iS2 -cQ -for -iZ1 -a=0;a1)data=new -xK2 -xF(*data);} -tK1 -yZ2 -yZ2::GetUniqueRef(){if(GetRefCount()>1)return -yZ2(*this,CloneTag())i1*this;} -i4):yS -cNop -iR3),n8 -i4 -const -xK2&b):yS -b.Opcode -iR3 -b.Value),lL2(b.cO1,t53 -b.Params),Hash(b.Hash),Depth(b.Depth -eB1 -b.lM2){} -i4 -tX1:yS -cImmed -iR3 -i),n8 -#ifdef __GXX_EXPERIMENTAL_CXX0X__ -i4 -xK2 -xF&&b):yS -b.Opcode -iR3 -tF2 -b.Value)),lL2(b.cO1,t53 -tF2 -b.Params)),Hash(b.Hash),Depth(b.Depth -eB1 -b.lM2){} -i4 -Value_t&&i):yS -cImmed -iR3 -tF2 -i)),n8 -#endif -i4 -iU1 -o):yS -o -iR3),n8 -i4 -iU1 -o,x83 -f):yS -o -iR3),lL2(f),t53),Hash(),Depth(1 -eB1 -0){} -} -#endif -#ifdef FP_SUPPORT_OPTIMIZER -#include -#include -#include -#include -#include -using -l33 -FUNCTIONPARSERTYPES; -#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING -l33{xL1 -tZ1 -nO,std -c9&done,std::ostream&o){x51 -tZ1 -xW -a),done,o);std::ostringstream -buf -iL2 -tree,buf);done[nJ2].insert(buf.str());} -} -#endif -t5{ -#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING -xL1 -DumpHashes(cE){std -c9 -done;tZ1 -tree,done,o);for(std -c9::const_iterator -i=done.y73 -i!=done.end();++i){const -std::set&flist=i -eC2;if(flist -eJ3!=1)o<<"ERROR - HASH COLLISION?\n" -;for(std::set::const_iterator -j=flist.y73 -j!=flist.end();++j){o<<'['<first.hash1<<','<first.hash2<<']'<0)o<<' ' -iL2 -xW -a),o);if(a+1 -l33 -lA1{x83 -ParamSpec_GetDepCode -iS1 -eA2&b -yY3 -b.first){case -ParamHolder:{cM*s=(cM*)b.second -i1 -s->depcode;} -case -SubFunction:{cN*s=(cN*)b.second -i1 -s->depcode;} -yF3 -xY3 -return -0;} -xL1 -DumpParam -iS1 -eA2&yA2 -std::ostream&o){static -const -char -ParamHolderNames[][2]={"%" -,"&" -,"x" -,"y" -,"z" -,"a" -,"b" -,"c" -} -;x83 -y32 -0;e23 -lX3.first){case -NumConstant:{const -ParamSpec_NumConstant -xF¶m=*iS1 -ParamSpec_NumConstant -xF*tF1;using -l33 -FUNCTIONPARSERTYPES;o.precision(12);o<';yF -PositionalParams)o<<"]" -;yF -SelectedParams)o<<"}" -;o<<')';} -xY3 -c73(ImmedConstraint_Value(constraints&ValueMask)){case -ValueMask:lC -Value_AnyNum:lC -x62:o<<"@E" -;lC -Value_OddInt:o<<"@O" -;lC -i11:o<<"@I" -;lC -Value_NonInteger:o<<"@F" -;lC -eY1:o<<"@L" -;yV3 -ImmedConstraint_Sign(constraints&SignMask)){case -SignMask:lC -Sign_AnySign:lC -nD1:o<<"@P" -;lC -eZ1:o<<"@N" -;yV3 -ImmedConstraint_Oneness(constraints&OnenessMask)){case -OnenessMask:lC -Oneness_Any:lC -Oneness_One:o<<"@1" -;lC -Oneness_NotOne:o<<"@M" -;yV3 -ImmedConstraint_Constness(constraints&ConstnessMask)){case -ConstnessMask:lC -i01:if(lX3.first==ParamHolder){cM&yU3 -cM*tF1;if -yZ3 -index<2)xY3 -o<<"@C" -;lC -Constness_NotConst:o<<"@V" -;lC -Oneness_Any:xY3} -xL1 -DumpParams -lT1 -paramlist,x83 -count,std::ostream&o){for -lT1 -a=0;a0)o<<' ';const -eA2¶m=ParamSpec_Extract -xF(paramlist,a);DumpParam -xF(param,o);x83 -depcode=ParamSpec_GetDepCode(param);if(depcode!=0)o<<"@D" -< -using -l33 -lA1;using -l33 -FUNCTIONPARSERTYPES;l33{cM -plist_p[37]={{2,0,0x0} -nT -0,0x4} -nT -nD1,0x0} -nT -eZ1|Constness_NotConst,0x0} -nT -Sign_NoIdea,0x0} -nT -eY1,0x0} -,{3,Sign_NoIdea,0x0} -,{3,0,0x0} -,{3,eY1,0x0} -,{3,0,0x8} -,{3,Value_OddInt,0x0} -,{3,Value_NonInteger,0x0} -,{3,x62,0x0} -,{3,nD1,0x0} -,{0,eZ1|lV{0,lV{0,nD1|lV{0,x62|lV{0,i01,0x1} -,{0,i11|nD1|lV{0,i21 -i01,0x1} -,{0,i21 -lV{0,Oneness_One|lV{0,eY1|lV{1,lV{1,x62|lV{1,i21 -lV{1,i11|lV{1,nD1|lV{1,eZ1|lV{6,0,0x0} -,{4,0,0x0} -,{4,i11,0x0} -,{4,lV{4,0,0x16} -,{5,0,0x0} -,{5,lV} -yO1 -e72 -plist_n_container{static -const -ParamSpec_NumConstant -xF -plist_n[20];} -yO1 -const -ParamSpec_NumConstant -xF -plist_n_container -xF::plist_n[20]={{e62-2 -i5-1 -i5-0.5 -i5-0.25 -i5 -0 -tG2 -fp_const_deg_to_rad -xF(tG2 -fp_const_einv -xF(tG2 -fp_const_log10inv -xF(i5 -0.5 -tG2 -fp_const_log2 -xF(i5 -1 -tG2 -fp_const_log2inv -xF(i5 -2 -tG2 -fp_const_log10 -xF(tG2 -fp_const_e -xF(tG2 -fp_const_rad_to_deg -xF(tG2-fp_const_pihalf -xF(),xU1{xH1,xU1{fp_const_pihalf -xF(),xU1{fp_const_pi -xF(),xU1} -;cN -plist_s[517]={{{1,15,tH2 -398,tH2 -477,tH2 -15,cNeg,GroupFunction,0} -,i01,0x1 -lR3 -15,y42 -24,y42 -465,y42 -466,y42 -498,cInv,lT -2,327995 -x9 -l0 -2,48276 -x9 -l6 -260151 -x9 -l6 -470171 -x9 -l6 -169126 -x9 -l6 -48418 -x9 -l6 -1328 -x9 -l6 -283962 -x9 -l6 -169275 -x9 -l6 -39202 -x9 -l6 -283964 -x9 -l6 -283973 -x9 -l6 -476619 -x9 -l6 -296998 -x9 -l6 -47 -x9 -SelectedParams,0} -,0,0x4 -nH -161839 -x9 -l6 -25036 -x9 -l6 -35847 -x9 -l6 -60440 -x9 -l6 -30751 -x9 -l6 -270599 -x9 -l6 -60431 -x9 -l6 -259119 -x9 -l6 -183474 -x9 -l6 -332066 -x9 -l6 -7168 -x9 -l6 -197632 -x9 -l6 -291840 -x9 -l6 -283648 -x9 -l6 -238866 -x9 -l6 -239902 -x9 -l6 -31751 -x9 -l6 -244743 -x9 -l6 -384022 -x9 -SelectedParams,0} -,0,0x4 -nH -385262 -x9 -l6 -386086 -x9 -l6 -393254 -x9 -SelectedParams,0} -,0,0x5 -nH -393254 -x9 -l6 -386095 -x9 -l6 -387312 -x9 -l6 -18662 -x9 -l6 -61670 -x9 -l6 -387397 -x9 -l6 -247855 -x9 -SelectedParams,0} -,0,0x1 -nH -342063 -x9 -l6 -297007 -x9 -l6 -15820 -x9 -l6 -393263 -x9 -l6 -393263 -x9 -SelectedParams,0} -,0,0x5 -nH -161847 -x9 -l6 -258103 -x9 -l6 -249073 -x9 -l6 -249076 -x9 -iO -0,0 -x9 -nF -0,0 -i31 -1,45 -x9 -nF -1,53 -x9 -nF -1,54 -x9 -nF -1,55 -x9 -nF -1,56 -x9 -nF -1,26 -x9 -nF -1,259 -eK2 -0x16 -lR3 -253 -x9 -nF -1,272 -i31 -1,323 -eK2 -0x16 -lR3 -0 -x9 -nF -1,21 -x9 -nF -1,447 -eK2 -0x4 -lR3 -449 -eK2 -0x4 -lR3 -0 -eK2 -0x4 -lR3 -0 -tJ -2} -,0,0x4 -lR3 -15 -x9 -nF -1,24 -tJ -2} -,0,0x0 -nH -58392 -i31 -0,0 -tJ -1} -,nD1,0x0 -nH -24591 -lS3 -33807 -lS3 -48143 -lS3 -285720 -lS3 -290840 -lS3 -305152,l9 -312400,l9 -39202,l9 -121894,l9 -421926,l9 -429094,l9 -443430,l9 -317834,l9 -329098,l9 -7633,l9 -7706,l9 -7730,l9 -38,l9 -50587,l9 -406528,l9 -24583,l9 -31751,l9 -405511,l9 -321551 -iV2 -327713,l9 -322596,l9 -88361,l9 -335174,l9 -327050,l9 -493606,l9 -496678,l9 -503846,l9 -516134,l9 -7217,l9 -333875,l9 -336896,l9 -524326,l9 -509952,l9 -286727,l9 -90127,l9 -131087,l9 -296976,tQ1 -324623,l1 -0x14 -nH -332815,l1 -0x10} -,{{3,7340056,tQ1 -289092,l9 -92176 -iV2 -337935 -e31 -7340060 -lO3 -7340176,l9 -338959 -e31 -7340061 -iV2 -7206,l9 -x63 -l9 -357414,l9 -368678,l9 -370745,l1 -0x7} -,{{3,7340177,l9 -39277,tQ1 -426398 -lO3 -40272286 -iV2 -490910 -lO3 -40336798 -iV2 -50600,l9 -426462 -iV2 -490974 -iV2 -370726,l1 -0x6 -nH -371750,l1 -0x6 -nH -428070 -e31 -40336862 -iV2 -38378,l9 -50671 -e31 -47662080,l9 -477184,l9 -568320,l9 -371727,l1 -0x7} -,{{3,15779306,l9 -370703,l1 -0x7 -nH -39277,l9 -39279,l1 -0x4} -,{{3,15779238,l9 -39338,tQ1 -436262,l9 -508966,l9 -39409,tQ1 -296998,tQ1 -35847,l9 -15,tQ1 -377894,l9 -386063,l1 -0x1 -nH -15,l9 -7192,l9 -122904,l9 -121880,l9 -30751,l9 -57,l9 -7456,l9 -15674 -e31 -67579935,l9 -39237,l9 -58768,l9 -62924,l9 -121856,l9 -15760 -e31 -64009216,l1 -0x0} -,{{0,0,xL -0,0,iW -2,eC1 -2,eD1 -3,eC1 -3,eD1 -38,xL -1,38,iW -14,xL -1,57,xL -1,16,eL2 -0x0 -nH -471103,eL2 -0x1 -lR3 -303,xL -1,323,yH3 -0x0 -nH -471363,eL2 -0x16 -lR3 -293,eC1 -294,eD1 -295,xL -1,296,iW -400,xL -1,0,xL -1,460,xL -1,465,xL -1,16,eL2 -0x1 -lR3 -57,yH3 -0x1 -lR3 -0,iW -21,xL -1,15,eL2 -0x0 -nH -24591,xL -1,24,iW -517,yH3 -0x0 -nH -46095,lK -46104,lK -15397,lK -287789,lK -66584,lK -404763,lK -62504,lK -15409,lK -39951,lK -24591,lK -33807,lK -50200,lK -62509,lK -50176,lF,178176,t21 -tF3 -283648,lF,19456,lF,27648,lF,89088,lF,86016,lF,488448,lF,14342,lF,58375,lF,46147 -xX -46151,lF,284679,lF,7183,lF,46159 -xX -38993 -xX -50265,lF,50249,lF,283808,lF,284835,lF,24822,lF,10240,lF,11264,lF,7170,lF,x63 -lF,17408,lF,164864,lF,237568,lF,242688,t21 -0x14 -nH -476160,lF,25607,lF,121871,lF,50252,lF,39374,lF,50183,lF,7192,lF,121887,lF,252979,lF,46155,lF,38919,lF,50267,lF,50268,lF,50253,lF,46190,lF,50295,lF,7563,t21 -0x10 -nH -416811,lF,416819,lF,40046,lF,46191 -xX -415795,lF,40047 -xX -415787,lF,39015,t21 -0x5 -nH -39326 -xX -39326,lF,39332,t21 -0x5 -nH -39333 -cC2 -50590 -xX -50590,lF,39338 -xX -39338,lF,39335,t21 -0x5 -nH -15786 -xX -146858,lF,39372,lF,39379,lF,39380,lF,39390 -xX -50654 -xX -50654,lF,24,t21 -0x6 -nH -62,lF,24,lF,62,t21 -0x6 -nH -43,lF,43 -xX -51,lF,51 -xX -50269,lF,50176 -xX -50270,lF,39159,lF,39183 -xX -7168 -xX -31744,lF,99328,lF,31746,lF,100376,lF,39409 -xX -39411 -xX -39411,lF,39420,lF,39420 -xX -15,lF,39025,t21 -0x5 -nH -39422,lF,16384,lF,62853,lF,15360,lF,15 -cC2 -16,lF,7183 -cC2 -7172 -tW2 -y71,nD1,0x0 -nH -24591 -tW2 -lT -2,50200 -tW2 -lT -2,63521 -tW2 -lT -2,62500 -tW2 -lT -2,50453 -tW2 -lT -2,62488 -tW2 -lT -1,0,t93 -7,t93 -194,t93 -0,cAcos -tA3 -cAcosh -tA3 -cAsin -tA3 -cAsinh -nS -119,cAsinh -tA3 -cAtan -t11 -306176,cAtan2 -t11 -x63 -cAtan2 -tA3 -cAtanh -nS -246,cCeil -tA3 -cCeil -tB3 -0,cD2 -0,cCos -tB3 -7,cD2 -91,cD2 -92,cD2 -119,cD2 -236,cD2 -255,cD2 -214,iW2 -236,iW2 -464,iW2 -0,cCosh -tB3 -0,iW2 -0,cExp -nS -7,cExp -nS -91,cExp -tA3 -yI3 -7,yI3 -91,yI3 -246,cFloor -tA3 -cFloor,lA -0x4 -nH -309540,cHypot -t11 -316708,cHypot -t11 -316724,cHypot,l0 -3,32513024,eM2 -34627584 -iL -31493120,eM2 -89213952 -iL -149042176 -iL -246647808 -iL -301234176 -iL -494360576 -iL -498558976 -iL -62933520 -iL -62933520,eM2 -62933526 -iL -62933526,eM2 -24670208 -iL -579378176 -iL -573578240 -iL -32513024 -iL -566254592 -iL -7900160 -iL -588822528,cIf -nS -119,cInt -nS -246,tI2 -0,tI2 -7,tI2 -31,tI2 -194,tI2 -363,tI2 -15,cLog,lT -1,24,cLog,lT -1,0,cLog10 -tA3 -cLog2 -t11 -x63 -cMax -t11 -35847,cMax -t11 -30751,cMax -tA3 -cMax,AnyParams,1} -,0,0x4 -nH -x63 -cMin -t11 -35847,cMin -t11 -30751,cMin -tA3 -cMin,AnyParams,1} -,0,0x4 -nH -24591,cMin,lT -1,0,x72 -7,x72 -91,x72 -92,x72 -119,x72 -149,x72 -231,cSin,lA -0x5 -lR3 -246,x72 -255,x72 -254,x72 -0,cSin -tB3 -273,cSin,lA -0x1 -lR3 -214,y52 -231,tD3 -lA -0x5 -lR3 -246,y52 -254,y52 -255,y52 -464,y52 -0,cSinh -tB3 -0,y52 -15,cSqrt,lT -1,0,cTan -tA3 -cTan -tB3 -115,cTan -tB3 -116 -tC3 -231 -tC3 -246 -tC3 -273 -tC3 -254 -tC3 -255,cTan -tA3 -y62 -0,cTanh -tB3 -213,y62 -231,y62 -246,y62 -254,y62 -255,y62 -0,cTrunc -t11 -15384,cSub,lT -2,15384,cDiv,lT -2,476626,cDiv,lT -2,121913,tJ2 -x63 -lP3 -tF3 -x63 -tJ2 -31744,lP3 -0x20 -nH -31751,lP3 -0x24 -nH -31751,tJ2 -121913,i51 -t11 -x63 -cLess,lA -tF3 -41984,cLess,lA -0x4 -nH -41984,cLess -t11 -7,cLess -t11 -x63 -cLessOrEq -t11 -296182,cLessOrEq -t11 -7168 -tV2,lA -tF3 -41984 -tV2,lA -0x4 -nH -41984 -tV2 -t11 -7 -tV2 -t11 -x63 -y9 -l0 -2,296182,cGreaterOrEq -tA3 -n32 -245,n32 -7,n32 -550,n32 -553,n32 -554,n32 -556,n32 -31,n32 -559,n32 -15,n32 -560,cNot -t11 -7706,lT3 -x63 -lT3 -35847,lT3 -30751,lT3 -463903,lT3 -466975,cAnd,iO -0,0,cAnd,nF -2,x63 -e03 -7706,e03 -35847,e03 -463903,e03 -466975,e03 -30751,cOr,iO -1,0,n42 -91,n42 -131,n42 -245,n42 -215,n42 -246,cDeg -nS -246,cRad -t11 -x63 -cAbsAnd,l6 -x63 -cAbsOr,iO -1,0,cC3 -tA3 -cAbsNotNot,l0 -3,32513024,yT3 -lA -0x0} -,} -;} -l33 -lA1{const -Rule -grammar_rules[262]={{ProduceNewTree,17,1,0,{1,0,cAbs,eN2 -409,{1,146,cAtan,eN2 -403 -nT -1324,cAtan2,eN2 -405 -nT -307201,cAtan2 -eL -253174 -nT -255224,cAtan2 -eL -259324 -nT -257274,cAtan2,eN2 -152,{1,252,cCeil -i7 -486,{1,68 -yH2 -482,{1,122 -yH2 -483,{1,124 -yH2 -151,{1,125 -yH2 -419,{1,123 -yH2 -0,{1,403,cCos,l2 -2,1,246,{1,252,cCos,l2 -18,1,0,{1,400 -yH2 -301,{1,406,cCosh,l2 -2,1,246,{1,252,cCosh,l2 -18,1,0,{1,400,cCosh -i7 -458,{1,121,cFloor,eN2 -150,{1,252,cFloor,tG3 -156,{3,7382016,eF -549,{3,8430592,eF -556,{3,8436736,eF -157,{3,42998784,eF -550,{3,42999808,eF -562,{3,43039744,eF -557,{3,49291264,eF -538,{3,49325056,eF -469,{3,1058318,eF -473,{3,1058324,eF -473,{3,9438734,eF -469,{3,9438740,cIf,l2 -0,3,32542225,{3,36732434,cIf,l2 -0,3,32542231,{3,36732440,cIf,yR3 -573,{3,32513026,cIf,yR3 -515,{3,455505423,cIf,yR3 -515,{3,433506837,cIf -i7 -78,{1,256,cLog -i7 -69,{1,258,cLog -i7 -404,{1,72,cLog -i7 -159,{1,147,cLog,l2 -0,1,0 -nT -487425,cMax -l3 -16,1,445 -nT -yJ3 -cMax -l3 -0,1,0 -nT -483329,cMin -l3 -16,1,446 -nT -yJ3 -cMin,c3 -0,1,153 -nT -24832 -tW2 -tG3 -153 -nT -25854 -tW2 -tG3 -154 -nT -129039 -tW2 -xV1 -32055 -tW2 -xV1 -32056 -tW2 -xV1 -32057 -tW2 -l2 -0,2,166288 -nT -32137 -tW2 -xV1 -33082 -tW2 -l2 -0,2,7168 -nT -12688 -tW2 -l2 -0,2,7434 -nT -12553,tX2 -435 -nT -46146,tX2 -436 -nT -46154,tX2 -437 -nT -46150,tX2 -169 -nT -83983,tX2 -168 -nT -130082,tX2 -175 -nT -133154 -tW2 -tI3 -476160 -nT -471055 -tW2 -tI3 -274432 -nT -273423 -tW2 -tI3 -251904 -nT -266274 -tW2 -tI3 -251904 -nT -263186,tX2 -171,{1,252,cE2 -421,{1,68,cE2 -151,{1,122,cE2 -419,{1,124,cE2 -170,{1,125,cE2 -482,{1,123,cE2 -0,{1,405,cE2 -172,{1,252,cSinh -i7 -328,{1,404,cSinh -i7 -173,{1,252,tJ3 -0,{1,408,tJ3 -176,{1,410,tJ3 -177,{1,252,cTanh,l2 -0,1,442 -nT -449551,i6 -1,441 -nT -yJ3 -i6 -1,167 -nT -268549,i6 -1,181 -nT -276749,i6 -1,180 -nT -276500,i6 -2,190770 -nT -189622,i6 -2,194748 -nT -193723,i6 -2,202943 -nT -196795,i6 -2,59699 -nT -298148,i6 -2,59714 -nT -325815,i6 -2,59724 -nT -343224 -x9 -c3 -2,1,337,{1,333 -tJ -1 -tF -336,{1,338 -tJ -1} -} -,{ReplaceParams,2,1,340 -nT -1363 -nR -342 -nT -1365 -nR -463 -nT -472524 -nR -47 -nT -356711 -nR -349 -nT -200751 -nR -360 -nT -199727 -nR -480 -nT -207053 -nR -481 -nT -208077 -nR -417 -nT -211144 -nR -209 -nT -211145 -nR -418 -nT -215240 -nR -212 -nT -212329 -nR -204 -nT -373097 -nR -211 -nT -372944 -nR -217 -nT -201944 -nR -221 -nT -223448 -nR -367 -nT -508329 -nR -219 -nT -508126 -nR -224 -nT -225705 -nR -223 -nT -225776 -nR -365 -nT -230825 -nR -426 -nT -377057 -nR -497 -nT -377054 -nR -497 -nT -204201 -nR -426 -nT -375280 -nR -224 -nT -375006,cAdd -l3 -2,2,407781 -nT -233698,cAdd -l3 -2,2,59763 -nT -233842,i6 -1,372 -nT -1397,lW1 -95 -nT -24705,lW1 -96 -nT -24708,lW1 -444 -nT -449551,lW1 -443 -nT -yJ3 -lW1 -100 -nT -101750,lW1 -108 -nT -106821,lW1 -105 -nT -103749 -lU3 -0,2,110607 -nT -108869 -lU3 -0,2,107535 -nT -109893,lJ -0 -tF -112 -nT -111634,cMul,SelectedParams,0 -tF -567,{1,52,lJ -1 -tF -568,{1,42,lJ -1} -} -,{ReplaceParams,2,1,467 -nT -45516 -xA -356 -nT -51555 -xA -468 -nT -49612 -xA -357 -nT -47459 -xA -429 -nT -438699 -xA -432 -nT -441774 -xA -486 -nT -498726 -xA -494 -nT -504870 -xA -382 -nT -435579 -xA -497 -nT -435709 -xA -426 -nT -508287 -xA -414 -nT -500092 -xA -499 -nT -352744 -xA -345 -nT -367092 -xA -381 -nT -425318 -xA -478 -nT -425460 -xA -47 -nT -512501 -xA -505 -nT -355817 -xA -47 -nT -516598 -xA -507 -nT -518182 -xA -508 -nT -358896 -xA -351 -nT -388605 -xA -511 -nT -360939 -xA -503 -nT -354788 -xA -514 -nT -525350 -xA -510 -nT -394342 -xA -386 -nT -351346 -lU3 -2,2,363004 -nT -361968 -lU3 -16,1,117 -nT -1157 -lU3 -16,1,118 -nT -1158 -lU3 -16,1,402 -nT -411024 -lU3 -16,2,58768 -nT -1472 -lU3 -16,2,15760 -nT -1474 -lU3 -17,1,0,{1,400 -lU3 -17,1,57,{1,14,lJ -0} -} -,{ProduceNewTree,4,1,538 -nT -41,lQ3 -yK3 -0 -nT -5167,lQ3 -cH -41984 -e22 -lQ3 -cH -tU -lQ3 -cH -eV -lQ3 -cH -eW -cEqual -cN1 -24849,cEqual -eL -tV -cEqual -eL -n52 -281873,cEqual -eL -iP -cEqual -eL -lH1 -lQ3 -yK3 -562 -nT -41,i51,yK3 -538 -nT -5167,i51,cH -41984 -e22 -i51,cH -tU -i51,cH -eV -i51,cH -eW -i51 -cN1 -24849,i51 -eL -tV -i51 -eL -n52 -281873,i51 -eL -iP -i51 -eL -lH1 -i51,cH -tU -yN3 -eV -yN3 -eW -cLess,eN2 -571 -nT -46080,cLess -cN1 -24832,cLess -eL -xW1 -cLess -eL -tV -cLess -eL -n52 -tK3 -cLess -eL -nY1 -cLess -eL -iP -cLess -eL -lH1 -cLess,yL3 -562 -e22 -yN3 -tU -n62 -cH -eV -n62 -cH -eW -n62 -eN2 -565 -nT -409615,cLessOrEq -cN1 -24832,cLessOrEq -eL -xW1 -cLessOrEq -eL -tV -cLessOrEq -eL -n52 -tK3 -cLessOrEq -eL -nY1 -cLessOrEq -eL -iP -cLessOrEq -eL -lH1 -n62 -yL3 -562 -nT -409647,n62 -cH -tU -cF2 -eV -cF2 -eW -cGreater,eN2 -539 -nT -409615 -tV2 -cN1 -24832 -tV2 -eL -xW1 -cGreater -eL -tV -cGreater -eL -n52 -281856 -tV2 -eL -nY1 -cGreater -eL -iP -cGreater -eL -lH1 -cGreater,yL3 -538 -nT -409647,cF2 -tU -y9 -cH -eV -y9 -cH -eW -y9 -eN2 -572 -nT -46080,y9 -nQ2 -529654 -nT -24832,y9 -nQ2 -xW1 -y9 -nQ2 -tV -y9 -nQ2 -n52 -tK3 -y9 -nQ2 -nY1 -y9 -nQ2 -iP -y9 -nQ2 -lH1 -y9 -yL3 -538 -e22 -y9 -yK3 -519,{1,137,cNot,yR3 -571,{1,2,cNot,l2 -0,1,452 -nT -yJ3 -lV3 -0,2,537097,{3,547892744,cAnd,c3 -16,1,566,{1,5,cAnd,AnyParams,1} -} -,{ReplaceParams,16,1,569 -nT -13314,lV3 -16,1,544 -nT -553498,lV3 -16,1,546 -nT -462369,lV3 -16,1,548 -nT -466465,lV3 -0,1,457 -nT -yJ3 -xX1 -570 -nT -13314,xX1 -563 -nT -8197,xX1 -541 -nT -553498,xX1 -542 -nT -462369,xX1 -543 -nT -466465,xX1 -564 -nT -143365,cOr,c3 -4,1,525,{1,137,yS3 -yR3 -572,{1,2,yS3 -l4 -17,1,0,{1,0,yS3 -eN2 -537,{1,256,cAbsNotNot,c3 -18,1,531,{1,254,cAbsNotNot,c3 -0,1,572,{3,43039744,yT3 -tG3 -571,{3,49325056,yT3 -yR3 -454,{3,32513586,yT3 -l2 -16,3,32542225,{3,36732434,yT3 -y71} -,} -;e72 -grammar_optimize_abslogical_type{y3 -9 -cT -grammar_optimize_abslogical_type -grammar_optimize_abslogical={9,{34,192,228,238,242,247,254,260,261} -} -;} -e72 -grammar_optimize_ignore_if_sideeffects_type{y3 -59 -cT -grammar_optimize_ignore_if_sideeffects_type -grammar_optimize_ignore_if_sideeffects={59,{0,20,21,22,23,24,25,26,cO -l42 -78,cP -cU -e72 -grammar_optimize_nonshortcut_logical_evaluation_type{y3 -56 -cT -grammar_optimize_nonshortcut_logical_evaluation_type -grammar_optimize_nonshortcut_logical_evaluation={56,{0,25,cO -l42 -78,cP -241,243,244,245,246,248,249,250,251,252,253,255,256,257,258,259} -} -;} -e72 -grammar_optimize_recreate_type{y3 -22 -cT -grammar_optimize_recreate_type -grammar_optimize_recreate={22,{18,55,56,57,80,81,82,83,84,85,117,118,120,121,130,131,132,133,134,135,136,137} -} -;} -e72 -grammar_optimize_round1_type{y3 -125 -cT -grammar_optimize_round1_type -grammar_optimize_round1={125,{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,19,25,cO -37,38,l42 -45,46,47,48,49,50,51,52,53,54,58,59,60,61,62,63,64,65,66,67,68,69,70,71,78,79,80,81,82,83,84,85,86,87,88,93,94,95,96,97,98,99,100,101,117,118,119,120,121,122,123,124,125,126,127,128,129,138,160,161,162,163,164,165,166,167,168,169,178,179,180,200,204,212,216,224,236,237,239,240,cU -e72 -grammar_optimize_round2_type{y3 -103 -cT -grammar_optimize_round2_type -grammar_optimize_round2={103,{0,15,16,17,25,cO -39,40,l42 -45,46,47,48,49,50,51,52,53,54,59,60,72,73,78,79,86,87,88,89,90,91,92,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,119,122,123,124,125,126,127,128,139,159,160,161,162,163,164,165,166,167,168,169,178,179,180,200,204,212,216,224,236,237,239,240,cU -e72 -grammar_optimize_round3_type{y3 -79 -cT -grammar_optimize_round3_type -grammar_optimize_round3={79,{74,75,76,77,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,170,171,172,173,174,175,176,177,181,182,183,184,185,186,187,188,189,190,191,193,194,195,196,197,198,199,201,202,203,205,206,207,208,209,210,211,213,214,215,217,218,219,220,221,222,223,225,226,227,229,230,231,232,233,234,235} -} -;} -e72 -grammar_optimize_round4_type{y3 -12 -cT -grammar_optimize_round4_type -grammar_optimize_round4={12,{18,55,56,57,130,131,132,133,134,135,136,137} -} -;} -e72 -grammar_optimize_shortcut_logical_evaluation_type{y3 -53 -cT -grammar_optimize_shortcut_logical_evaluation_type -grammar_optimize_shortcut_logical_evaluation={53,{0,25,cO -l42 -78,cP -cU} -l33 -lA1{tK1 -eA2 -ParamSpec_Extract -lT1 -paramlist,lJ1){index=(paramlist>>(index*10))&1023;if(index>=57)return -eA2(SubFunction,cG2 -plist_s[index-57]);if(index>=37)return -eA2(NumConstant,cG2 -plist_n_container -xF::plist_n[index-37])i1 -eA2(ParamHolder,cG2 -plist_p[index]);} -} -#ifdef FP_SUPPORT_OPTIMIZER -#include -#include -#include -#include -using -l33 -FUNCTIONPARSERTYPES;using -l33 -lA1;using -t5;using -nG1;l33{nN1 -It,x93 -T,x93 -Comp>t31 -MyEqualRange(It -first,It -last,const -T&val,Comp -comp){size_t -len=last-first;while(len>0){size_t -xR3 -len/2;It -x23(first);x23+=half;if(comp(*x23,val)){first=x23;++first;len=len-half-1;} -iP1 -comp(val,*x23)){len=half;} -else{It -left(first);{It&eO2=left;It -last2(x23);size_t -len2=last2-eO2;while(len2>0){size_t -half2=len2/2;It -eN3(eO2);eN3+=half2;if(comp(*eN3,val)){eO2=eN3;++eO2;len2=len2-half2-1;} -else -len2=half2;} -} -first+=len;It -right(++x23);{It&eO2=right;It&last2=first;size_t -len2=last2-eO2;while(len2>0){size_t -half2=len2/2;It -eN3(eO2);eN3+=half2;if(comp(val,*eN3))len2=half2;else{eO2=eN3;++eO2;len2=len2-half2-1;} -} -eE3 -t31(left,right);} -eE3 -t31(first,first);} -tK1 -e72 -OpcodeRuleCompare{iD2()iS1 -nP1 -x83 -y72)const{const -Rule&rule=grammar_rules[y72]i1 -t72range=MyEqualRange(tK2.rule_list,tK2.rule_list+tK2.rule_count -cU3,OpcodeRuleCompare -xF());eO3 -x83 -short>rules;rules.xH3 -range.second-range.first);for -y0 -if(IsLogisticallyPlausibleParamsMatch(tM1 -yR2 -cU3))rules -c52*r);} -range.first=!rules -eU3?&rules[0]:0;range.second=!rules -eU3?&rules[rules -eJ3-1]+1:0;if(range.first!=range.second){ -#ifdef DEBUG_SUBSTITUTIONS -if(range.first!=range.second)cH2"Input (" -< -#include -#include -#include -#include /* for auto_ptr */ -using -l33 -FUNCTIONPARSERTYPES;using -l33 -lA1;using -t5;using -nG1;l33{yP1 -TestImmedConstraints -lT1 -bitmask,const -eR{e23 -bitmask&ValueMask){case -Value_AnyNum:case -ValueMask:lC -x62:if(GetEvennessInfo -iS3 -n72 -Value_OddInt:if(GetEvennessInfo -iS3 -x82 -i11:if(GetIntegerInfo -iS3 -n72 -Value_NonInteger:if(GetIntegerInfo -iS3 -x82 -eY1:if(!IsLogicalValue(tree)cQ -nE1 -SignMask){case -Sign_AnySign:lC -nD1:if(l81 -n72 -eZ1:if(l81 -x82 -Sign_NoIdea:if(l81 -Unknown -cQ -nE1 -OnenessMask){case -Oneness_Any:case -OnenessMask:lC -Oneness_One:if(!xY1 -if(!lJ3 -fp_abs(tree -x41),e62 -1))cQ -lC -Oneness_NotOne:if(!xY1 -lG3 -fp_abs(tree -x41),e62 -1))cQ -nE1 -ConstnessMask){case -Constness_Any:lC -i01:if(!xY1 -lC -Constness_NotConst:if(xY1 -xY3 -lD2} -tP1 -x83 -extent,x83 -nbits,x93 -eP2=x83 -int>e72 -nbitmap{private:static -const -x83 -bits_in_char=8;static -const -x83 -eQ2=(sizeof(eP2)*bits_in_char)/nbits;eP2 -data[(extent+eQ2-1)/eQ2];e43 -void -inc(lJ1,int -by=1){data[pos(index)]+=by*eP2(1<>y82)&mask()iT3 -pos(lJ1)yP -index/eQ2 -iT3 -shift(lJ1)yP -nbits*(index%eQ2)iT3 -mask()yP(1<SubTreesDetail;Needs(){std::memset(this,0,sizeof(*this));} -Needs -iS1 -Needs&b){std::memcpy(this,&b,sizeof(b));} -Needs&eM1=iS1 -Needs&b){std::memcpy(this,&b,sizeof(b))i1*this;} -} -yO1 -Needs -CreateNeedList_uncached(eX&tL2{Needs -yQ1;for -lT1 -a=0;aeE1;static -eE1 -yV1;eE1::y83 -i=yV1.xU2&tL2;if(i!=yV1.cX1&tL2 -return -i -eC2 -i1 -yV1.y43,std::make_pair(¶ms,CreateNeedList_uncached -xF(tL2))eC2;} -tK1 -yZ2 -CalculateGroupFunction -iS1 -eA2&yA2 -const -tC -info -yY3 -lX3.first){case -NumConstant:{const -ParamSpec_NumConstant -xF¶m=*iS1 -ParamSpec_NumConstant -xF*tF1 -i1 -CodeTreeImmed -yZ3 -constvalue);} -case -ParamHolder:{cM&yU3 -cM*tF1 -i1 -info.GetParamHolderValueIfFound -yZ3 -index);} -case -SubFunction:{cN&yU3 -cN*tF1 -tX -nS3;nS3 -iH -param.lG1);nS3.lJ2).xH3 -iH3 -y92);for -lT1 -a=0;a0)--yQ1.Immeds;else--iN2;lC -iU2:case -cFCall:case -cPCall:--iN2;break;yF3 -assert(opcode0&&yQ1.SubTreesDetail.get(opcode)>0){--iO2;yQ1.SubTreesDetail.dec(opcode);} -else--iN2;} -} -if(yQ1.Immeds>0||iO2>0||iN2>0)tM2 -if(params.match_type!=AnyParams){if(0||iO2<0||iN2<0)tM2} -lD2} -tK1 -n31 -TestParam -iS1 -eA2&yA2 -const -nP1 -const -cZ&start_at,tC -info -yY3 -lX3.first){case -NumConstant:{const -ParamSpec_NumConstant -xF¶m=*iS1 -ParamSpec_NumConstant -xF*tF1;if(!xY1 -Value_t -imm=tree -x41;switch -yZ3 -modulo){case -Modulo_None:lC -Modulo_Radians:imm=cK3 -imm,yK -immfp_const_pi -xF())imm-=fp_const_twopi -xF(e02 -return -lJ3 -imm,param.constvalue);} -case -ParamHolder:{cM&yU3 -cM*tF1;if(!x3 -return -info.SaveOrTestParamHolder -yZ3 -index -cU3);} -case -SubFunction:{cN&yU3 -cN*tF1;yF -GroupFunction){if(!x3 -yZ2 -xZ1=CalculateGroupFunction(yA2 -info); -#ifdef DEBUG_SUBSTITUTIONS -DumpHashes(xZ1 -lE2*iS1 -void**)&xZ1 -x41;cV2<<"\n" -;cV2<<*iS1 -void**)&tree -x41;cV2<<"\n" -;DumpHashes(tree -lE2"Comparing " -iL2 -xZ1 -lE2" and " -iL2 -tree -lE2": " -;cV2<<(xZ1 -xI -tree)?"true" -:"false" -lE2"\n" -; -#endif -return -xZ1 -xI -tree);} -cJ3!eK1){if(!x3 -if(t72!=param.lG1 -cQ -eE3 -TestParams -yZ3 -data -cU3,start_at,info,false);} -} -eE3 -t23 -tK1 -e72 -l31 -x92 -MatchInfo -xF -info;l31():start_at(),info(){} -} -yO1 -class -MatchPositionSpec_PositionalParams:nQ1 -l31 -xF>{e43 -iX2 -MatchPositionSpec_PositionalParams -iZ1 -n):eF1 -l31 -xF>(n){} -} -;e72 -l72 -x92 -l72():start_at(){} -} -;class -yG:nQ1 -l72>{e43 -x83 -trypos;iX2 -yG -iZ1 -n):eF1 -l72>(n),trypos(0){} -} -yO1 -n31 -TestParam_AnyWhere -iS1 -eA2&yA2 -const -nP1 -const -cZ&start_at,tC -info,cY2&used,bool -iX1{xPx8;x83 -xA2(yG*)eK1;a=x8->trypos;goto -retry_anywhere_2;cO2 -yG -l51);a=0;} -tM3 -yC++a){if(used[a])yA1 -retry_anywhere -yW3 -TestParam(yA2 -xW -a)xS3);yP3 -used[a]=true;if(iX1 -info.SaveMatchedParamIndex(a);x8->trypos=a -i1 -n31(true,&*x8);} -} -retry_anywhere_2 -yX3 -goto -retry_anywhere;} -eE3 -t23 -tK1 -e72 -yD1 -x92 -MatchInfo -xF -info;cY2 -used;iX2 -yD1 -iZ1 -tL3):start_at(),info(),used(tL3){} -} -yO1 -class -MatchPositionSpec_AnyParams:nQ1 -yD1 -xF>{e43 -iX2 -MatchPositionSpec_AnyParams -iZ1 -n,size_t -m):eF1 -yD1 -xF>(n,yD1 -xF(m)){} -} -yO1 -n31 -TestParams(eX&nN,const -nP1 -const -cZ&start_at,tC -info,bool -iX1{if(nN.match_type!=AnyParams){if(xT!=tree.GetParamCount()cQ} -if(!IsLogisticallyPlausibleParamsMatch(nN -cU3))tM2 -e23 -nN.match_type){case -PositionalParams:{xPx8;x83 -xA2(cF*)eK1;a=xT-1;goto -lK1;cO2 -cF(xT);a=0;} -tM3 -xT;++a){(yQ3=info;retry_positionalparams -yW3 -TestParam(cW -a),xW -a)xS3);yP3 -yA1} -} -lK1 -yX3 -info=(yQ3;goto -retry_positionalparams;} -if(a>0){--a;goto -lK1;} -info=c12 -i1 -t23 -if(iX1 -tN3 -info.SaveMatchedParamIndex(a)i1 -n31(true,&*x8);} -case -SelectedParams:case -AnyParams:{xPx8;cY2 -used -l51);eO3 -x83>iY2(xT);eO3 -x83>yB2(xT);tN3{const -eA2 -lX3=cW -a);iY2[a]=ParamSpec_GetDepCode(lX3);} -{x83 -b=0;tN3 -if(iY2[a]!=0)yB2[b++]=a;tN3 -if(iY2[a]==0)yB2[b++]=a;} -x83 -xA2(t6*)eK1;if(xT==0){a=0;goto -retry_anyparams_4;} -a=xT-1;goto -eG1;cO2 -t6(xT -cU3.GetParamCount());a=0;if(xT!=0){c12=info;(*x8)[0].used=used;} -} -tM3 -xT;++a){if(a>0){(yQ3=info;(yO3 -used=used;} -retry_anyparams -yW3 -TestParam_AnyWhere -xF(cW -yB2[a])cU3 -xS3,used,iX1;yP3 -yA1} -} -eG1 -yX3 -info=(yQ3;used=(yO3 -used;goto -retry_anyparams;} -eH1:if(a>0){--a;goto -eG1;} -info=c12 -i1 -t23 -retry_anyparams_4:if(nN.n1!=0){if(!TopLevel||!info.HasRestHolder(nN.n1)){eK -cI2;cI2.reserve -l51);for -lT1 -b=0;b -#include -using -t5;using -nG1;l33{tK1 -yZ2 -yW1 -iS1 -eA2&yA2 -tC -info,bool -inner=true -yY3 -lX3.first){case -NumConstant:{const -ParamSpec_NumConstant -xF¶m=*iS1 -ParamSpec_NumConstant -xF*tF1 -i1 -CodeTreeImmed -yZ3 -constvalue);} -case -ParamHolder:{cM&yU3 -cM*tF1 -i1 -info.GetParamHolderValue -yZ3 -index);} -case -SubFunction:{cN&yU3 -cN*tF1 -tX -tree;tD2 -param.lG1);for -lT1 -a=0;alist=info.GetMatchedParamIndexes();std::sort(list.iJ2 -list.end()iY1 -list -eJ3;a-->0;)tree.i91 -list[a]);for -lT1 -a=0;a -#include -using -l33 -FUNCTIONPARSERTYPES;using -l33 -lA1;using -t5;using -nG1;l33 -lA1{xL1 -DumpMatch(t41 -const -nP1 -const -tC -info,bool -DidMatch,std::ostream&o){DumpMatch -yG2,DidMatch?iX3"match" -:iX3"mismatch" -,o);} -xL1 -DumpMatch(t41 -const -nP1 -const -tC -info,e32 -tO3,std::ostream&o){static -const -char -ParamHolderNames[][2]={"%" -,"&" -,"x" -,"y" -,"z" -,"a" -,"b" -,"c" -} -;o< = " -iL2 -iW3 -eI3[a],o);o< -#include -#ifdef FP_SUPPORT_OPTIMIZER -using -l33 -FUNCTIONPARSERTYPES;l33{yP1 -MarkIncompletes(FPoptimizer_CodeTree::eR{if(tree.Is_Incompletely_Hashed())lD2 -bool -l82 -eW3 -x51 -l82|=MarkIncompletes(xW -a));if(l82)tree.Mark_Incompletely_Hashed()i1 -l82;} -xL1 -FixIncompletes(FPoptimizer_CodeTree::eR{if(tree.Is_Incompletely_Hashed()){x51 -FixIncompletes(xW -a)yB -e33);} -} -} -t5{lB -Sort()iZ3 -Sort();} -lB -e33 -bool -constantfolding){if(constantfolding)ConstantFolding(*this);else -Sort();data -xC -tK1 -e72 -cB -c03 -Value_t -c13 -yE1=0; -#if 0 -long -double -value=Value;e9=crc32::calc(iS1 -x83 -char*)&value,sizeof(value));key^=(key<<24); -#elif 0 -union{e72{x83 -char -filler1[16]iK2 -v;x83 -char -filler2[16];} -buf2;e72{x83 -char -filler3[sizeof -cX3)+16-sizeof(xE1)];e9;} -buf1;} -data;memset(&data,0,sizeof(data));data.buf2.v=Value;e9=data.buf1.key; -#else -int -exponent -iK2 -nR2=std::frexp(Value,&tU2 -e9=lT1(exponent+0x8000)&0xFFFF);if(nR2<0){nR2=-nR2;key=key^0xFFFF;} -else -key+=0x10000;nR2-=yF2;key<<=39;key|=n51(nR2+nR2)*e62 -1u<<31))<<8; -#endif -lP -#ifdef FP_SUPPORT_COMPLEX_NUMBERS -nN1 -T -cJ2 -std::complex >c03 -std::complexc13 -cB::lY3 -cK2,Value.real());nB -fphash_t -temp;cB::lY3 -temp,Value.imag());yE1^=temp.hash2;cK2.hash2^=temp.hash1;} -} -; -#endif -#ifdef FP_SUPPORT_LONG_INT_TYPE -tP1 -cJ2 -long>yD -long -Value){e9=Value;lP -#endif -#ifdef FP_SUPPORT_GMP_INT_TYPE -tP1 -cJ2 -GmpInt>c03 -GmpInt -c13 -e9=Value.toInt();lP -#endif -xL1 -xK2 -xF::Recalculate_Hash_NoRecursion(){fphash_t -cK2(n51 -Opcode)<<56,Opcode*iE3(0x1131462E270012B));Depth=1;e23 -Opcode){case -cImmed:{cB -xF::lY3 -cK2,Value -e02 -case -iU2:{yE1|=n51 -cO1<<48 -lL1((n51 -cO1)*11)^iE3(0x3A83A83A83A83A0);xY3 -case -cFCall:case -cPCall:{yE1|=n51 -cO1<<48 -lL1((~n51 -cO1)*7)^3456789;} -yF3{size_t -t61=0 -e73 -0;at61)t61=iT2 -nP2;yE1+=((iT2.tN2 -hash1*(a+1))>>12)lL1 -iT2.tN2 -hash1 -lL1(3)*iE3(0x9ABCD801357);cK2.hash2*=iE3(0xECADB912345)lL1(~iT2.tN2 -hash2)^4567890;} -Depth+=t61;} -} -if(Hash!=cK2){Hash=cK2;lM2=0;} -} -lB -tE3{MarkIncompletes(*this);FixIncompletes(*this);} -} -#endif -#include -#include -#include -#ifdef FP_SUPPORT_OPTIMIZER -using -l33 -FUNCTIONPARSERTYPES;l33{using -t5 -yO1 -bool -x01 -const -nP1 -long -count,const -xK1::SequenceOpCode -xF&eQ,xK1::eP3&synth,size_t -max_bytecode_grow_length);static -const -e72 -SinCosTanDataType{OPCODE -whichopcode;OPCODE -inverse_opcode;enum{eR2,nS2,nZ1,lM1} -;OPCODE -codes[4];} -SinCosTanData[12]={{cTan,cCot,{cSin,cCos,cCsc,cSec} -} -,{cCot,cCot,{cCos,cSin,cSec,cCsc} -} -,{cCos,cSec,{cSin,cTan,cCsc,cCot} -} -,{cSec,cCos,{cTan,cSin,cCot,cCsc} -} -,{cSin,cCsc,{cCos,cCot,cSec,cTan} -} -,{cCsc,cSin,{cCot,cCos,cTan,cSec} -} -,{cL2{tD3 -cCosh,cM2,{tD3 -cNop,{cL2 -cNop,cCosh} -} -,{cCosh,cNop,{tD3 -cL2 -cNop} -} -,{cNop,cTanh,{cCosh,tD3 -cM2,{cNop,tD3{cNop,cTanh,cCosh,cNop} -} -,{cNop,cCosh,{cTanh,tD3 -cM2} -;} -t5{lB -SynthesizeByteCode(eO3 -x83>&eN1,std -xM3 -xF&Immed,size_t&stacktop_max){ -#ifdef DEBUG_SUBSTITUTIONS -cV2<<"Making bytecode for:\n" -;l21 -#endif -while(RecreateInversionsAndNegations()){ -#ifdef DEBUG_SUBSTITUTIONS -cV2<<"One change issued, produced:\n" -;l21 -#endif -tE3;using -nG1;using -l33 -lA1;const -void*g=cG2 -grammar_optimize_recreate;while(ApplyGrammar(*iS1 -Grammar*)g,*this)){tE3;} -} -#ifdef DEBUG_SUBSTITUTIONS -cV2<<"Actually synthesizing, after recreating inv/neg:\n" -;l21 -#endif -xK1::eP3 -synth;SynthesizeByteCode(synth,false -iM2.Pull(eN1,Immed,stacktop_max);} -lB -SynthesizeByteCode(xK1::eP3&synth,bool -MustPopTemps)const{y01*this))yP;} -for -iZ1 -a=0;a<12;++a){const -SinCosTanDataType&data=SinCosTanData[a];if(data.whichopcode!=cNop)iC1!=data.whichopcode)yA1 -c02 -lZ3;lZ3.xA1);lZ3 -iH -data.inverse_opcode);lZ3.yC2);y01 -lZ3)){synth.tQ -else -iC1!=cInv)yA1 -if(GetParam(0)nC!=data.inverse_opcode)yA1 -y01 -GetParam(0))){synth.tQ -size_t -found[4];e11 -4;++b){c02 -tree;if(data.tP3]==cNop){tD2 -cInv);c02 -n03;n03.xA1);n03 -iH -data.tP3^2]);n03.yC2 -c81 -n03);} -else{tree.xA1 -yB -eL3 -data.tP3]);} -tree.yC2);found[b]=synth.xK3 -tree);} -if(found[data.eR2 -e3 -nS2 -tG -eR2]iM2.yT -nS2]);yB1 -cDiv -tW -eR2 -e3 -lM1 -tG -eR2]iM2.yT -lM1]);yB1 -cMul -tW -nZ1 -e3 -lM1 -tG -nZ1]iM2.yT -lM1]);yB1 -cRDiv -tW -nZ1 -e3 -nS2 -tG -nZ1]iM2.yT -nS2]);yB1 -cMul,2,1 -iM2.tQ -size_t -n_subexpressions_synthesized=SynthCommonSubExpressions(c92 -e23 -l92{case -iU2:synth.PushVar(GetVar());lC -cImmed:t71 -GetImmed());lC -cAdd:case -cMul:case -cMin:case -cMax:case -cAnd:case -cOr:case -cAbsAnd:case -cAbsOr:iC1==cMul){bool -c23 -eW3 -yH -lX1 -tD1&&isLongInteger(lX1 -x41)){c11=makeLongInteger(lX1 -x41);c02 -tmp(*this,x93 -c02::CloneTag());tmp.i91 -a);tmp -iW1;if(x01 -tmp,value,xK1::tU1 -xF::AddSequence,synth,MAX_MULI_BYTECODE_LENGTH)){c23=true;xY3} -} -if(c23)xY3 -int -yF1=0;cY2 -done(GetParamCount(),false);c02 -iQ;iQ -iH -l92;for(;;){bool -found -eW3 -yH -done[a])yA1 -if(synth.IsStackTop(lX1)){found=true;done[a]=true;lX1.n7 -iQ -cS -lX1);if(++yF1>1){yU -2);iQ.yC2)yC1 -iQ);yF1=yF1-2+1;} -} -} -if(!found)xY3 -yH -done[a])yA1 -lX1.n7 -iQ -cS -lX1);if(++yF1>1){yU -2);iQ.yC2)yC1 -iQ);yF1=yF1-2+1;} -} -if(yF1==0 -yY3 -l92{case -cAdd:case -cOr:case -cAbsOr:t71 -0);lC -cMul:case -cAnd:case -cAbsAnd:t71 -1);lC -cMin:case -cMax:t71 -0);break;yF3 -xY3++yF1;} -assert(n_stacked==1);xY3 -case -cPow:{tW1 -p0 -i42 -0);tW1 -p1 -i42 -1);if(!p1 -tD1||!isLongInteger -cR3||!x01 -p0,makeLongInteger -cR3,xK1::tU1 -xF::MulSequence,synth,MAX_POWI_BYTECODE_LENGTH)){p0.n7 -p1.n7 -yU -2);e21 -cIf:case -cAbsIf:{x93 -xK1::eP3::IfData -ifdata;GetParam(0)e93 -SynthIfStep1(ifdata,l92;GetParam(1)e93 -SynthIfStep2(ifdata);GetParam(2)e93 -SynthIfStep3(ifdata -e02 -case -cFCall:case -cPCall:{for -iZ1 -a=0;a0){size_t -top=synth.GetStackTop(iM2.DoPopNMov(top-1-n_subexpressions_synthesized,top-1);} -} -} -l33{yP1 -x01 -const -nP1 -long -count,const -xK1::SequenceOpCode -xF&eQ,xK1::eP3&synth,size_t -max_bytecode_grow_length){if -cW3!=0){xK1::eP3 -backup=synth;tree.n7 -size_t -bytecodesize_backup=synth.GetByteCodeSize();xK1::x01 -count -e63 -size_t -bytecode_grow_amount=synth.GetByteCodeSize()-bytecodesize_backup;if(bytecode_grow_amount>max_bytecode_grow_length){synth=backup -i1 -t23 -lD2} -else{xK1::x01 -count,eQ,synth -yQ2} -} -#endif -#include -#include -#ifdef FP_SUPPORT_OPTIMIZER -using -l33 -FUNCTIONPARSERTYPES;l33{using -t5; -#define FactorStack std xM3 -const -e72 -PowiMuliType{x83 -opcode_square;x83 -opcode_cumulate;x83 -opcode_invert;x83 -opcode_half;x83 -opcode_invhalf;} -iseq_powi={cSqr,cMul,cInv,cSqrt,cRSqrt} -,iseq_muli={l52 -x9 -cNeg,l52,l52} -yO1 -Value_t -cP1 -const -PowiMuliType&c33,const -std -nA3,n82&stack)eQ3 -1);while(IPxH1&&isEvenInteger(eT3 -yF2;yZ -opcode_invhalf){if(nS3>xH1&&isEvenInteger(eT3 -e62-0.5);++IP;yA1} -size_t -xB2=IP -iK2 -lhs(1);if(n13 -cFetch){lJ1=n43;if(index=lB2){IP=xB2;xY3 -lhs=stack[index-y2];goto -yD2;} -if(n13 -cDup){lhs=nS3;goto -yD2;yD2:t91 -nS3);++IP -iK2 -subexponent=cP1 -c33 -iK -if(IP>=limit||eN1[IP]!=c33.opcode_cumulate){IP=xB2;xY3++IP;stack.pop_back();nS3+=lhs*subexponent;yA1} -xY3 -return -nS3;} -tK1 -Value_t -ParsePowiSequence -iS1 -std -nA3){n82 -stack;t91 -e62 -1))i1 -cP1 -iseq_powi -iK} -tK1 -Value_t -ParseMuliSequence -iS1 -std -nA3){n82 -stack;t91 -e62 -1))i1 -cP1 -iseq_muli -iK} -tK1 -class -CodeTreeParserData{e43 -iX2 -CodeTreeParserData(bool -k_powi):stack(),clones(),keep_powi(k_powi){} -void -Eat -iZ1 -tL3,OPCODE -opcode -nQ -xM;xM -iH -opcode);eK -params=Pop(tL3 -yR1 -tL2;if(!keep_powi)e23 -opcode){case -cTanh:{yZ2 -sinh,cosh;sinh -iH -cSinh);sinh -cS -xM -c43 -sinh -iW1;cosh -iH -cCosh);cosh -c91 -xM -c43 -cosh -iW1 -tX -pow;pow -iH -cPow);pow -c91 -cosh);pow.yA -nU2));pow -iW1;xM -iH -cMul);xM.nB1 -0,sinh);xM -c91 -pow -e02 -case -cTan:{yZ2 -sin,cos;sin -iH -cSin);sin -cS -xM -c43 -sin -iW1;cos -iH -cCos);cos -c91 -xM -c43 -cos -iW1 -tX -pow;pow -iH -cPow);pow -c91 -cos);pow.yA -nU2));pow -iW1;xM -iH -cMul);xM.nB1 -0,sin);xM -c91 -pow -e02 -case -cPow:{iT1&p0=xM -l8 -0);iT1&p1=xM -l8 -1);if(p1 -nC==cAdd){eK -mulgroup(p1.GetParamCount()iY1 -0;a" -<void -Push(T -tree){ -#ifdef DEBUG_SUBSTITUTIONS -cV2<0;){iA1 -iL2 -nS3[n]);iB1 -nS3[n]);} -#endif -stack -xF3 -lB2-n_pop)i1 -nS3;} -size_t -GetStackTop(c01 -lB2;} -private:void -FindClone(yZ2&,bool=true)yP;} -private:eK -stack;std::multimapclones;bool -keep_powi;private:CodeTreeParserData -iS1 -CodeTreeParserData&);CodeTreeParserData&eM1=iS1 -CodeTreeParserData&);} -yO1 -e72 -IfInfo{yZ2 -eS2 -tX -thenbranch;size_t -endif_location;IfInfo():eS2(),thenbranch(),endif_location(){} -} -;} -t5{lB -GenerateFrom -iS1 -x93 -FunctionParserBase -xF::Data&x33,bool -keep_powi){eK -xH2;xH2.xH3 -x33.mVariablesAmount);for -lT1 -n=0;n&eN1=x33.mByteCode;const -std -xM3 -xF&Immed=x33.mImmed; -#ifdef DEBUG_SUBSTITUTIONS -cV2<<"ENTERS GenerateFrom()\n" -; -#endif -CodeTreeParserData -xF -sim(keep_powi);eO3 -IfInfo -xF>eJ -eK3 -IP=0,DP=0;;++IP){tO2:while(!eJ -eU3&&(eJ.eA==IP||(IP=n41)break;x83 -opcode=eN1[IP];if(eS3 -cSqr||opcode==cDup||eS3 -cInv&&!IsIntType -xF::nS3)||opcode==cNeg||opcode==cSqrt||opcode==cRSqrt||opcode==cFetch)){size_t -was_ip=IP -iK2 -eD2 -ParsePowiSequence -xF(eN1,IP,eJ -eU3?n41:eJ.eA,sim.xH -1);if(exponent!=e62 -1.0)){xG -exponent -iU3);goto -tO2;} -if -eS3 -cDup||opcode==cFetch||opcode==cNeg)l14 -xT2=ParseMuliSequence -xF(eN1,IP,eJ -eU3?n41:eJ.eA,sim.xH -1);if(xT2!=e62 -1.0)){xG -xT2)yR -2,cMul);goto -tO2;} -} -IP=was_ip;} -if(nB2>=iU2){lJ1=opcode-iU2 -nA2 -xH2[index]);} -else{e23 -nB2){case -cIf:case -cAbsIf:{eJ -xF3 -eJ -eJ3+1);c02 -res(sim.yE2);eJ.back().eS2.swap(res);eJ.eA=n41;IP+=2;yA1} -case -cJump:{c02 -res(sim.yE2);eJ -e81.swap(res);eJ.eA=eN1[IP+1]+1;IP+=2;yA1} -case -cImmed:xG -Immed[DP++]);lC -cDup:sim.Dup();lC -cNop:lC -cFCall:{x83 -funcno=n43;assert(funcno -#ifdef FP_SUPPORT_OPTIMIZER -#include -#define FP_MUL_COMBINE_EXPONENTS -l33{using -l33 -FUNCTIONPARSERTYPES;using -t5 -yO1 -static -void -AdoptChildrenWithSameOpcode(eR{ -#ifdef DEBUG_SUBSTITUTIONS -bool -nT2 -eW3 -#endif -for -l41 -if(xW -a)nC==t72){ -#ifdef DEBUG_SUBSTITUTIONS -if(!nT2)cH2"Before assimilation: " -cR -nT2=true;} -#endif -tree.AddParamsMove(xW -a).GetUniqueRef().lJ2),a);} -#ifdef DEBUG_SUBSTITUTIONS -if(nT2)cH2"After assimilation: " -cR} -#endif -} -} -t5{xL1 -ConstantFolding(eR{tree.Sort(); -#ifdef DEBUG_SUBSTITUTIONS -void*c63=0;cV2<<"[" -<<(&c63)<<"]Runs ConstantFolding for: " -cR -DumpHashes(tree -lE2 -std::flush; -#endif -if(false){redo:;tree.Sort(); -#ifdef DEBUG_SUBSTITUTIONS -cV2<<"[" -<<(&c63)<<"]Re-runs ConstantFolding: " -cR -DumpHashes(tree); -#endif -} -if(t72!=cImmed){yD3 -p=CalculateResultBoundaries(tree);if(p -yI&&p -e61&&p -yM==p -tG1{nU -p -yM);nD} -if(false){ReplaceTreeWithOne:nU -e62 -1));goto -do_return;ReplaceTreeWithZero:nU -xG1;goto -do_return;ReplaceTreeWithParam0: -#ifdef DEBUG_SUBSTITUTIONS -cV2<<"Before replace: " -;cV2<1||(lC2==1&&lJ3 -nH1,e62 -1))))nI1=true;if(nI1){ -#ifdef DEBUG_SUBSTITUTIONS -cV2<<"cMul: Will add new " -iJ3 -nH1<<"\n" -; -#endif -for -l41 -if(xW -tC1{ -#ifdef DEBUG_SUBSTITUTIONS -cV2<<" - For that, deleting " -iJ3 -xW -a)x41;cV2<<"\n" -; -#endif -tU3(!lJ3 -nH1,e62 -1)))tree -cS -eA1 -nH1));c73 -l51){case -0:iD -1:n73 -yF3 -if(ConstantFolding_MulGrouping(tB2 -if(ConstantFolding_MulLogicItems(tB2 -e21 -cAdd -cK -Value_t -nD2=0.0;size_t -lC2=0;bool -nI1 -eW3 -x51{if(!xW -tC1 -yA1 -Value_t -immed=xW -a)x41;nD2+=immed;++lC2;} -if(lC2>1||(lC2==1&&nD2==xG1)nI1=true;if(nI1){ -#ifdef DEBUG_SUBSTITUTIONS -cV2<<"cAdd: Will add new " -iJ3 -nD2<<"\n" -;cV2<<"In: " -cR -#endif -for -l41 -if(xW -tC1{ -#ifdef DEBUG_SUBSTITUTIONS -cV2<<" - For that, deleting " -iJ3 -xW -a)x41;cV2<<"\n" -; -#endif -tU3(!(nD2==e62 -0.0)))tree -cS -eA1 -nD2));c73 -l51){case -0 -t7 -1:n73 -yF3 -if(ConstantFolding_AddGrouping(tB2 -if(ConstantFolding_AddLogicItems(tB2 -e21 -cMin -cK -size_t -yI2=0;yD3 -e4;x51{while(a+1=e4 -tG1 -tU3 -l51==1){n73 -e21 -cMax -cK -size_t -yI2=0;yD3 -eY;x51{while(a+1eY -yM)){eY -yM=p -yM;eY -yI=true;yI2=a;} -} -if(eY -yI){for -l41{yE3 -max.cF3 -a!=yI2&&(p -tG1=tE1 -xG1;nD} -if(eI1 -lJ3 -xW -i8,xG1){if(p0 -e61&&(p0 -tG1xG1{nU -fp_const_pihalf -cH3} -if -lI -fp_atan2 -e51 -if((p1 -yI&&p1 -yM>xG1||(p1 -e61&&(p1 -tG1e62);bool -crosses_axis=has_negative&&has_positive;cI1 -xF -newmax;if(min.cF3 -cG3)newmax.set(fp_max(i61,i71);if(crosses_axis -cI3 -e62));cJ3 -min.cF3 -cG3 -cI3 -fp_min(i61,i71);iP1 -min.known -cI3 -i61);else -min.set(i71;} -max=newmax;} -xL1 -yD3::set_neg(){std::swap(min,max);min.val=-min.val;max.val=-max.val;} -yP1 -IsLogicalTrueValue -iS1 -yD3&p,bool -abs){if(nB -IsIntType -xF::nS3){if(p -yI&&p -yM>=e62 -1))lD2 -if(!abs&&p -e61 -t43<=nU2)lD2} -cJ3 -p -yI&&p -yM>=yF2)lD2 -if(!abs&&p -e61 -t43<=e62-0.5))lD2 -eE3 -t23 -yP1 -IsLogicalFalseValue -iS1 -yD3&p,bool -abs){if(nB -IsIntType -xF::nS3){if(abs)eG3 -e61 -l61 -1);else -eG3 -yI&&p -e61&&p -yM>nU2 -l61 -1);} -cJ3 -abs)eG3 -e61 -l61 -0.5);else -eG3 -yI&&p -e61&&p -yM>e62-0.5)l61 -0.5);} -} -} -#endif -#ifdef FP_SUPPORT_OPTIMIZER -using -l33 -FUNCTIONPARSERTYPES;using -t5;t5{tK1 -yD3 -CalculateResultBoundaries -iS1 -eR -#ifdef DEBUG_SUBSTITUTIONS_extra_verbose -{using -l33 -FUNCTIONPARSERTYPES;yD3 -tmp=CalculateResultBoundaries_do(tree -lE2"Estimated boundaries: " -;if(tmp -yI)cV2<=nU2)?fp_acos(m -yM):fp_const_pi -xF());} -case -cAsin:tW3 -min.n3-1),fp_asin,yH1 -yM -tR3 -cLess -tH1 -fp_asin,yH1 -tG1;tK -cAtan:tW3 -min.set(fp_atan,yH1 -yM);tO -set(fp_atan,yH1 -tG1;tK -cAtan2:{nP&&lJ3 -lR,xG1)yP -abs_pi_limits;} -if(eI1 -lJ3 -xW -i8,xG1)yP -yH1;eE3 -pi_limits;} -case -cSin:lD -bool -x11=!m -yI||!tO -known||(tO -val-m -yM)>=(yK -x11)tM -Value_t -min=cK3 -m -yM,yK -min=fp_const_pihalf -xF());bool -nJ1=(min<=cD&&max>=cD);if(y21&&nJ1)tM -if(nJ1)nM -nU2,nW2 -if(y21)nM -yL2 -e62 -1));nM -yL2 -nW2} -case -cCos:lD -if(m -yI)m -yM+=fp_const_pihalf -xF();if(xI2 -tO -val+=fp_const_pihalf -xF();bool -x11=!m -yI||!tO -known||(tO -val-m -yM)>=(yK -x11)tM -Value_t -min=cK3 -m -yM,yK -min=fp_const_pihalf -xF());bool -nJ1=(min<=cD&&max>=cD);if(y21&&nJ1)tM -if(nJ1)nM -nU2,nW2 -if(y21)nM -yL2 -e62 -1));nM -yL2 -nW2} -case -cTan:{nM);} -case -cCeil:lD -tO -i81 -cFloor:lD -m -yI1 -tK -cTrunc:lD -m -yI1 -tO -i81 -cInt:lD -m -yI1 -tO -i81 -cSinh:tW3 -min.set(fp_sinh);tO -set(fp_sinh);tK -cTanh:tW3 -min.set(fp_tanh,plusminus1_limits.min);tO -set(fp_tanh,plusminus1_limits.max);tK -cCosh:lD -if(m -yI){if(xI2{if(m -yM>=xH1&&tO -val>=xG1{m -yM -xS} -iP1(m -yM)=xG1 -l14 -tmp -xS -if(tmp>tO -val)tO -val=tmp;m -yM=e62 -1);} -else{m -yM -xS -std::swap(m -yM,tO -val);} -} -cJ3 -m -yM>=xG1{m.tL -m -yM=fp_cosh(m -yM);} -else{m.tL -m -yM=e62 -1);} -} -} -else{m -yI=true;m -yM=e62 -1);if(xI2{m -yM=fp_cosh(tO -val);m.tL} -else -m.tL} -tK -cIf:case -cAbsIf:{yD3 -res1=tZ -1));yD3 -res2=tZ -2));if(!res2 -yI)res1 -yI -eW3 -iP1 -res1 -yI&&(res2 -yM)res1 -tG1 -res1 -nL3=res2 -nL3 -i1 -res1;} -case -cMin:{bool -iT -eW3 -bool -iU -eW3 -e83;x7 -m -tZ3 -m -yI)iT -iN3 -yI||(m -yM)nF3)nF3=m -yM;if(!xI2 -iU -iN3 -e61||tO -val>nG3 -nH3=tO -val;} -if(iT)nK3 -iU)nQ3 -return -nR3 -cAdd:{e83(xH1,xG1;x7 -item=tZ -a));if(item -yI)nF3+=item -yM;else -nK3 -item -e61)nH3+=item -nL3;else -nQ3 -if(!nI3&&!nJ3)xY3 -if(nI3&&nJ3&&nF3>nG3 -std::swap(nF3,nG3 -i1 -nR3 -cMul:{e72 -Value{enum -nT3{tT2,lG2,PlusInf} -;nT3 -eB -iK2 -value;Value(nT3 -t):eB(t),value(0){} -Value -cX3 -v):eB(tT2),value(v){} -bool -cQ2 -c01 -eB==lG2||(eB==tT2&&valuenG3 -std::swap(nF3,nG3 -i1 -nR3 -cMod:{yD3 -x=tZ -yP2 -y=tZ -1));if(y -e61){if(y -nL3>=xG1{if(!x -yI||(x -yM)=xG1 -nM -y -nL3,-y -tG1;i03 -y -nL3,fp_const_negativezero -xF());} -} -i03);} -case -cPow:{if(eI1 -xW -i8==xG1{nM -nM3} -nP&&lR==xG1{nM -xH1,xG1;} -nP&&lJ3 -lR -nH2 -nM -nM3} -if(eI1 -xW -i8>xH1&&GetEvennessInfo(xW -1))==iF2)l14 -eD2 -xW -i8;yD3 -tmp=tZ -yP2 -nS3;nI3=true;nF3=0;if(tmp -yI&&tmp -yM>=xG1 -nF3=t33 -tmp -yM,tU2 -iP1 -tmp -e61&&tmp -nL3<=xG1 -nF3=t33 -tmp -nL3,tU2 -nQ3 -if(tmp -yI&&tmp -e61){nJ3=true;nH3=fp_max(fp_abs(tmp -yM),fp_abs(tmp -tG1);nH3=t33 -nH3,tU2 -eE3 -nS3;} -yD3 -tY -xW -yP2 -p1=tZ -1));TriTruthValue -p0_positivity=cN3(p0 -yM)>=xG1?iF2:(p0 -e61&&(p0 -tG1=xG1{eZ=iF2;} -xY3} -c73(eZ -tN1 -l14 -min=xH1;if -cN3 -p1 -yI){min=t33 -p0 -yM,p1 -yM);if(p0 -yM=xG1&&min>=xG1 -min=xH1;} -if -cN3 -p0 -yM>=xH1&&p0 -e61&&p1 -e61)l14 -max=t33 -p0 -nL3,p1 -tG1;if(min>max)std::swap(min,max);nM -min,max);} -nM -min,false);} -case -l03{nM -false,fp_const_negativezero -xF());} -yF3{xY3 -e21 -cNeg:tW3 -set_neg();tK -cSub:yJ -cNeg);tmp2 -tX3 -tmp -iH -cAdd);tmp -tY3 -tmp -c91 -tmp2 -i0 -cInv:{c02 -lW-1))i0 -cDiv:yJ -cInv);tmp2 -tX3 -tmp -iH -xC1 -AddParamMove(tmp2 -i0 -cRad:yV -xC1 -yA -fp_const_rad_to_deg -xF())i0 -cDeg:yV -xC1 -yA -fp_const_deg_to_rad -xF())i0 -cSqr:{c02 -lW -2))i0 -cExp:yV -cPow);tmp.yA -fp_const_e -xF()));tmp.nJ -0)i0 -cExp2:yV -cPow);tmp.yA -nX3 -tmp.nJ -0)i0 -cCbrt:tW3 -min.set(fp_cbrt);tO -set(fp_cbrt);tK -cSqrt:lD -if(m -yI)m -yM=(m -yM) -#endif -l33 -xK1{extern -const -x83 -char -powi_table[256];} -l33{using -t5 -yO1 -bool -IsOptimizableUsingPowi(long -immed,long -penalty=0){xK1::eP3 -synth;synth.PushVar(iU2);size_t -bytecodesize_backup=synth.GetByteCodeSize();xK1::x01 -immed,xK1::tU1 -xF::MulSequence,c92 -size_t -bytecode_grow_amount=synth.GetByteCodeSize()-bytecodesize_backup -i1 -bytecode_grow_amount0 -t82 -cCbrt);t92);tmp.e33 -xD2--tZ2;} -while(tY2>0 -t82 -cSqrt);if(l13){tmp -iH -cRSqrt);l13 -eW3} -t92);tmp.e33 -xD2--tY2;} -if(l13 -t82 -cInv);t92 -xD2} -} -tK1 -e72 -RootPowerTable{static -const -Value_t -RootPowers[(1+4)*(1+3)];} -yO1 -const -Value_t -t9(1+4)*(1+3)]={e62 -1)lS -2)lS -2*2)lS -2*2*2)lS -2*2*2*2)lS -3)lS -3*2)lS -3*2*2)lS -3*2*2*2)lS -3*2*2*2*2)lS -3*3)lS -3*3*2 -yG3 -yG3*2 -yG3*2*2)lS -3*3*3 -eY2 -eY2*2 -eY2*2*2 -eY2*2*2*2)} -;e72 -PowiResolver{static -const -x83 -MaxSep=4;static -x03 -i13=5;typedef -int -cO3;typedef -long -x43;typedef -long -tP;e72 -yS2{yS2():n_int_sqrt(0),n_int_cbrt(0),sep_list(),n01(0){} -int -n_int_sqrt;int -n_int_cbrt;int -tT1 -MaxSep];tP -n01;} -yO1 -static -yS2 -CreatePowiResult -cX3 -exponent){yS2 -nS3;cO3 -tA=FindIntegerFactor(tU2 -if(tA==0){ -#ifdef DEBUG_POWI -i02"no factor found for %Lg\n" -,(cP3); -#endif -return -nS3;} -nS3.n01=y31 -exponent,tA);x43 -eT2=EvaluateFactorCost(tA,0,0,0)+cC -nS3.n01);int -s_count=0;int -i23=0;int -nZ3=0; -#ifdef DEBUG_POWI -i02"orig = %Lg\n" -,(cP3);i02"plain factor = " -iL3"%ld\n" -,(int)tA,(long)eT2); -#endif -for -lT1 -n_s=0;n_s=i13)break; -#endif -int -n_sqrt=s%i13;int -n_cbrt=s/i13;if(n_sqrt+n_cbrt>4)yA1 -Value_t -lN1=exponent;lN1-=t9 -s];iE1=FindIntegerFactor(lN1);if(xT2!=0){tP -xN=y31 -lN1,xT2);x43 -cost=EvaluateFactorCost(xT2,s_count+n_sqrt,i23+n_cbrt,nZ3+1)+cC -xN); -#ifdef DEBUG_POWI -i02"Candidate sep %u (%d*sqrt %d*cbrt)factor = " -iL3"%ld (for %Lg to %ld)\n" -,s,n_sqrt,n_cbrt,xT2,(long)cost -cX2 -lN1,(long)xN); -#endif -if(cost%Lg\n" -,xD,xD%i13,xD/i13,yX1,yK1 -cX2(exponent)cX2(exponent-t9 -xD])); -#endif -nS3.tT1 -n_s]=xD -eX3-=t9 -xD];s_count+=xD%i13;i23+=xD/i13;eT2=yK1;tA=yX1;nZ3+=1;} -nS3.n01=y31 -exponent,tA); -#ifdef DEBUG_POWI -i02"resulting exponent is %ld (from exponent=%Lg, best_factor=%Lg)\n" -,nS3.n01,(cP3 -cX2 -tA); -#endif -while(tA%2==0){++nS3 -e52;tA/=2;} -while(tA%3==0){++nS3.n_int_cbrt;tA/=3;eE3 -nS3;} -private:static -x43 -cC -tP -xN){static -std::map -cS2 -iM;if(xN<0){x43 -cost=22 -i1 -cost+cC-xN);} -std::map -cS2::y83 -i=iM.xU2 -xN);if(i!=iM.cX1 -xN)return -i -eC2;std::pair -cS2 -nS3(xN,0.0);x43&cost=nS3.i63 -while(xN>1){int -xT2=0;if(xN<256){xT2=xK1::powi_table[xN];if(xT2&128)xT2&=127;else -xT2=0;if(xT2&64)xT2=-(xT2&63)-1;} -if(xT2){cost+=cC -xT2);xN/=xT2;yA1} -if(!(xN&1)){xN/=2;cost+=6;} -else{cost+=7;xN-=1;} -} -iM.y43,nS3)i1 -cost;} -cB1 -tP -y31 -yL1,iE1)yP -makeLongInteger(value*e62 -xT2));} -cB1 -bool -yM1 -yL1,iE1)l14 -v=value*e62 -xT2)i1 -isLongInteger(v);} -cB1 -cO3 -FindIntegerFactor(yL1){iE1=(2*2*2*2); -#ifdef CBRT_IS_SLOW -#else -xT2*=(3*3*3); -#endif -cO3 -nS3=0;if(yM1 -value,xT2)){nS3=xT2;while((xT2%2)==0&&yM1 -value,xT2/2))nS3=xT2/=2;while((xT2%3)==0&&yM1 -value,xT2/3))nS3=xT2/=3;} -#ifdef CBRT_IS_SLOW -if(nS3==0){if(yM1 -value,3 -y03 -3;} -#endif -return -nS3;} -static -int -EvaluateFactorCost(int -xT2,int -s,int -c,int -nmuls){x03 -x13=6; -#ifdef CBRT_IS_SLOW -x03 -eU2=25; -#else -x03 -eU2=8; -#endif -int -nS3=s*x13+c*eU2;while(xT2%2==0){xT2/=2;nS3+=x13;} -while(xT2%3==0){xT2/=3;nS3+=eU2;} -nS3+=nmuls -i1 -nS3;} -} -;} -t5{yP1 -yZ2::RecreateInversionsAndNegations(bool -prefer_base2){bool -changed=false -e73 -0;a0;nQ&powgroup=lX1;if(powgroup -i12 -tI -0)i22 -tI -1)tD1 -nQ&log2=tI -0);log2.lD1 -log2 -iH -cQ3);log2.yA -t33 -immeds,e62 -1)/xE2)));log2 -iW1;xY3} -} -} -for -iZ1 -a=tI1 -i12 -tI -1)tD1){iT1&exp_param=tI -1)iK2 -eD2 -exp_param -x41;if(cZ1,nU2)){lD1 -nE2 -c52 -lX1 -c43 -yN1 -iP1 -exponent=cF1 -nP2 -tC2 -cDiv -iG1 -tN -cF1);} -else{eL3 -cRDiv)tN -cF1 -iG1;} -} -} -if(nF2.nX2 -nQ -iG -l92;cA1 -SetParamsMove -eM -while(cA1 -RecreateInversionsAndNegations(prefer_base2))cA1 -tE3;eL3 -cQ3)tN -nF2 -iG1;yS1} -if(cR1.nX2 -nQ -iG -cMul);mulgroup -c91 -cR1 -l8 -1));cA1 -AddParamsMove -eM -while(cA1 -RecreateInversionsAndNegations(prefer_base2))cA1 -tE3;DelParams();eL3 -cQ3)tN -cR1 -l8 -0)iG1;yS1 -e21 -cAdd:{eK -i32 -e73 -l91 -a-->0;)if(eY3 -cMul){nG2 -y41:tX&mulgroup=cT2 -for -iZ1 -b=cA1 -l91 -b-->0;){if -eH2 -l8 -b).lV1 -xT2=mulgroup -l8 -b)x41;lG3 -xT2 -xU -y41;} -cA1 -lD1 -cA1 -i91 -b -tA2 -iP1 -lJ3 -xT2,e62-2)))eN -y41;} -cA1 -lD1 -cA1 -i91 -b);cA1 -yA -e62 -2))tA2} -} -if(t0){cA1 -tB -mulgroup);yN1} -iP1 -eY3 -cDiv&&!IsIntType -xF::nS3){nG2 -y51:tX&cF1=cT2 -if(cF1 -l8 -0)tD1){lG3 -cF1 -l8 -0)x41 -xU -y51;} -cF1.lD1 -cF1.i91 -0);cF1 -iH -cInv -tA2} -if(t0)eN -y51;} -cF1.tB -cF1);yN1} -iP1 -eY3 -cRDiv&&!IsIntType -xF::nS3){nG2 -xD1:tX&cF1=cT2 -if(cF1 -l8 -1)tD1){lG3 -cF1 -l8 -i8 -xU -xD1;} -cF1.lD1 -cF1.i91 -1);cF1 -iH -cInv -tA2} -if(t0)eN -xD1;} -cF1.tB -cF1);yN1} -if(!i32 -eU3){ -#ifdef DEBUG_SUBSTITUTIONS -i02"Will make a Sub conversion in:\n" -);fflush(stdout);l21 -#endif -yZ2 -yT2;yT2 -iH -cAdd);yT2 -iF1 -i32);yT2 -iW1 -tX -cS1;cS1 -iH -cAdd);cS1 -iF1 -lJ2));cS1 -iW1;if(cS1 -tD1&&lJ3 -cS1 -x41,xG1 -tC2 -cNeg);eC);} -cJ3 -cS1 -nP2==1 -tC2 -cRSub);eC)eV3} -iP1 -yT2 -nC==cAdd -tC2 -cSub)eV3 -eC -l8 -0)iY1 -1;a0){lH2=true;} -#ifdef DEBUG_POWI -i02"Will resolve powi %Lg as powi(chain(%d,%d),%ld)" -cX2 -fp_abs -cR3,r -e52,r.n_int_cbrt,r.n01);for -lT1 -n=0;ne62 -0.0)){if(prefer_base2)l14 -yV2=fp_log2(p0 -x41);lG3 -yV2 -nH2 -i91 -0);} -else{n0 -eA1 -yV2))eX3 -cS -p1 -t81 -nB1 -t1} -eL3 -cExp2);yS1} -else -l14 -yV2=fp_log(p0 -x41);lG3 -yV2 -nH2 -i91 -0);} -else{n0 -eA1 -yV2))eX3 -cS -p1 -t81 -nB1 -t1} -eL3 -cExp);yS1} -} -iP1 -GetPositivityInfo(p0)==iF2){if(prefer_base2 -nQ -log;log -iH -cLog2);log -cS -p0);log -iW1;n0 -p1)eX3 -c91 -log -t81 -eL3 -cExp2);nB1 -t1 -yS1} -else{yZ2 -log;log -iH -cLog);log -cS -p0);log -iW1;n0 -p1)eX3 -c91 -log -t81 -eL3 -cExp);nB1 -t1 -yS1} -} -e21 -cDiv:{if(GetParam(0)tD1&&lJ3 -GetParam(0)x41 -nH2 -eL3 -cInv);i91 -0);} -xY3 -yF3 -xY3 -if(changed)goto -exit_changed -i1 -changed;} -} -#endif -#ifdef FP_SUPPORT_OPTIMIZER -using -l33 -FUNCTIONPARSERTYPES;l33{using -t5;class -eF3{size_t -nL1;size_t -eH;size_t -eI;size_t -lO1;size_t -t3;size_t -t4;size_t -n71;e43 -eF3():nL1(0),eH(0),eI(0),lO1(0),t3(0),t4(0),n71(0){} -void -i43 -OPCODE -op){nL1+=1 -i33 -cCos)++eH -i33 -cSin)++eI -i33 -cSec)++eH -i33 -cCsc)++eI -i33 -cTan)++lO1 -i33 -cCot)++lO1 -i33 -cSinh)++t4 -i33 -cCosh)++t3 -i33 -cTanh)++n71;} -size_t -GetCSEscore()const{size_t -nS3=nL1 -i1 -nS3;} -int -NeedsSinCos()const{bool -y61=(nL1==(eH+eI+lO1));if((lO1&&(eI||eH))||(eI&&eH)){if(y61)return -1 -i1 -2;eE3 -0;} -int -NeedsSinhCosh()const{bool -y61=(nL1==(t3+t4+n71));if((n71&&(t4||t3))||(t4&&t3)){if(y61)return -1 -i1 -2;eE3 -0;} -size_t -MinimumDepth()const{size_t -n_sincos=std::min(eH,eI);size_t -n_sinhcosh=std::min(t3,t4);if(n_sincos==0&&n_sinhcosh==0)return -2 -i1 -1;} -} -yO1 -class -TreeCountType:public -std::multimap >{} -;xL1 -FindTreeCounts(tJ1&nI2,const -nP1 -OPCODE -xF2,bool -skip_root=false){cX -i=nI2.xU2 -nJ2);if(!skip_root){bool -found -eW3 -for(;i!=nI2.cX1 -nJ2;++i){if(tree -xI -i -eC2.second)){i -eC2.first.i43 -xF2);found=true;xY3} -if(!found){eF3 -count;count.i43 -xF2);nI2.y43,std::make_pair(nJ2,std::make_pair -cW3 -cU3)));} -} -x51 -FindTreeCounts(nI2,xW -a),t72);} -e72 -yW{bool -BalanceGood;bool -FoundChild;} -yO1 -yW -lP1 -iT1&root,iT1&cS3{if(root -xI -cS3){yW -nS3={true,true} -i1 -nS3;} -yW -nS3={true,false} -;if(root -nC==cIf||root -nC==t03{yW -cond=lP1 -root -l8 -0),cS3;yW -xV=lP1 -root -l8 -1),cS3;yW -y4=lP1 -root -l8 -2),cS3;if -l23||xV -yX||y4 -yX){nS3 -yX=true;} -nS3 -eD=((xV -yX==y4 -yX)||l23 -i62)&&(cond -eD||(xV -yX&&y4 -yX))&&(xV -eD||l23 -i62)&&(y4 -eD||l23 -i62);} -else{bool -iH1 -eW3 -bool -nM1=false -eK3 -b=root.GetParamCount(),a=0;afirst!=leaf.GetHash())yA1 -const -eF3&occ -nY2 -first;size_t -score=occ.GetCSEscore();iT1&candidate -nY2 -i63 -if(lF2 -candidate))yA1 -if(leaf -nP2yW2){yW2=score;cs_it=i;} -} -if(yW2<=0){ -#ifdef DEBUG_SUBSTITUTIONS_CSE -cV2<<"No more CSE candidates.\n" -<(lE2"Done with Common Subexpression:" -;DumpTree -xF(tree -lE2 -std::endl; -#endif -#if 0 -if(n11)i73==2||i9){synth.eL1} -yB1 -cSinCos,1,2)yC1 -i82,1)yC1 -i92,0);} -if(i9)i73)synth.eL1 -if(i9==2){synth.eL1} -yB1 -cSinhCosh,1,2)yC1 -yX2,1)yC1 -yY2,0);} -#endif -eE3 -xV3 -stacktop_before;} -} -#endif -#ifdef FP_SUPPORT_OPTIMIZER -tK1 -lU1 -xF::iA2{using -t5;CopyOnWrite()tX -tree;tree.GenerateFrom(*mData);FPoptimizer_Optimize::ApplyGrammars(tree);eO3 -x83>cT3;std -xM3 -xF -immed;size_t -stacktop_max=0;tree.SynthesizeByteCode(cT3,immed,stacktop_max);if(mData->mStackSize!=stacktop_max){mData->mStackSize=x83(stacktop_max); -#if !defined(FP_USE_THREAD_SAFE_EVAL) && \ - !defined(FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA) -mData->mStack -xF3 -stacktop_max); -#endif -} -mData->mByteCode.swap(cT3);mData->mImmed.swap(immed);} -#define FUNCTIONPARSER_INSTANTIATE_EMPTY_OPTIMIZE(type) tP1>lU1::iA2{} -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE -i93(MpfrFloat) -#endif -#ifdef FP_SUPPORT_GMP_INT_TYPE -i93(GmpInt) -#endif -#ifdef FP_SUPPORT_COMPLEX_DOUBLE_TYPE -i93(std::complex) -#endif -#ifdef FP_SUPPORT_COMPLEX_FLOAT_TYPE -i93(std::complex) -#endif -#ifdef FP_SUPPORT_COMPLEX_LONG_DOUBLE_TYPE -i93(std::complex) -#endif -#define FUNCTIONPARSER_INSTANTIATE_OPTIMIZE(type) x73 lU1::iA2; -#ifndef FP_DISABLE_DOUBLE_TYPE -iA3(double) -#endif -#ifdef FP_SUPPORT_FLOAT_TYPE -iA3(float) -#endif -#ifdef FP_SUPPORT_LONG_DOUBLE_TYPE -iA3(long -double) -#endif -#ifdef FP_SUPPORT_LONG_INT_TYPE -iA3(long) -#endif -#endif // FP_SUPPORT_OPTIMIZER - -#endif diff --git a/fparser/mpfr/GmpInt.cc b/fparser/mpfr/GmpInt.cc deleted file mode 100644 index 490add4..0000000 --- a/fparser/mpfr/GmpInt.cc +++ /dev/null @@ -1,710 +0,0 @@ -#include "GmpInt.hh" -#include -#include -#include -#include -#include - -//=========================================================================== -// Shared data -//=========================================================================== -namespace -{ - unsigned long gIntDefaultNumberOfBits = 256; - - std::vector& intString() - { - static std::vector str; - return str; - } -} - -//=========================================================================== -// Auxiliary structs -//=========================================================================== -struct GmpInt::GmpIntData -{ - unsigned mRefCount; - GmpIntData* nextFreeNode; - mpz_t mInteger; - - GmpIntData(): mRefCount(1), nextFreeNode(0) {} -}; - -class GmpInt::GmpIntDataContainer -{ - std::deque mData; - GmpInt::GmpIntData* mFirstFreeNode; - GmpInt::GmpIntData* mConst_0; - - public: - GmpIntDataContainer(): mFirstFreeNode(0), mConst_0(0) {} - - ~GmpIntDataContainer() - { - for(size_t i = 0; i < mData.size(); ++i) - mpz_clear(mData[i].mInteger); - } - - GmpInt::GmpIntData* allocateGmpIntData(unsigned long numberOfBits, - bool initToZero) - { - if(mFirstFreeNode) - { - GmpInt::GmpIntData* node = mFirstFreeNode; - mFirstFreeNode = node->nextFreeNode; - if(initToZero) mpz_set_si(node->mInteger, 0); - ++(node->mRefCount); - return node; - } - - mData.push_back(GmpInt::GmpIntData()); - if(numberOfBits > 0) - mpz_init2(mData.back().mInteger, numberOfBits); - else - mpz_init(mData.back().mInteger); - return &mData.back(); - } - - void releaseGmpIntData(GmpIntData* data) - { - if(--(data->mRefCount) == 0) - { - data->nextFreeNode = mFirstFreeNode; - mFirstFreeNode = data; - } - } - - GmpInt::GmpIntData* const_0() - { - if(!mConst_0) - mConst_0 = allocateGmpIntData(gIntDefaultNumberOfBits, true); - return mConst_0; - } -}; - - -GmpInt::GmpIntDataContainer& GmpInt::gmpIntDataContainer() -{ - static GmpIntDataContainer container; - return container; -} - -//=========================================================================== -// Auxiliary functions -//=========================================================================== -void GmpInt::setDefaultNumberOfBits(unsigned long value) -{ - gIntDefaultNumberOfBits = value; -} - -unsigned long GmpInt::getDefaultNumberOfBits() -{ - return gIntDefaultNumberOfBits; -} - -inline void GmpInt::copyIfShared() -{ - if(mData->mRefCount > 1) - { - --(mData->mRefCount); - GmpIntData* oldData = mData; - mData = gmpIntDataContainer().allocateGmpIntData(0, false); - mpz_set(mData->mInteger, oldData->mInteger); - } -} - - -//=========================================================================== -// Constructors, destructor, assignment -//=========================================================================== -GmpInt::GmpInt(DummyType): - mData(gmpIntDataContainer().allocateGmpIntData(0, false)) -{} - -GmpInt::GmpInt() -{ - mData = gmpIntDataContainer().const_0(); - ++(mData->mRefCount); -} - -GmpInt::GmpInt(long value) -{ - if(value == 0) - { - mData = gmpIntDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - mData = gmpIntDataContainer().allocateGmpIntData - (gIntDefaultNumberOfBits, false); - mpz_set_si(mData->mInteger, value); - } -} - -GmpInt::GmpInt(unsigned long value) -{ - if(value == 0) - { - mData = gmpIntDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - mData = gmpIntDataContainer().allocateGmpIntData - (gIntDefaultNumberOfBits, false); - mpz_set_ui(mData->mInteger, value); - } -} - -GmpInt::GmpInt(int value) -{ - if(value == 0) - { - mData = gmpIntDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - mData = gmpIntDataContainer().allocateGmpIntData - (gIntDefaultNumberOfBits, false); - mpz_set_si(mData->mInteger, value); - } -} - -GmpInt::GmpInt(double value) -{ - const double absValue = value >= 0.0 ? value : -value; - if(absValue < 1.0) - { - mData = gmpIntDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - mData = gmpIntDataContainer().allocateGmpIntData - (gIntDefaultNumberOfBits, false); - mpz_set_d(mData->mInteger, value); - } -} - -GmpInt::GmpInt(long double value) -{ - const long double absValue = value >= 0.0L ? value : -value; - if(absValue < 1.0L) - { - mData = gmpIntDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - mData = gmpIntDataContainer().allocateGmpIntData - (gIntDefaultNumberOfBits, false); - mpz_set_d(mData->mInteger, double(value)); - } -} - -GmpInt::GmpInt(const GmpInt& rhs): - mData(rhs.mData) -{ - ++(mData->mRefCount); -} - -GmpInt& GmpInt::operator=(const GmpInt& rhs) -{ - if(mData != rhs.mData) - { - gmpIntDataContainer().releaseGmpIntData(mData); - mData = rhs.mData; - ++(mData->mRefCount); - } - return *this; -} - -GmpInt& GmpInt::operator=(signed long value) -{ - if(value == 0) - { - gmpIntDataContainer().releaseGmpIntData(mData); - mData = gmpIntDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - if(mData->mRefCount > 1) - { - --(mData->mRefCount); - mData = gmpIntDataContainer().allocateGmpIntData - (gIntDefaultNumberOfBits, false); - } - mpz_set_si(mData->mInteger, value); - } - return *this; -} - -GmpInt::~GmpInt() -{ - gmpIntDataContainer().releaseGmpIntData(mData); -} - - -//=========================================================================== -// Data getters -//=========================================================================== -template<> -void GmpInt::get_raw_mpfr_data(mpz_t& dest_mpz_t) -{ - std::memcpy(&dest_mpz_t, mData->mInteger, sizeof(mpz_t)); -} - -const char* GmpInt::getAsString(int base) const -{ - intString().resize(mpz_sizeinbase(mData->mInteger, base) + 2); - return mpz_get_str(&intString()[0], base, mData->mInteger); -} - -long GmpInt::toInt() const -{ - return mpz_get_si(mData->mInteger); -} - - -//=========================================================================== -// Modifying operators -//=========================================================================== -GmpInt& GmpInt::operator+=(const GmpInt& rhs) -{ - copyIfShared(); - mpz_add(mData->mInteger, mData->mInteger, rhs.mData->mInteger); - return *this; -} - -GmpInt& GmpInt::operator+=(long value) -{ - copyIfShared(); - if(value >= 0) - mpz_add_ui(mData->mInteger, mData->mInteger, value); - else - mpz_sub_ui(mData->mInteger, mData->mInteger, -value); - return *this; -} - -GmpInt& GmpInt::operator-=(const GmpInt& rhs) -{ - copyIfShared(); - mpz_sub(mData->mInteger, mData->mInteger, rhs.mData->mInteger); - return *this; -} - -GmpInt& GmpInt::operator-=(long value) -{ - copyIfShared(); - if(value >= 0) - mpz_sub_ui(mData->mInteger, mData->mInteger, value); - else - mpz_add_ui(mData->mInteger, mData->mInteger, -value); - return *this; -} - -GmpInt& GmpInt::operator*=(const GmpInt& rhs) -{ - copyIfShared(); - mpz_mul(mData->mInteger, mData->mInteger, rhs.mData->mInteger); - return *this; -} - -GmpInt& GmpInt::operator*=(long value) -{ - copyIfShared(); - mpz_mul_si(mData->mInteger, mData->mInteger, value); - return *this; -} - -GmpInt& GmpInt::operator/=(const GmpInt& rhs) -{ - copyIfShared(); - mpz_tdiv_q(mData->mInteger, mData->mInteger, rhs.mData->mInteger); - return *this; -} - -GmpInt& GmpInt::operator/=(long value) -{ - copyIfShared(); - if(value >= 0) - mpz_tdiv_q_ui(mData->mInteger, mData->mInteger, value); - else - { - mpz_neg(mData->mInteger, mData->mInteger); - mpz_tdiv_q_ui(mData->mInteger, mData->mInteger, -value); - } - return *this; -} - -GmpInt& GmpInt::operator%=(const GmpInt& rhs) -{ - copyIfShared(); - if(operator<(0)) - { - negate(); - mpz_mod(mData->mInteger, mData->mInteger, rhs.mData->mInteger); - negate(); - } - else - { - mpz_mod(mData->mInteger, mData->mInteger, rhs.mData->mInteger); - } - return *this; -} - -GmpInt& GmpInt::operator%=(long value) -{ - copyIfShared(); - if(value < 0) value = -value; - if(operator<(0)) - { - negate(); - mpz_mod_ui(mData->mInteger, mData->mInteger, value); - negate(); - } - else - { - mpz_mod_ui(mData->mInteger, mData->mInteger, value); - } - return *this; -} - -GmpInt& GmpInt::operator<<=(unsigned long bits) -{ - copyIfShared(); - mpz_mul_2exp(mData->mInteger, mData->mInteger, bits); - return *this; -} - -GmpInt& GmpInt::operator>>=(unsigned long bits) -{ - copyIfShared(); - mpz_tdiv_q_2exp(mData->mInteger, mData->mInteger, bits); - return *this; -} - - -//=========================================================================== -// Modifying functions -//=========================================================================== -void GmpInt::addProduct(const GmpInt& value1, const GmpInt& value2) -{ - copyIfShared(); - mpz_addmul(mData->mInteger, value1.mData->mInteger, value2.mData->mInteger); -} - -void GmpInt::addProduct(const GmpInt& value1, unsigned long value2) -{ - copyIfShared(); - mpz_addmul_ui(mData->mInteger, value1.mData->mInteger, value2); -} - -void GmpInt::subProduct(const GmpInt& value1, const GmpInt& value2) -{ - copyIfShared(); - mpz_submul(mData->mInteger, value1.mData->mInteger, value2.mData->mInteger); -} - -void GmpInt::subProduct(const GmpInt& value1, unsigned long value2) -{ - copyIfShared(); - mpz_submul_ui(mData->mInteger, value1.mData->mInteger, value2); -} - -void GmpInt::negate() -{ - copyIfShared(); - mpz_neg(mData->mInteger, mData->mInteger); -} - -void GmpInt::abs() -{ - copyIfShared(); - mpz_abs(mData->mInteger, mData->mInteger); -} - -GmpInt GmpInt::abs(const GmpInt& value) -{ - GmpInt retval(kNoInitialization); - mpz_abs(retval.mData->mInteger, value.mData->mInteger); - return retval; -} - - -//=========================================================================== -// Non-modifying operators -//=========================================================================== -GmpInt GmpInt::operator+(const GmpInt& rhs) const -{ - GmpInt retval(kNoInitialization); - mpz_add(retval.mData->mInteger, mData->mInteger, rhs.mData->mInteger); - return retval; -} - -GmpInt GmpInt::operator+(long value) const -{ - GmpInt retval(kNoInitialization); - if(value >= 0) - mpz_add_ui(retval.mData->mInteger, mData->mInteger, value); - else - mpz_sub_ui(retval.mData->mInteger, mData->mInteger, -value); - return retval; -} - -GmpInt GmpInt::operator-(const GmpInt& rhs) const -{ - GmpInt retval(kNoInitialization); - mpz_sub(retval.mData->mInteger, mData->mInteger, rhs.mData->mInteger); - return retval; -} - -GmpInt GmpInt::operator-(long value) const -{ - GmpInt retval(kNoInitialization); - if(value >= 0) - mpz_sub_ui(retval.mData->mInteger, mData->mInteger, value); - else - mpz_add_ui(retval.mData->mInteger, mData->mInteger, -value); - return retval; -} - -GmpInt GmpInt::operator*(const GmpInt& rhs) const -{ - GmpInt retval(kNoInitialization); - mpz_mul(retval.mData->mInteger, mData->mInteger, rhs.mData->mInteger); - return retval; -} - -GmpInt GmpInt::operator*(long value) const -{ - GmpInt retval(kNoInitialization); - mpz_mul_si(retval.mData->mInteger, mData->mInteger, value); - return retval; -} - -GmpInt GmpInt::operator/(const GmpInt& rhs) const -{ - GmpInt retval(kNoInitialization); - mpz_tdiv_q(retval.mData->mInteger, mData->mInteger, rhs.mData->mInteger); - return retval; -} - -GmpInt GmpInt::operator/(long value) const -{ - GmpInt retval(kNoInitialization); - if(value >= 0) - mpz_tdiv_q_ui(retval.mData->mInteger, mData->mInteger, value); - else - { - mpz_neg(retval.mData->mInteger, mData->mInteger); - mpz_tdiv_q_ui(retval.mData->mInteger, retval.mData->mInteger, -value); - } - return retval; -} - -GmpInt GmpInt::operator%(const GmpInt& rhs) const -{ - GmpInt retval(kNoInitialization); - if(operator<(0)) - { - mpz_neg(retval.mData->mInteger, mData->mInteger); - mpz_mod(retval.mData->mInteger, - retval.mData->mInteger, rhs.mData->mInteger); - retval.negate(); - } - else - { - mpz_mod(retval.mData->mInteger, mData->mInteger, rhs.mData->mInteger); - } - return retval; -} - -GmpInt GmpInt::operator%(long value) const -{ - GmpInt retval(kNoInitialization); - if(value < 0) value = -value; - if(operator<(0)) - { - mpz_neg(retval.mData->mInteger, mData->mInteger); - mpz_mod_ui(retval.mData->mInteger, retval.mData->mInteger, value); - retval.negate(); - } - else - { - mpz_mod_ui(retval.mData->mInteger, mData->mInteger, value); - } - return retval; -} - -GmpInt GmpInt::operator-() const -{ - GmpInt retval(kNoInitialization); - mpz_neg(retval.mData->mInteger, mData->mInteger); - return retval; -} - -GmpInt GmpInt::operator<<(unsigned long bits) const -{ - GmpInt retval(kNoInitialization); - mpz_mul_2exp(retval.mData->mInteger, mData->mInteger, bits); - return retval; -} - -GmpInt GmpInt::operator>>(unsigned long bits) const -{ - GmpInt retval(kNoInitialization); - mpz_tdiv_q_2exp(retval.mData->mInteger, mData->mInteger, bits); - return retval; -} - - -//=========================================================================== -// Comparison operators -//=========================================================================== -bool GmpInt::operator<(const GmpInt& rhs) const -{ - return mpz_cmp(mData->mInteger, rhs.mData->mInteger) < 0; -} - -bool GmpInt::operator<(long value) const -{ - return mpz_cmp_si(mData->mInteger, value) < 0; -} - -bool GmpInt::operator<=(const GmpInt& rhs) const -{ - return mpz_cmp(mData->mInteger, rhs.mData->mInteger) <= 0; -} - -bool GmpInt::operator<=(long value) const -{ - return mpz_cmp_si(mData->mInteger, value) <= 0; -} - -bool GmpInt::operator>(const GmpInt& rhs) const -{ - return mpz_cmp(mData->mInteger, rhs.mData->mInteger) > 0; -} - -bool GmpInt::operator>(long value) const -{ - return mpz_cmp_si(mData->mInteger, value) > 0; -} - -bool GmpInt::operator>=(const GmpInt& rhs) const -{ - return mpz_cmp(mData->mInteger, rhs.mData->mInteger) >= 0; -} - -bool GmpInt::operator>=(long value) const -{ - return mpz_cmp_si(mData->mInteger, value) >= 0; -} - -bool GmpInt::operator==(const GmpInt& rhs) const -{ - return mpz_cmp(mData->mInteger, rhs.mData->mInteger) == 0; -} - -bool GmpInt::operator==(long value) const -{ - return mpz_cmp_si(mData->mInteger, value) == 0; -} - -bool GmpInt::operator!=(const GmpInt& rhs) const -{ - return mpz_cmp(mData->mInteger, rhs.mData->mInteger) != 0; -} - -bool GmpInt::operator!=(long value) const -{ - return mpz_cmp_si(mData->mInteger, value) != 0; -} - -void GmpInt::parseValue(const char* value) -{ - mpz_set_str(mData->mInteger, value, 10); -} - -void GmpInt::parseValue(const char* value, char** endptr) -{ - static std::vector str; - - unsigned startIndex = 0; - while(value[startIndex] && std::isspace(value[startIndex])) ++startIndex; - if(!value[startIndex]) { *endptr = const_cast(value); return; } - - unsigned endIndex = startIndex; - if(value[endIndex] == '-') ++endIndex; - if(!std::isdigit(value[endIndex])) - { *endptr = const_cast(value); return; } - if(value[endIndex] == '0' && value[endIndex+1] == 'x') - { - endIndex += 1; - while(std::isxdigit(value[++endIndex])) {} - } - else - { - while(std::isdigit(value[++endIndex])) {} - } - - str.reserve(endIndex - startIndex + 1); - str.assign(value + startIndex, value + endIndex); - str.push_back(0); - - mpz_set_str(mData->mInteger, &str[0], 0); - *endptr = const_cast(value + endIndex); -} - -GmpInt GmpInt::parseString(const char* str, char** endptr) -{ - GmpInt retval(kNoInitialization); - retval.parseValue(str, endptr); - return retval; -} - -//=========================================================================== -// Operator functions -//=========================================================================== -GmpInt operator+(long lhs, const GmpInt& rhs) -{ - GmpInt retval(GmpInt::kNoInitialization); - if(lhs >= 0) - mpz_add_ui(retval.mData->mInteger, rhs.mData->mInteger, lhs); - else - mpz_sub_ui(retval.mData->mInteger, rhs.mData->mInteger, -lhs); - return retval; -} - -GmpInt operator-(long lhs, const GmpInt& rhs) -{ - GmpInt retval(GmpInt::kNoInitialization); - if(lhs >= 0) - mpz_ui_sub(retval.mData->mInteger, lhs, rhs.mData->mInteger); - else - { - mpz_add_ui(retval.mData->mInteger, rhs.mData->mInteger, -lhs); - mpz_neg(retval.mData->mInteger, retval.mData->mInteger); - } - return retval; -} - -GmpInt operator*(long lhs, const GmpInt& rhs) -{ - return rhs * lhs; -} - -GmpInt operator/(long lhs, const GmpInt& rhs) -{ - return GmpInt(lhs) / rhs; -} - -GmpInt operator%(long lhs, const GmpInt& rhs) -{ - return GmpInt(lhs) % rhs; -} diff --git a/fparser/mpfr/GmpInt.hh b/fparser/mpfr/GmpInt.hh deleted file mode 100644 index 1c1c171..0000000 --- a/fparser/mpfr/GmpInt.hh +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef ONCE_FP_GMP_INT_HH_ -#define ONCE_FP_GMP_INT_HH_ - -#include - -class GmpInt -{ - public: - /* A default of 256 bits will be used for all newly-instantiated GmpInt - objects. This default can be changed with the function below. - */ - static void setDefaultNumberOfBits(unsigned long); - static unsigned long getDefaultNumberOfBits(); - - GmpInt(); - GmpInt(long value); - GmpInt(unsigned long value); - GmpInt(int value); - GmpInt(double value); - GmpInt(long double value); - - GmpInt(const GmpInt&); - GmpInt& operator=(const GmpInt&); - GmpInt& operator=(signed long value); - - ~GmpInt(); - - - /* This function can be used to retrieve the raw mpz_t data structure - used by this object. (The template trick is used to avoid a dependency - of this header file with .) - In other words, it can be called like: - - mpz_t raw_mpz_data; - intValue.get_raw_mpz_data(raw_mpz_data); - - Note that the returned mpz_t should be considered as read-only and - not be modified from the outside because it may be shared among - several objects. If the calling code needs to modify the data, it - should copy it for itself first with the appropriate GMP library - functions. - */ - template - void get_raw_mpfr_data(Mpz_t& dest_mpz_t); - - - // Note that the returned char* points to an internal (shared) buffer - // which will be valid until the next time this function is called - // (by any object). - const char* getAsString(int base = 10) const; - long toInt() const; - - GmpInt& operator+=(const GmpInt&); - GmpInt& operator+=(long); - GmpInt& operator-=(const GmpInt&); - GmpInt& operator-=(long); - GmpInt& operator*=(const GmpInt&); - GmpInt& operator*=(long); - GmpInt& operator/=(const GmpInt&); - GmpInt& operator/=(long); - GmpInt& operator%=(const GmpInt&); - GmpInt& operator%=(long); - - GmpInt& operator<<=(unsigned long); - GmpInt& operator>>=(unsigned long); - - // Equivalent to "+= value1 * value2;" - void addProduct(const GmpInt& value1, const GmpInt& value2); - void addProduct(const GmpInt& value1, unsigned long value2); - - // Equivalent to "-= value1 * value2;" - void subProduct(const GmpInt& value1, const GmpInt& value2); - void subProduct(const GmpInt& value1, unsigned long value2); - - void negate(); - void abs(); - static GmpInt abs(const GmpInt&); - - GmpInt operator+(const GmpInt&) const; - GmpInt operator+(long) const; - GmpInt operator-(const GmpInt&) const; - GmpInt operator-(long) const; - GmpInt operator*(const GmpInt&) const; - GmpInt operator*(long) const; - GmpInt operator/(const GmpInt&) const; - GmpInt operator/(long) const; - GmpInt operator%(const GmpInt&) const; - GmpInt operator%(long) const; - - GmpInt operator-() const; - - GmpInt operator<<(unsigned long) const; - GmpInt operator>>(unsigned long) const; - - bool operator<(const GmpInt&) const; - bool operator<(long) const; - bool operator<=(const GmpInt&) const; - bool operator<=(long) const; - bool operator>(const GmpInt&) const; - bool operator>(long) const; - bool operator>=(const GmpInt&) const; - bool operator>=(long) const; - bool operator==(const GmpInt&) const; - bool operator==(long) const; - bool operator!=(const GmpInt&) const; - bool operator!=(long) const; - - void parseValue(const char* value); - void parseValue(const char* value, char** endptr); - static GmpInt parseString(const char* str, char** endptr); - - - private: - struct GmpIntData; - class GmpIntDataContainer; - - GmpIntData* mData; - - enum DummyType { kNoInitialization }; - GmpInt(DummyType); - - void copyIfShared(); - static GmpIntDataContainer& gmpIntDataContainer(); - - friend GmpInt operator+(long lhs, const GmpInt& rhs); - friend GmpInt operator-(long lhs, const GmpInt& rhs); -}; - -GmpInt operator+(long lhs, const GmpInt& rhs); -GmpInt operator-(long lhs, const GmpInt& rhs); -GmpInt operator*(long lhs, const GmpInt& rhs); -GmpInt operator/(long lhs, const GmpInt& rhs); -GmpInt operator%(long lhs, const GmpInt& rhs); - -inline bool operator<(long lhs, const GmpInt& rhs) { return rhs > lhs; } -inline bool operator<=(long lhs, const GmpInt& rhs) { return rhs >= lhs; } -inline bool operator>(long lhs, const GmpInt& rhs) { return rhs < lhs; } -inline bool operator>=(long lhs, const GmpInt& rhs) { return rhs <= lhs; } -inline bool operator==(long lhs, const GmpInt& rhs) { return rhs == lhs; } -inline bool operator!=(long lhs, const GmpInt& rhs) { return rhs != lhs; } - -inline std::ostream& operator<<(std::ostream& os, const GmpInt& value) -{ - os << value.getAsString(); - return os; -} - -#endif diff --git a/fparser/mpfr/MpfrFloat.cc b/fparser/mpfr/MpfrFloat.cc deleted file mode 100644 index 112c684..0000000 --- a/fparser/mpfr/MpfrFloat.cc +++ /dev/null @@ -1,976 +0,0 @@ -#include "MpfrFloat.hh" -#include -#include -#include -#include -#include -#include - -//=========================================================================== -// Auxiliary structs -//=========================================================================== -struct MpfrFloat::MpfrFloatData -{ - unsigned mRefCount; - MpfrFloatData* nextFreeNode; - mpfr_t mFloat; - - MpfrFloatData(): mRefCount(1), nextFreeNode(0) {} -}; - -class MpfrFloat::MpfrFloatDataContainer -{ - unsigned long mDefaultPrecision; - std::deque mData; - MpfrFloatData* mFirstFreeNode; - - MpfrFloatData - *mConst_0, *mConst_pi, *mConst_e, *mConst_log2, *mConst_epsilon; - - void recalculateEpsilon() - { - mpfr_set_si(mConst_epsilon->mFloat, 1, GMP_RNDN); - mpfr_div_2ui(mConst_epsilon->mFloat, mConst_epsilon->mFloat, - mDefaultPrecision*7/8 - 1, GMP_RNDN); - } - - public: - MpfrFloatDataContainer(): - mDefaultPrecision(256), mFirstFreeNode(0), mConst_0(0), - mConst_pi(0), mConst_e(0), mConst_log2(0), mConst_epsilon(0) - {} - - ~MpfrFloatDataContainer() - { - for(size_t i = 0; i < mData.size(); ++i) - mpfr_clear(mData[i].mFloat); - } - - MpfrFloatData* allocateMpfrFloatData(bool initToZero) - { - if(mFirstFreeNode) - { - MpfrFloatData* node = mFirstFreeNode; - mFirstFreeNode = node->nextFreeNode; - if(initToZero) mpfr_set_si(node->mFloat, 0, GMP_RNDN); - ++(node->mRefCount); - return node; - } - - mData.push_back(MpfrFloatData()); - mpfr_init2(mData.back().mFloat, mDefaultPrecision); - if(initToZero) mpfr_set_si(mData.back().mFloat, 0, GMP_RNDN); - return &mData.back(); - } - - void releaseMpfrFloatData(MpfrFloatData* data) - { - if(--(data->mRefCount) == 0) - { - data->nextFreeNode = mFirstFreeNode; - mFirstFreeNode = data; - } - } - - void setDefaultPrecision(unsigned long bits) - { - if(bits != mDefaultPrecision) - { - mDefaultPrecision = bits; - for(size_t i = 0; i < mData.size(); ++i) - mpfr_prec_round(mData[i].mFloat, bits, GMP_RNDN); - - if(mConst_pi) mpfr_const_pi(mConst_pi->mFloat, GMP_RNDN); - if(mConst_e) - { - mpfr_set_si(mConst_e->mFloat, 1, GMP_RNDN); - mpfr_exp(mConst_e->mFloat, mConst_e->mFloat, GMP_RNDN); - } - if(mConst_log2) mpfr_const_log2(mConst_log2->mFloat, GMP_RNDN); - if(mConst_epsilon) recalculateEpsilon(); - } - } - - unsigned long getDefaultPrecision() const - { - return mDefaultPrecision; - } - - MpfrFloatData* const_0() - { - if(!mConst_0) mConst_0 = allocateMpfrFloatData(true); - return mConst_0; - } - - MpfrFloat const_pi() - { - if(!mConst_pi) - { - mConst_pi = allocateMpfrFloatData(false); - mpfr_const_pi(mConst_pi->mFloat, GMP_RNDN); - } - return MpfrFloat(mConst_pi); - } - - MpfrFloat const_e() - { - if(!mConst_e) - { - mConst_e = allocateMpfrFloatData(false); - mpfr_set_si(mConst_e->mFloat, 1, GMP_RNDN); - mpfr_exp(mConst_e->mFloat, mConst_e->mFloat, GMP_RNDN); - } - return MpfrFloat(mConst_e); - } - - MpfrFloat const_log2() - { - if(!mConst_log2) - { - mConst_log2 = allocateMpfrFloatData(false); - mpfr_const_log2(mConst_log2->mFloat, GMP_RNDN); - } - return MpfrFloat(mConst_log2); - } - - MpfrFloat const_epsilon() - { - if(!mConst_epsilon) - { - mConst_epsilon = allocateMpfrFloatData(false); - recalculateEpsilon(); - } - return MpfrFloat(mConst_epsilon); - } -}; - - -//=========================================================================== -// Shared data -//=========================================================================== -// This should ensure that the container is not accessed by any MpfrFloat -// instance before it has been constructed or after it has been destroyed -// (which might otherwise happen if MpfrFloat is instantiated globally.) -MpfrFloat::MpfrFloatDataContainer& MpfrFloat::mpfrFloatDataContainer() -{ - static MpfrFloat::MpfrFloatDataContainer container; - return container; -} - - -//=========================================================================== -// Auxiliary functions -//=========================================================================== -void MpfrFloat::setDefaultMantissaBits(unsigned long bits) -{ - mpfrFloatDataContainer().setDefaultPrecision(bits); -} - -unsigned long MpfrFloat::getCurrentDefaultMantissaBits() -{ - return mpfrFloatDataContainer().getDefaultPrecision(); -} - -inline void MpfrFloat::copyIfShared() -{ - if(mData->mRefCount > 1) - { - --(mData->mRefCount); - MpfrFloatData* oldData = mData; - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - mpfr_set(mData->mFloat, oldData->mFloat, GMP_RNDN); - } -} - - -//=========================================================================== -// Constructors, destructor, assignment -//=========================================================================== -MpfrFloat::MpfrFloat(DummyType): - mData(mpfrFloatDataContainer().allocateMpfrFloatData(false)) -{} - -MpfrFloat::MpfrFloat(MpfrFloatData* data): - mData(data) -{ - assert(data != 0); - ++(mData->mRefCount); -} - -MpfrFloat::MpfrFloat(): - mData(mpfrFloatDataContainer().const_0()) -{ - ++(mData->mRefCount); -} - -MpfrFloat::MpfrFloat(double value) -{ - if(value == 0.0) - { - mData = mpfrFloatDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - mpfr_set_d(mData->mFloat, value, GMP_RNDN); - } -} - -MpfrFloat::MpfrFloat(long double value) -{ - if(value == 0.0L) - { - mData = mpfrFloatDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - mpfr_set_ld(mData->mFloat, value, GMP_RNDN); - } -} - -MpfrFloat::MpfrFloat(long value) -{ - if(value == 0) - { - mData = mpfrFloatDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - mpfr_set_si(mData->mFloat, value, GMP_RNDN); - } -} - -MpfrFloat::MpfrFloat(int value) -{ - if(value == 0) - { - mData = mpfrFloatDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - mpfr_set_si(mData->mFloat, value, GMP_RNDN); - } -} - -MpfrFloat::MpfrFloat(const char* value, char** endptr): - mData(mpfrFloatDataContainer().allocateMpfrFloatData(false)) -{ - mpfr_strtofr(mData->mFloat, value, endptr, 0, GMP_RNDN); -} - -MpfrFloat::~MpfrFloat() -{ - mpfrFloatDataContainer().releaseMpfrFloatData(mData); -} - -MpfrFloat::MpfrFloat(const MpfrFloat& rhs): - mData(rhs.mData) -{ - ++(mData->mRefCount); -} - -MpfrFloat& MpfrFloat::operator=(const MpfrFloat& rhs) -{ - if(mData != rhs.mData) - { - mpfrFloatDataContainer().releaseMpfrFloatData(mData); - mData = rhs.mData; - ++(mData->mRefCount); - } - return *this; -} - -MpfrFloat& MpfrFloat::operator=(double value) -{ - if(value == 0.0) - { - mpfrFloatDataContainer().releaseMpfrFloatData(mData); - mData = mpfrFloatDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - if(mData->mRefCount > 1) - { - --(mData->mRefCount); - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - } - mpfr_set_d(mData->mFloat, value, GMP_RNDN); - } - return *this; -} - -MpfrFloat& MpfrFloat::operator=(long double value) -{ - if(value == 0.0L) - { - mpfrFloatDataContainer().releaseMpfrFloatData(mData); - mData = mpfrFloatDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - if(mData->mRefCount > 1) - { - --(mData->mRefCount); - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - } - mpfr_set_ld(mData->mFloat, value, GMP_RNDN); - } - return *this; -} - -MpfrFloat& MpfrFloat::operator=(long value) -{ - if(value == 0) - { - mpfrFloatDataContainer().releaseMpfrFloatData(mData); - mData = mpfrFloatDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - if(mData->mRefCount > 1) - { - --(mData->mRefCount); - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - } - mpfr_set_si(mData->mFloat, value, GMP_RNDN); - } - return *this; -} - -MpfrFloat& MpfrFloat::operator=(int value) -{ - if(value == 0) - { - mpfrFloatDataContainer().releaseMpfrFloatData(mData); - mData = mpfrFloatDataContainer().const_0(); - ++(mData->mRefCount); - } - else - { - if(mData->mRefCount > 1) - { - --(mData->mRefCount); - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - } - mpfr_set_si(mData->mFloat, value, GMP_RNDN); - } - return *this; -} - -/* -MpfrFloat& MpfrFloat::operator=(const char* value) -{ - if(mData->mRefCount > 1) - { - --(mData->mRefCount); - mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); - } - - mpfr_set_str(mData->mFloat, value, 10, GMP_RNDN); - return *this; -} -*/ - -void MpfrFloat::parseValue(const char* value) -{ - copyIfShared(); - mpfr_set_str(mData->mFloat, value, 10, GMP_RNDN); -} - -void MpfrFloat::parseValue(const char* value, char** endptr) -{ - copyIfShared(); - mpfr_strtofr(mData->mFloat, value, endptr, 0, GMP_RNDN); -} - - -//=========================================================================== -// Data getters -//=========================================================================== -template<> -void MpfrFloat::get_raw_mpfr_data(mpfr_t& dest_mpfr_t) -{ - std::memcpy(&dest_mpfr_t, mData->mFloat, sizeof(mpfr_t)); -} - -const char* MpfrFloat::getAsString(unsigned precision) const -{ -#if(MPFR_VERSION_MAJOR < 2 || (MPFR_VERSION_MAJOR == 2 && MPFR_VERSION_MINOR < 4)) - static const char* retval = - "[mpfr_snprintf() is not supported in mpfr versions prior to 2.4]"; - return retval; -#else - static std::vector str; - str.resize(precision+30); - mpfr_snprintf(&(str[0]), precision+30, "%.*RNg", precision, mData->mFloat); - return &(str[0]); -#endif -} - -bool MpfrFloat::isInteger() const -{ - return mpfr_integer_p(mData->mFloat) != 0; -} - -long MpfrFloat::toInt() const -{ - return mpfr_get_si(mData->mFloat, GMP_RNDN); -} - -double MpfrFloat::toDouble() const -{ - return mpfr_get_d(mData->mFloat, GMP_RNDN); -} - - -//=========================================================================== -// Modifying operators -//=========================================================================== -MpfrFloat& MpfrFloat::operator+=(const MpfrFloat& rhs) -{ - copyIfShared(); - mpfr_add(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return *this; -} - -MpfrFloat& MpfrFloat::operator+=(double value) -{ - copyIfShared(); - mpfr_add_d(mData->mFloat, mData->mFloat, value, GMP_RNDN); - return *this; -} - -MpfrFloat& MpfrFloat::operator-=(const MpfrFloat& rhs) -{ - copyIfShared(); - mpfr_sub(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return *this; -} - -MpfrFloat& MpfrFloat::operator-=(double value) -{ - copyIfShared(); - mpfr_sub_d(mData->mFloat, mData->mFloat, value, GMP_RNDN); - return *this; -} - -MpfrFloat& MpfrFloat::operator*=(const MpfrFloat& rhs) -{ - copyIfShared(); - mpfr_mul(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return *this; -} - -MpfrFloat& MpfrFloat::operator*=(double value) -{ - copyIfShared(); - mpfr_mul_d(mData->mFloat, mData->mFloat, value, GMP_RNDN); - return *this; -} - -MpfrFloat& MpfrFloat::operator/=(const MpfrFloat& rhs) -{ - copyIfShared(); - mpfr_div(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return *this; -} - -MpfrFloat& MpfrFloat::operator/=(double value) -{ - copyIfShared(); - mpfr_div_d(mData->mFloat, mData->mFloat, value, GMP_RNDN); - return *this; -} - -MpfrFloat& MpfrFloat::operator%=(const MpfrFloat& rhs) -{ - copyIfShared(); - mpfr_fmod(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return *this; -} - - -//=========================================================================== -// Modifying functions -//=========================================================================== -void MpfrFloat::negate() -{ - copyIfShared(); - mpfr_neg(mData->mFloat, mData->mFloat, GMP_RNDN); -} - -void MpfrFloat::abs() -{ - copyIfShared(); - mpfr_abs(mData->mFloat, mData->mFloat, GMP_RNDN); -} - - -//=========================================================================== -// Non-modifying operators -//=========================================================================== -MpfrFloat MpfrFloat::operator+(const MpfrFloat& rhs) const -{ - MpfrFloat retval(kNoInitialization); - mpfr_add(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::operator+(double value) const -{ - MpfrFloat retval(kNoInitialization); - mpfr_add_d(retval.mData->mFloat, mData->mFloat, value, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::operator-(const MpfrFloat& rhs) const -{ - MpfrFloat retval(kNoInitialization); - mpfr_sub(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::operator-(double value) const -{ - MpfrFloat retval(kNoInitialization); - mpfr_sub_d(retval.mData->mFloat, mData->mFloat, value, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::operator*(const MpfrFloat& rhs) const -{ - MpfrFloat retval(kNoInitialization); - mpfr_mul(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::operator*(double value) const -{ - MpfrFloat retval(kNoInitialization); - mpfr_mul_d(retval.mData->mFloat, mData->mFloat, value, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::operator/(const MpfrFloat& rhs) const -{ - MpfrFloat retval(kNoInitialization); - mpfr_div(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::operator/(double value) const -{ - MpfrFloat retval(kNoInitialization); - mpfr_div_d(retval.mData->mFloat, mData->mFloat, value, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::operator%(const MpfrFloat& rhs) const -{ - MpfrFloat retval(kNoInitialization); - mpfr_fmod(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::operator-() const -{ - MpfrFloat retval(kNoInitialization); - mpfr_neg(retval.mData->mFloat, mData->mFloat, GMP_RNDN); - return retval; -} - - - -//=========================================================================== -// Comparison operators -//=========================================================================== -bool MpfrFloat::operator<(const MpfrFloat& rhs) const -{ - return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) < 0; -} - -bool MpfrFloat::operator<(double value) const -{ - return mpfr_cmp_d(mData->mFloat, value) < 0; -} - -bool MpfrFloat::operator<=(const MpfrFloat& rhs) const -{ - return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) <= 0; -} - -bool MpfrFloat::operator<=(double value) const -{ - return mpfr_cmp_d(mData->mFloat, value) <= 0; -} - -bool MpfrFloat::operator>(const MpfrFloat& rhs) const -{ - return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) > 0; -} - -bool MpfrFloat::operator>(double value) const -{ - return mpfr_cmp_d(mData->mFloat, value) > 0; -} - -bool MpfrFloat::operator>=(const MpfrFloat& rhs) const -{ - return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) >= 0; -} - -bool MpfrFloat::operator>=(double value) const -{ - return mpfr_cmp_d(mData->mFloat, value) >= 0; -} - -bool MpfrFloat::operator==(const MpfrFloat& rhs) const -{ - return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) == 0; -} - -bool MpfrFloat::operator==(double value) const -{ - return mpfr_cmp_d(mData->mFloat, value) == 0; -} - -bool MpfrFloat::operator!=(const MpfrFloat& rhs) const -{ - return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) != 0; -} - -bool MpfrFloat::operator!=(double value) const -{ - return mpfr_cmp_d(mData->mFloat, value) != 0; -} - - -//=========================================================================== -// Operator functions -//=========================================================================== -MpfrFloat operator+(double lhs, const MpfrFloat& rhs) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_add_d(retval.mData->mFloat, rhs.mData->mFloat, lhs, GMP_RNDN); - return retval; -} - -MpfrFloat operator-(double lhs, const MpfrFloat& rhs) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_d_sub(retval.mData->mFloat, lhs, rhs.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat operator*(double lhs, const MpfrFloat& rhs) -{ - return rhs * lhs; -} - -MpfrFloat operator/(double lhs, const MpfrFloat& rhs) -{ - return MpfrFloat(lhs) / rhs; -} - -MpfrFloat operator%(double lhs, const MpfrFloat& rhs) -{ - return MpfrFloat(lhs) % rhs; -} - -std::ostream& operator<<(std::ostream& os, const MpfrFloat& value) -{ - os << value.getAsString(unsigned(os.precision())); - return os; -} - -//=========================================================================== -// Static functions -//=========================================================================== -MpfrFloat MpfrFloat::log(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_log(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::log2(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_log2(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::log10(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_log10(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::exp(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_exp(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::exp2(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_exp2(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::exp10(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_exp10(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::cos(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_cos(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::sin(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_sin(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::tan(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_tan(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::sec(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_sec(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::csc(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_csc(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::cot(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_cot(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -void MpfrFloat::sincos(const MpfrFloat& value, - MpfrFloat& sin, - MpfrFloat& cos) -{ - sin.copyIfShared(); - cos.copyIfShared(); - mpfr_sin_cos - (sin.mData->mFloat, cos.mData->mFloat, value.mData->mFloat, GMP_RNDN); -} - -MpfrFloat MpfrFloat::acos(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_acos(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::asin(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_asin(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::atan(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_atan(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::atan2(const MpfrFloat& value1, const MpfrFloat& value2) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_atan2(retval.mData->mFloat, - value1.mData->mFloat, value2.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::hypot(const MpfrFloat& value1, const MpfrFloat& value2) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_hypot(retval.mData->mFloat, - value1.mData->mFloat, value2.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::cosh(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_cosh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::sinh(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_sinh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::tanh(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_tanh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::acosh(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_acosh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::asinh(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_asinh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::atanh(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_atanh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::sqrt(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_sqrt(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::cbrt(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_cbrt(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::root(const MpfrFloat& value, unsigned long root) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_root(retval.mData->mFloat, value.mData->mFloat, root, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::pow(const MpfrFloat& value1, const MpfrFloat& value2) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_pow(retval.mData->mFloat, - value1.mData->mFloat, value2.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::pow(const MpfrFloat& value, long exponent) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_pow_si(retval.mData->mFloat, value.mData->mFloat, exponent, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::abs(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_abs(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::dim(const MpfrFloat& value1, const MpfrFloat& value2) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_dim(retval.mData->mFloat, - value1.mData->mFloat, value2.mData->mFloat, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::round(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_round(retval.mData->mFloat, value.mData->mFloat); - return retval; -} - -MpfrFloat MpfrFloat::ceil(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_ceil(retval.mData->mFloat, value.mData->mFloat); - return retval; -} - -MpfrFloat MpfrFloat::floor(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_floor(retval.mData->mFloat, value.mData->mFloat); - return retval; -} - -MpfrFloat MpfrFloat::trunc(const MpfrFloat& value) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_trunc(retval.mData->mFloat, value.mData->mFloat); - return retval; -} - -MpfrFloat MpfrFloat::parseString(const char* str, char** endptr) -{ - MpfrFloat retval(MpfrFloat::kNoInitialization); - mpfr_strtofr(retval.mData->mFloat, str, endptr, 0, GMP_RNDN); - return retval; -} - -MpfrFloat MpfrFloat::const_pi() -{ - return mpfrFloatDataContainer().const_pi(); -} - -MpfrFloat MpfrFloat::const_e() -{ - return mpfrFloatDataContainer().const_e(); -} - -MpfrFloat MpfrFloat::const_log2() -{ - return mpfrFloatDataContainer().const_log2(); -} - -MpfrFloat MpfrFloat::someEpsilon() -{ - return mpfrFloatDataContainer().const_epsilon(); -} diff --git a/fparser/mpfr/MpfrFloat.hh b/fparser/mpfr/MpfrFloat.hh deleted file mode 100644 index d455d24..0000000 --- a/fparser/mpfr/MpfrFloat.hh +++ /dev/null @@ -1,206 +0,0 @@ -#ifndef ONCE_FP_MPFR_FLOAT_ -#define ONCE_FP_MPFR_FLOAT_ - -#include - -class MpfrFloat -{ - public: - /* A default of 256 bits will be used unless changed with this function. - Note that all existing and cached GMP objects will be resized to the - specified precision (which can be a somewhat heavy operation). - */ - static void setDefaultMantissaBits(unsigned long bits); - - static unsigned long getCurrentDefaultMantissaBits(); - - /* The default constructor initializes the object to the value 0. - It's efficient to instantiate such zero-initialized objects because - all of them will share the same mpfr data. (Also any object initialized - with or assigned the explicit value of zero will also share that one - mpfr data.) Thus multiple zero-initialized MpfrFloat instances won't - consume significant amounts of memory (until they are modified to - contain some other value, of course). - - Important caveat: - ---------------- - Note that initializing an MpfrFloat object with, for example, 0.1 will - suffer from accuracy problems (at least if the MpfrFloat object has - more mantissa bits than a double). The C++ double value 0.1 has only - 53 mantissa bits, while the MpfrFloat object usually has more. If the - MpfrFloat object is initialized with a double, only that many bits of - accuracy will end up in the value of the MpfrFloat object. This can - create significant rounding/accuracy problems in some cases. - If you need to initialize the MpfrObject with some value (which cannot - be represented accurately by base-2 floating point numbers, eg. 0.1) - at full mantissa precision, you have to use parseValue("0.1") instead, - rather than relying on the constructor taking a double type value. - */ - MpfrFloat(); - MpfrFloat(double value); - MpfrFloat(long double value); - MpfrFloat(long value); - MpfrFloat(int value); - MpfrFloat(const char* value, char** endptr); - - ~MpfrFloat(); - - MpfrFloat(const MpfrFloat&); - - MpfrFloat& operator=(const MpfrFloat&); - MpfrFloat& operator=(double value); - MpfrFloat& operator=(long double value); - MpfrFloat& operator=(long value); - MpfrFloat& operator=(int value); - //MpfrFloat& operator=(const char* value); - - void parseValue(const char* value); - void parseValue(const char* value, char** endptr); - - - /* This function can be used to retrieve the raw mpfr_t data structure - used by this object. (The template trick is used to avoid a dependency - of this header file with .) - In other words, it can be called like: - - mpfr_t raw_mpfr_data; - floatValue.get_raw_mpfr_data(raw_mpfr_data); - - Note that the returned mpfr_t should be considered as read-only and - not be modified from the outside because it may be shared among - several objects. If the calling code needs to modify the data, it - should copy it for itself first with the appropriate MPFR library - functions. - */ - template - void get_raw_mpfr_data(Mpfr_t& dest_mpfr_t); - - - /* Note that the returned char* points to an internal (shared) buffer - which will be valid until the next time this function is called - (by any object). - */ - const char* getAsString(unsigned precision) const; - - bool isInteger() const; - long toInt() const; - double toDouble() const; - - MpfrFloat& operator+=(const MpfrFloat&); - MpfrFloat& operator+=(double); - MpfrFloat& operator-=(const MpfrFloat&); - MpfrFloat& operator-=(double); - MpfrFloat& operator*=(const MpfrFloat&); - MpfrFloat& operator*=(double); - MpfrFloat& operator/=(const MpfrFloat&); - MpfrFloat& operator/=(double); - MpfrFloat& operator%=(const MpfrFloat&); - - void negate(); - void abs(); - - MpfrFloat operator+(const MpfrFloat&) const; - MpfrFloat operator+(double) const; - MpfrFloat operator-(const MpfrFloat&) const; - MpfrFloat operator-(double) const; - MpfrFloat operator*(const MpfrFloat&) const; - MpfrFloat operator*(double) const; - MpfrFloat operator/(const MpfrFloat&) const; - MpfrFloat operator/(double) const; - MpfrFloat operator%(const MpfrFloat&) const; - - MpfrFloat operator-() const; - - bool operator<(const MpfrFloat&) const; - bool operator<(double) const; - bool operator<=(const MpfrFloat&) const; - bool operator<=(double) const; - bool operator>(const MpfrFloat&) const; - bool operator>(double) const; - bool operator>=(const MpfrFloat&) const; - bool operator>=(double) const; - bool operator==(const MpfrFloat&) const; - bool operator==(double) const; - bool operator!=(const MpfrFloat&) const; - bool operator!=(double) const; - - static MpfrFloat log(const MpfrFloat&); - static MpfrFloat log2(const MpfrFloat&); - static MpfrFloat log10(const MpfrFloat&); - static MpfrFloat exp(const MpfrFloat&); - static MpfrFloat exp2(const MpfrFloat&); - static MpfrFloat exp10(const MpfrFloat&); - static MpfrFloat cos(const MpfrFloat&); - static MpfrFloat sin(const MpfrFloat&); - static MpfrFloat tan(const MpfrFloat&); - static MpfrFloat sec(const MpfrFloat&); - static MpfrFloat csc(const MpfrFloat&); - static MpfrFloat cot(const MpfrFloat&); - static void sincos(const MpfrFloat&, MpfrFloat& sin, MpfrFloat& cos); - static MpfrFloat acos(const MpfrFloat&); - static MpfrFloat asin(const MpfrFloat&); - static MpfrFloat atan(const MpfrFloat&); - static MpfrFloat atan2(const MpfrFloat&, const MpfrFloat&); - static MpfrFloat hypot(const MpfrFloat&, const MpfrFloat&); - static MpfrFloat cosh(const MpfrFloat&); - static MpfrFloat sinh(const MpfrFloat&); - static MpfrFloat tanh(const MpfrFloat&); - static MpfrFloat acosh(const MpfrFloat&); - static MpfrFloat asinh(const MpfrFloat&); - static MpfrFloat atanh(const MpfrFloat&); - static MpfrFloat sqrt(const MpfrFloat&); - static MpfrFloat cbrt(const MpfrFloat&); - static MpfrFloat root(const MpfrFloat&, unsigned long root); - static MpfrFloat pow(const MpfrFloat&, const MpfrFloat&); - static MpfrFloat pow(const MpfrFloat&, long exponent); - static MpfrFloat abs(const MpfrFloat&); - static MpfrFloat dim(const MpfrFloat&, const MpfrFloat&); - static MpfrFloat round(const MpfrFloat&); - static MpfrFloat ceil(const MpfrFloat&); - static MpfrFloat floor(const MpfrFloat&); - static MpfrFloat trunc(const MpfrFloat&); - - static MpfrFloat parseString(const char* str, char** endptr); - - // These values are cached (and recalculated every time the mantissa bits - // change), so it's efficient to call these repeatedly: - static MpfrFloat const_pi(); - static MpfrFloat const_e(); - static MpfrFloat const_log2(); - static MpfrFloat someEpsilon(); - - - private: - struct MpfrFloatData; - class MpfrFloatDataContainer; - - MpfrFloatData* mData; - - enum DummyType { kNoInitialization }; - MpfrFloat(DummyType); - MpfrFloat(MpfrFloatData*); - - void copyIfShared(); - static MpfrFloatDataContainer& mpfrFloatDataContainer(); - - friend MpfrFloat operator+(double lhs, const MpfrFloat& rhs); - friend MpfrFloat operator-(double lhs, const MpfrFloat& rhs); -}; - -MpfrFloat operator+(double lhs, const MpfrFloat& rhs); -MpfrFloat operator-(double lhs, const MpfrFloat& rhs); -MpfrFloat operator*(double lhs, const MpfrFloat& rhs); -MpfrFloat operator/(double lhs, const MpfrFloat& rhs); -MpfrFloat operator%(double lhs, const MpfrFloat& rhs); - -inline bool operator<(double lhs, const MpfrFloat& rhs) { return rhs > lhs; } -inline bool operator<=(double lhs, const MpfrFloat& rhs) { return rhs >= lhs; } -inline bool operator>(double lhs, const MpfrFloat& rhs) { return rhs < lhs; } -inline bool operator>=(double lhs, const MpfrFloat& rhs) { return rhs <= lhs; } -inline bool operator==(double lhs, const MpfrFloat& rhs) { return rhs == lhs; } -inline bool operator!=(double lhs, const MpfrFloat& rhs) { return rhs != lhs; } - -// This function takes into account the value of os.precision() -std::ostream& operator<<(std::ostream& os, const MpfrFloat& value); - -#endif -- cgit v1.2.3