Fixed compilation problems with Visual Studio 2013 and gcc.
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.
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).
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.
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.
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.
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:
Function
String containing the function to parse.
Vars
String 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:
On success the function returns -1.
On error the function returns an index to where the error was found
(0 is the first character, 1 the second, etc).
If the error was not a parsing error returns an index to the end of the
string.
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).
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:
double: 1e-12
float: 1e-5
long double: 1e-14
MpfrFloat: The value of MpfrFloat::someEpsilon()
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_ERROR
If 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:
On success returns the evaluated value of the function given to
Parse().
On error (such as division by 0) the return value is unspecified,
probably 0.
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:
1: division by zero
2: sqrt error (sqrt of a negative value)
3: log error (logarithm of a negative value)
4: trigonometric error (asin or acos of illegal value)
5: maximum recursion level in eval() reached
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.)
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.
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".
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 name of the function. The name follows the same naming conventions
as variable names.
A C++ function, which will be called when evaluating the function
string (if the user-given function is called there). The C++ function
must have the form:
double functionName(const double* params);
The number of parameters the function takes. 0 is a valid value
in which case the function takes no parameters (such function
should simply ignore the double* it gets as a parameter).
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:
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.)
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:
The FunctionParser instance given as parameter must be initialized
with a Parse() call before giving it as parameter. That
is, if you want to use the parser A in the parser
B, you must call A.Parse() before you can
call B.AddFunction("name", A).
The amount of variables in the FunctionParser instance given as
parameter must not change after it has been given to the
AddFunction()
of another instance. Changing the number of variables will result in
malfunction.
AddFunction() will fail (ie. return false)
if a recursive loop is
formed. The method specifically checks that no such loop is built.
The FunctionParser instance given as parameter will not be
copied internally, only referenced. Thus the FunctionParser instance
given as parameter must exist for as long as the other FunctionParser
instance uses it.
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).
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();")
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:
function: The input function string, as with
Parse().
amountOfVariablesFound: If non-null, the amount of found
variables will be assigned here.
resultVarString: The found variables will be written to
this string, in the same format as accepted by the Parse()
function. The variable names will be sorted using the <
operator of std::string.
resultVars: The found variables will be written to this
vector, each element being one variable name. They will be sorted using
the < operator of std::string. (The amount
of found variables can be retrieved, rather obviously, with the
size() method of the vector.)
useDegrees: As with Parse().
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:
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:
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:
(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:
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 unit
a unit multiplier (if one has been added)
A^B
exponentiation (A raised to the power B)
-A
unary minus
!A
unary logical not (result is 1 if int(A) is 0, else 0)
A*B A/B A%B
multiplication, division and modulo
A+B A-B
addition 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&B
result 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|B
result 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:
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 number
Character name
UTF-8 byte sequence
U+0009
HORIZONTAL TABULATION
09
U+000A
LINE FEED
0A
U+000B
VERTICAL TABULATION
0B
U+000D
CARRIAGE RETURN
0D
U+0020
SPACE
20
U+00A0
NO-BREAK SPACE
C2 A0
U+2000
EN QUAD
E2 80 80
U+2001
EM QUAD
E2 80 81
U+2002
EN SPACE
E2 80 82
U+2003
EM SPACE
E2 80 83
U+2004
THREE-PER-EM SPACE
E2 80 84
U+2005
FOUR-PER-EM SPACE
E2 80 85
U+2006
SIX-PER-EM SPACE
E2 80 86
U+2007
FIGURE SPACE
E2 80 87
U+2008
PUNCTUATION SPACE
E2 80 88
U+2009
THIN SPACE
E2 80 89
U+200A
HAIR SPACE
E2 80 8A
U+200B
ZERO WIDTH SPACE
E2 80 8B
U+202F
NARROW NO-BREAK SPACE
E2 80 AF
U+205F
MEDIUM MATHEMATICAL SPACE
E2 81 9F
U+3000
IDEOGRAPHIC 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:
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:
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:
Division by (the exact value of) zero.
Square root of a negative value.
Logarithm of a non-positive value.
Arcsine or arccosine of a value not in the range [-1, 1]. (This includes
hyperbolic versions of the functions.)
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
This Library is distributed under the
Lesser General Public
License (LGPL) version 3.
fparserc++-4.5.2/docs/gpl.txt 0000664 0000000 0000000 00000104513 13327317146 0015743 0 ustar 00root root 0000000 0000000 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
.
fparserc++-4.5.2/docs/lgpl.txt 0000664 0000000 0000000 00000016725 13327317146 0016126 0 ustar 00root root 0000000 0000000 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.
fparserc++-4.5.2/docs/style.css 0000664 0000000 0000000 00000001564 13327317146 0016274 0 ustar 00root root 0000000 0000000 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;
}
fparserc++-4.5.2/examples/ 0000775 0000000 0000000 00000000000 13327317146 0015302 5 ustar 00root root 0000000 0000000 fparserc++-4.5.2/examples/example.cc 0000664 0000000 0000000 00000002252 13327317146 0017245 0 ustar 00root root 0000000 0000000 // 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;
}
fparserc++-4.5.2/examples/example2.cc 0000664 0000000 0000000 00000004140 13327317146 0017325 0 ustar 00root root 0000000 0000000 // 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;
}
fparserc++-4.5.2/extrasrc/ 0000775 0000000 0000000 00000000000 13327317146 0015317 5 ustar 00root root 0000000 0000000 fparserc++-4.5.2/extrasrc/fp_identifier_parser.inc 0000664 0000000 0000000 00000020370 13327317146 0022177 0 ustar 00root root 0000000 0000000 /* 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;
fparserc++-4.5.2/extrasrc/fp_opcode_add.inc 0000664 0000000 0000000 00000224665 13327317146 0020577 0 ustar 00root root 0000000 0000000 /* Function Parser for C++ v4.5.2
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
fparserc++-4.5.2/extrasrc/fpaux.hh 0000664 0000000 0000000 00000127652 13327317146 0017000 0 ustar 00root root 0000000 0000000 /***************************************************************************\
|* Function Parser for C++ v4.5.2 *|
|*-------------------------------------------------------------------------*|
|* 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); }
template
inline std::complex fp_hypot
(const std::complex& x, const std::complex& y)
{ return fp_sqrt(x*x + y*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); }
template
inline std::complex fp_log2(const std::complex& x)
{
return fp_log(x) * fp_const_log2inv();
}
#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