"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "fparser/fparser.cc" between
mathmod-11.0-source.zip and mathmod-11.1-source.zip

About: MathMod is a mathematical modeling software that visualize and animate implicit and parametric surfaces.

fparser.cc  (mathmod-11.0-source):fparser.cc  (mathmod-11.1-source)
skipping to change at line 2592 skipping to change at line 2592
template<typename Value_t> template<typename Value_t>
Value_t FunctionParserBase<Value_t>::Eval(const Value_t* Vars) Value_t FunctionParserBase<Value_t>::Eval(const Value_t* Vars)
{ {
if(mData->mParseErrorType != FP_NO_ERROR) return Value_t(0); if(mData->mParseErrorType != FP_NO_ERROR) return Value_t(0);
const unsigned* const byteCode = &(mData->mByteCode[0]); const unsigned* const byteCode = &(mData->mByteCode[0]);
const Value_t* const immed = mData->mImmed.empty() ? 0 : &(mData->mImmed[0]) ; const Value_t* const immed = mData->mImmed.empty() ? 0 : &(mData->mImmed[0]) ;
const unsigned byteCodeSize = unsigned(mData->mByteCode.size()); const unsigned byteCodeSize = unsigned(mData->mByteCode.size());
unsigned IP, DP=0; unsigned IP, DP=0;
int SP=-1; int SP=-1;
int stt =0; //int stt =0;
std::vector<Value_t>& StackSave = mData->mStackSave; std::vector<Value_t>& StackSave = mData->mStackSave;
int VarSize = StackSave.size(); int VarSize = StackSave.size();
#ifdef FP_USE_THREAD_SAFE_EVAL #ifdef FP_USE_THREAD_SAFE_EVAL
/* If Eval() may be called by multiple threads simultaneously, /* If Eval() may be called by multiple threads simultaneously,
* then Eval() must allocate its own stack. * then Eval() must allocate its own stack.
*/ */
#ifdef FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA #ifdef FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA
/* alloca() allocates room from the hardware stack. /* alloca() allocates room from the hardware stack.
* It is automatically freed when the function returns. * It is automatically freed when the function returns.
skipping to change at line 2769 skipping to change at line 2769
if(Stack[SP-1] == Value_t(0) && Stack[SP] < Value_t(0)) if(Stack[SP-1] == Value_t(0) && Stack[SP] < Value_t(0))
{ {
mData->mEvalErrorType=3; mData->mEvalErrorType=3;
return Value_t(0); return Value_t(0);
} }
Stack[SP-1] = fp_pow(Stack[SP-1], Stack[SP]); Stack[SP-1] = fp_pow(Stack[SP-1], Stack[SP]);
--SP; --SP;
break; break;
case cPsh: case cPsh:
if((stt= Stack[SP-1]) >=VarSize || stt <0) if((Stack[SP-1]) >= Value_t(VarSize) || Stack[SP-1] <Value_t(0))
{ {
mData->mEvalErrorType=VAR_OVERFLOW; mData->mEvalErrorType=VAR_OVERFLOW;
return Value_t(VAR_OVERFLOW); return Value_t(7);
} }
StackSave[stt] = Stack[SP]; StackSave[abs(Stack[SP-1])] = Stack[SP];
Stack[SP-1] = 1.0; Stack[SP-1] = 1.0;
--SP; --SP;
break; break;
case cCsd: case cCsd:
if((stt= Stack[SP]) >=VarSize || stt <0) if(Stack[SP] >= Value_t(VarSize) || Stack[SP] <Value_t(0))
{ {
mData->mEvalErrorType=VAR_OVERFLOW; mData->mEvalErrorType=VAR_OVERFLOW;
return Value_t(VAR_OVERFLOW); return Value_t(7);
} }
Stack[SP] = StackSave[stt]; Stack[SP] = StackSave[abs(Stack[SP])];
break; break;
case cTrunc: case cTrunc:
Stack[SP] = fp_trunc(Stack[SP]); Stack[SP] = fp_trunc(Stack[SP]);
break; break;
case cSec: case cSec:
{ {
const Value_t c = fp_cos(Stack[SP]); const Value_t c = fp_cos(Stack[SP]);
if(c == Value_t(0)) if(c == Value_t(0))
skipping to change at line 3020 skipping to change at line 3020
// Variables: // Variables:
default: default:
Stack[++SP] = Vars[byteCode[IP]-VarBegin]; Stack[++SP] = Vars[byteCode[IP]-VarBegin];
} }
} }
mData->mEvalErrorType=0; mData->mEvalErrorType=0;
return Stack[SP]; return Stack[SP];
} }
//===========================================================================
// Function evaluation
//===========================================================================
template<typename Value_t>
std::complex<double> FunctionParserBase<Value_t>::EvalC(const std::complex<doubl
e>* Vars)
{
if(mData->mParseErrorType != FP_NO_ERROR) return Value_t(0);
const unsigned* const byteCode = &(mData->mByteCode[0]);
const Value_t* const immed = mData->mImmed.empty() ? 0 : &(mData->mImmed[0])
;
const unsigned byteCodeSize = unsigned(mData->mByteCode.size());
unsigned IP, DP=0;
int SP=-1;
std::vector<Value_t>& StackSave = mData->mStackSave;
unsigned int VarSize = StackSave.size();
#ifdef FP_USE_THREAD_SAFE_EVAL
/* If Eval() may be called by multiple threads simultaneously,
* then Eval() must allocate its own stack.
*/
#ifdef FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA
/* alloca() allocates room from the hardware stack.
* It is automatically freed when the function returns.
*/
Value_t* const Stack = (Value_t*)alloca(mData->mStackSize*sizeof(Value_t));
#else
/* Allocate from the heap. Ensure that it is freed
* automatically no matter which exit path is taken.
*/
struct AutoDealloc
{
Value_t* ptr;
~AutoDealloc() { delete[] ptr; }
} AutoDeallocStack = { new Value_t[mData->mStackSize] };
Value_t*& Stack = AutoDeallocStack.ptr;
#endif
#else
/* No thread safety, so use a global stack. */
//std::vector<Value_t>& Stack = mData->mStack;
#endif
std::complex<double>* const Stack = (std::complex<double>*)alloca(mData->mSt
ackSize*sizeof(std::complex<double>));
for(IP=0; IP<byteCodeSize; ++IP)
{
switch(byteCode[IP])
{
// Functions:
case cAbs: Stack[SP] = fp_abs(Stack[SP]); break;
case cAcos:
Stack[SP] = fp_acos(Stack[SP]); break;
case cAcosh:
Stack[SP] = fp_acosh(Stack[SP]); break;
case cAsin:
Stack[SP] = fp_asin(Stack[SP]); break;
case cAsinh: Stack[SP] = fp_asinh(Stack[SP]); break;
case cAtan: Stack[SP] = fp_atan(Stack[SP]); break;
case cAtan2: Stack[SP-1] = fp_atan2(Stack[SP-1], Stack[SP]);
--SP; break;
case cAtanh:
Stack[SP] = fp_atanh(Stack[SP]); break;
case cCbrt: Stack[SP] = fp_cbrt(Stack[SP]); break;
case cCeil: Stack[SP] = fp_ceil(Stack[SP]); break;
case cCos: Stack[SP] = fp_cos(Stack[SP]); break;
case cCosh: Stack[SP] = fp_cosh(Stack[SP]); break;
case cCot:
{
const std::complex<double> t = fp_tan(Stack[SP]);
Stack[SP] = (1.0)/t; break;
}
case cCsc:
{
const std::complex<double> s = fp_sin(Stack[SP]);
Stack[SP] = (1.0)/s; break;
}
case cExp: Stack[SP] = fp_exp(Stack[SP]); break;
case cExp2: Stack[SP] = fp_exp2(Stack[SP]); break;
case cFloor: Stack[SP] = fp_floor(Stack[SP]); break;
case cHypot:
Stack[SP-1] = fp_hypot(Stack[SP-1], Stack[SP]);
--SP; break;
case cIf:
if(fp_truth(Stack[SP--]))
IP += 2;
else
{
const unsigned* buf = &byteCode[IP+1];
IP = buf[0];
DP = buf[1];
}
break;
case cInt: Stack[SP] = fp_int(Stack[SP]); break;
case cLog:
Stack[SP] = fp_log(Stack[SP]); break;
case cLog10:
Stack[SP] = fp_log10(Stack[SP]);
break;
case cLog2:
Stack[SP] = fp_log2(Stack[SP]);
break;
case cMax: Stack[SP-1] = fp_max(Stack[SP-1], Stack[SP]);
--SP; break;
case cMin: Stack[SP-1] = fp_min(Stack[SP-1], Stack[SP]);
--SP; break;
case cPow:
// x:Negative ^ y:NonInteger is failure,
// except when the reciprocal of y forms an integer
/*if(IsComplexType<Value_t>::result == false
&& Stack[SP-1] < Value_t(0) &&
!isInteger(Stack[SP]) &&
!isInteger(1.0 / Stack[SP]))
{ mEvalErrorType=3; return Value_t(0); }*/
// x:0 ^ y:negative is failure
/*
if(Stack[SP-1] == Value_t(0) &&
Stack[SP] < Value_t(0))
{ mData->mEvalErrorType=3; return Value_t(0); }*/
Stack[SP-1] = fp_pow(Stack[SP-1], Stack[SP]);
--SP; break;
case cPsh:
if((Stack[SP-1]).real() >= VarSize || Stack[SP-1].real() < 0)
{
mData->mEvalErrorType=VAR_OVERFLOW;
return Value_t(7);
}
StackSave[abs(Stack[SP-1])] = (Stack[SP]).real();
Stack[SP-1] = 1.0;
--SP;
break;
case cCsd:
if(Stack[SP].real() >= VarSize || Stack[SP].real() < 0)
{
mData->mEvalErrorType=VAR_OVERFLOW;
return Value_t(7);
}
Stack[SP] = StackSave[abs(Stack[SP])];
break;
case cTrunc: Stack[SP] = fp_trunc(Stack[SP]); break;
case cSec:
{
const std::complex<double> c = fp_cos(Stack[SP]);
if(abs(c) == 0)
{ mData->mEvalErrorType=1; return Value_t(0); }
Stack[SP] = (1.0)/c; break;
}
case cSin: Stack[SP] = fp_sin(Stack[SP]); break;
case cSinh: Stack[SP] = fp_sinh(Stack[SP]); break;
case cSqrt:
/*
if(IsComplexType<Value_t>::result == false &&
Stack[SP] < Value_t(0))
{ mData->mEvalErrorType=2; return Value_t(0); }
*/
Stack[SP] = fp_sqrt(Stack[SP]); break;
case cTan: Stack[SP] = fp_tan(Stack[SP]); break;
case cTanh: Stack[SP] = fp_tanh(Stack[SP]); break;
// Misc:
case cImmed: Stack[++SP] = immed[DP++]; break;
case cJump:
{
const unsigned* buf = &byteCode[IP+1];
IP = buf[0];
DP = buf[1];
break;
}
// Operators:
case cNeg: Stack[SP] = -Stack[SP]; break;
case cAdd: Stack[SP-1] += Stack[SP]; --SP; break;
case cSub: Stack[SP-1] -= Stack[SP]; --SP; break;
case cMul: Stack[SP-1] *= Stack[SP]; --SP; break;
case cDiv:
if(abs(Stack[SP]) == 0)
{ mData->mEvalErrorType=1; return Value_t(0); }
Stack[SP-1] /= Stack[SP];
--SP; break;
case cMod:
if(abs(Stack[SP]) == 0)
{ mData->mEvalErrorType=1; return Value_t(0); }
Stack[SP-1] = fp_mod(Stack[SP-1], Stack[SP]);
--SP; break;
case cEqual:
Stack[SP-1] = fp_equal(Stack[SP-1], Stack[SP]);
--SP; break;
case cNEqual:
Stack[SP-1] = fp_nequal(Stack[SP-1], Stack[SP]);
--SP; break;
case cLess:
Stack[SP-1] = fp_less(Stack[SP-1], Stack[SP]);
--SP; break;
case cLessOrEq:
Stack[SP-1] = fp_lessOrEq(Stack[SP-1], Stack[SP]);
--SP; break;
case cGreater:
Stack[SP-1] = fp_less(Stack[SP], Stack[SP-1]);
--SP; break;
case cGreaterOrEq:
Stack[SP-1] = fp_lessOrEq(Stack[SP], Stack[SP-1]);
--SP; break;
case cNot: Stack[SP] = fp_not(Stack[SP]); break;
case cNotNot: Stack[SP] = fp_notNot(Stack[SP]); break;
case cAnd:
Stack[SP-1] = fp_and(Stack[SP-1], Stack[SP]);
--SP; break;
case cOr:
Stack[SP-1] = fp_or(Stack[SP-1], Stack[SP]);
--SP; break;
// Degrees-radians conversion:
case cDeg: Stack[SP] = RadiansToDegrees(Stack[SP]); break;
case cRad: Stack[SP] = DegreesToRadians(Stack[SP]); break;
// User-defined function calls:
case cFCall:
{
const unsigned index = byteCode[++IP];
const unsigned params = mData->mFuncPtrs[index].mParams;
const Value_t hy = Stack[SP-params+1].real();
std::complex<double> retVal =
mData->mFuncPtrs[index].mRawFuncPtr ?
mData->mFuncPtrs[index].mRawFuncPtr(&hy) :
mData->mFuncPtrs[index].mFuncWrapperPtr->callFunction
(&hy);
SP -= int(params)-1;
Stack[SP] = retVal;
break;
}
case cPCall:
{
unsigned index = byteCode[++IP];
unsigned params = mData->mFuncParsers[index].mParams;
std::complex<double> retVal =
mData->mFuncParsers[index].mParserPtr->EvalC
(&Stack[SP-params+1]);
SP -= int(params)-1;
Stack[SP] = retVal;
const int error =
mData->mFuncParsers[index].mParserPtr->EvalError();
if(error)
{
mData->mEvalErrorType = error;
return 0;
}
break;
}
case cFetch:
{
unsigned stackOffs = byteCode[++IP];
Stack[SP+1] = Stack[stackOffs]; ++SP;
break;
}
#ifdef FP_SUPPORT_OPTIMIZER
case cPopNMov:
{
unsigned stackOffs_target = byteCode[++IP];
unsigned stackOffs_source = byteCode[++IP];
Stack[stackOffs_target] = Stack[stackOffs_source];
SP = stackOffs_target;
break;
}
case cLog2by:/*
if(IsComplexType<Value_t>::result
? Stack[SP-1] == Value_t(0)
: !(Stack[SP-1] > Value_t(0)))
{ mData->mEvalErrorType=3; return Value_t(0); }*/
Stack[SP-1] = fp_log2(Stack[SP-1]) * Stack[SP];
--SP;
break;
case cNop: break;
#endif // FP_SUPPORT_OPTIMIZER
case cSinCos:
fp_sinCos(Stack[SP], Stack[SP+1], Stack[SP]);
++SP;
break;
case cSinhCosh:
fp_sinhCosh(Stack[SP], Stack[SP+1], Stack[SP]);
++SP;
break;
case cAbsNot:
Stack[SP] = fp_absNot(Stack[SP]); break;
case cAbsNotNot:
Stack[SP] = fp_absNotNot(Stack[SP]); break;
case cAbsAnd:
Stack[SP-1] = fp_absAnd(Stack[SP-1], Stack[SP]);
--SP; break;
case cAbsOr:
Stack[SP-1] = fp_absOr(Stack[SP-1], Stack[SP]);
--SP; break;
case cAbsIf:
if(fp_absTruth(Stack[SP--]))
IP += 2;
else
{
const unsigned* buf = &byteCode[IP+1];
IP = buf[0];
DP = buf[1];
}
break;
case cDup: Stack[SP+1] = Stack[SP]; ++SP; break;
case cInv:/*
if(Stack[SP] == Value_t(0))
{ mData->mEvalErrorType=1; return Value_t(0); }*/
Stack[SP] = (1.0)/Stack[SP];
break;
case cSqr:
Stack[SP] = Stack[SP]*Stack[SP];
break;
case cRDiv:/*
if(Stack[SP-1] == Value_t(0))
{ mData->mEvalErrorType=1; return Value_t(0); }*/
Stack[SP-1] = Stack[SP] / Stack[SP-1]; --SP; break;
case cRSub: Stack[SP-1] = Stack[SP] - Stack[SP-1]; --SP; break;
case cRSqrt:/*
if(Stack[SP] == Value_t(0))
{ mData->mEvalErrorType=1; return Value_t(0); }*/
Stack[SP] = (1.0) / fp_sqrt(Stack[SP]); break;
#ifdef FP_SUPPORT_COMPLEX_NUMBERS
case cReal: Stack[SP] = fp_real(Stack[SP]); break;
case cImag: Stack[SP] = fp_imag(Stack[SP]); break;
case cArg: Stack[SP] = fp_arg(Stack[SP]); break;
case cConj: Stack[SP] = fp_conj(Stack[SP]); break;
case cPolar:
Stack[SP-1] = fp_polar(Stack[SP-1], Stack[SP]);
--SP; break;
#endif
// Variables:
default:
Stack[++SP] = Vars[byteCode[IP]-VarBegin];
}
}
mData->mEvalErrorType=0;
return (Stack[SP]);
}
template<typename Value_t> template<typename Value_t>
void FunctionParserBase<Value_t>::AllocateStackMemory(unsigned int nbStack, int nbvar) void FunctionParserBase<Value_t>::AllocateStackMemory(unsigned int nbStack, int nbvar)
{ {
mData->mStacki.resize(nbStack*(mData->mStack).size()); mData->mStacki.resize(nbStack*(mData->mStack).size());
mData->mStackSave.resize(nbvar*nbStack); // Should be done earlier mData->mStackSave.resize(nbvar*nbStack); // Should be done earlier
} }
template<typename Value_t> template<typename Value_t>
Value_t FunctionParserBase<Value_t>::Eval2(const Value_t* Vars, unsigned NbVar, double* results, unsigned NbStack, int SP) Value_t FunctionParserBase<Value_t>::Eval2(const Value_t* Vars, unsigned NbVar, Value_t* results, unsigned NbStack, int SP)
{ {
if(mData->mParseErrorType != FP_NO_ERROR) return Value_t(0); if(mData->mParseErrorType != FP_NO_ERROR) return Value_t(0);
const unsigned* const byteCode = &(mData->mByteCode[0]); const unsigned* const byteCode = &(mData->mByteCode[0]);
const Value_t* const immed = mData->mImmed.empty() ? 0 : &(mData->mImmed[0]) ; const Value_t* const immed = mData->mImmed.empty() ? 0 : &(mData->mImmed[0]) ;
const unsigned byteCodeSize = unsigned(mData->mByteCode.size()); const unsigned byteCodeSize = unsigned(mData->mByteCode.size());
unsigned IP, DP=0, Nbval; unsigned IP, DP=0, Nbval;
/* No thread safety, so use a global stack. */ /* No thread safety, so use a global stack. */
std::vector<Value_t>& Stack = mData->mStack; std::vector<Value_t>& Stack = mData->mStack;
std::vector<Value_t>& Stacki = mData->mStacki; std::vector<Value_t>& Stacki = mData->mStacki;
std::vector<Value_t>& StackSave = mData->mStackSave; std::vector<Value_t>& StackSave = mData->mStackSave;
int Size = Stack.size(); int Size = Stack.size();
int VarSize = StackSave.size(); int VarSize = StackSave.size();
int stt; Value_t stt;
for(IP=0; IP<byteCodeSize; ++IP) for(IP=0; IP<byteCodeSize; ++IP)
{ {
switch(byteCode[IP]) switch(byteCode[IP])
{ {
// Functions: // Functions:
case cCos: case cCos:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
Stacki[Nbval*Size+SP] = fp_cos(Stacki[Nbval*Size+SP]); Stacki[Nbval*Size+SP] = fp_cos(Stacki[Nbval*Size+SP]);
break; break;
skipping to change at line 3133 skipping to change at line 3531
case cCosh: case cCosh:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
Stacki[Nbval*Size+SP] = fp_cosh(Stacki[Nbval*Size+SP]); Stacki[Nbval*Size+SP] = fp_cosh(Stacki[Nbval*Size+SP]);
break; break;
case cCot: case cCot:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
{ {
const Value_t t = fp_tan(Stacki[Nbval*Size+SP]); const Value_t t = fp_tan(Stacki[Nbval*Size+SP]);
if(t == Value_t(0)) if(t == Value_t(0))
{ mData->mEvalErrorType=DIVISION_BY_ZERO; return Value_t(DIVIS ION_BY_ZERO); } { mData->mEvalErrorType=DIVISION_BY_ZERO; return Value_t(1); }
Stacki[Nbval*Size+SP] = Value_t(1)/t; Stacki[Nbval*Size+SP] = Value_t(1)/t;
} }
break; break;
case cCsc: case cCsc:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
{ {
const Value_t s = fp_sin(Stacki[Nbval*Size+SP]); const Value_t s = fp_sin(Stacki[Nbval*Size+SP]);
if(s == Value_t(0)) if(s == Value_t(0))
{ mData->mEvalErrorType=DIVISION_BY_ZERO; return Value_t(DIVIS ION_BY_ZERO); } { mData->mEvalErrorType=DIVISION_BY_ZERO; return Value_t(1); }
Stacki[Nbval*Size+SP] = Value_t(1)/s; Stacki[Nbval*Size+SP] = Value_t(1)/s;
} }
break; break;
case cExp: case cExp:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
Stacki[Nbval*Size+SP] = fp_exp(Stacki[Nbval*Size+SP]); Stacki[Nbval*Size+SP] = fp_exp(Stacki[Nbval*Size+SP]);
break; break;
case cExp2: case cExp2:
skipping to change at line 3176 skipping to change at line 3574
--SP; --SP;
break; break;
case cIf: case cIf:
{ {
bool valid = fp_truth(Stacki[SP]); bool valid = fp_truth(Stacki[SP]);
for(Nbval=1; Nbval<NbStack; Nbval++) for(Nbval=1; Nbval<NbStack; Nbval++)
if(valid != fp_truth(Stacki[Nbval*Size+SP])) if(valid != fp_truth(Stacki[Nbval*Size+SP]))
{ {
mData->mEvalErrorType=IF_FUNCT_ERROR; return Value_t(IF_FUNC T_ERROR); mData->mEvalErrorType=IF_FUNCT_ERROR; return Value_t(5);
} }
if(valid) if(valid)
IP += 2; IP += 2;
else else
{ {
const unsigned* buf = &byteCode[IP+1]; const unsigned* buf = &byteCode[IP+1];
IP = buf[0]; IP = buf[0];
DP = buf[1]; DP = buf[1];
} }
} }
skipping to change at line 3258 skipping to change at line 3656
{ {
if(Stacki[Nbval*Size+SP-1] == Value_t(0) && if(Stacki[Nbval*Size+SP-1] == Value_t(0) &&
Stacki[Nbval*Size+SP] < Value_t(0)) Stacki[Nbval*Size+SP] < Value_t(0))
{ mData->mEvalErrorType=3; return Value_t(0); } { mData->mEvalErrorType=3; return Value_t(0); }
Stacki[Nbval*Size+SP-1] = fp_pow(Stacki[Nbval*Size+SP-1], Stac ki[Nbval*Size+SP]); Stacki[Nbval*Size+SP-1] = fp_pow(Stacki[Nbval*Size+SP-1], Stac ki[Nbval*Size+SP]);
} }
--SP; break; --SP; break;
case cPsh: case cPsh:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
{ {
if((stt= NbStack*(Stacki[Nbval*Size+SP-1])+Nbval) >= VarSize || st stt = (Value_t(NbStack)*(Stacki[Nbval*Size+SP-1])+Value_t(Nbval));
t <0) if(stt >= Value_t(VarSize) || stt < Value_t(0))
{ {
mData->mEvalErrorType=VAR_OVERFLOW; mData->mEvalErrorType=VAR_OVERFLOW;
return Value_t(VAR_OVERFLOW); return Value_t(7);
} }
StackSave[stt] = Stacki[Nbval*Size+SP]; StackSave[abs(stt)] = Stacki[Nbval*Size+SP];
Stacki[Nbval*Size+SP-1] = 1.0; Stacki[Nbval*Size+SP-1] = 1.0;
} }
--SP; --SP;
break; break;
case cCsd: case cCsd:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
{ {
if((stt= NbStack*(Stacki[Nbval*Size+SP])+Nbval) >= VarSize || stt stt = (Value_t(NbStack)*(Stacki[Nbval*Size+SP])+Value_t(Nbval));
<0) if(stt >= Value_t(VarSize) || stt < Value_t(0))
{ {
mData->mEvalErrorType=VAR_OVERFLOW; mData->mEvalErrorType=VAR_OVERFLOW;
return Value_t(VAR_OVERFLOW); return Value_t(7);
} }
Stacki[Nbval*Size+SP] = StackSave[stt]; Stacki[Nbval*Size+SP] = StackSave[abs(stt)];
} }
break; break;
case cTrunc: case cTrunc:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
Stacki[Nbval*Size+SP] = fp_trunc(Stacki[Nbval*Size+SP]); Stacki[Nbval*Size+SP] = fp_trunc(Stacki[Nbval*Size+SP]);
break; break;
case cSec: case cSec:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
{ {
const Value_t c = fp_cos(Stacki[Nbval*Size+SP]); const Value_t c = fp_cos(Stacki[Nbval*Size+SP]);
if(c == Value_t(0)) if(c == Value_t(0))
{ {
mData->mEvalErrorType=DIVISION_BY_ZERO; mData->mEvalErrorType=DIVISION_BY_ZERO;
return Value_t(DIVISION_BY_ZERO); return Value_t(1);
} }
Stacki[Nbval*Size+SP] = Value_t(1)/c; Stacki[Nbval*Size+SP] = Value_t(1)/c;
} }
break; break;
case cSin: case cSin:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
Stacki[Nbval*Size+SP] = fp_sin(Stacki[Nbval*Size+SP]); Stacki[Nbval*Size+SP] = fp_sin(Stacki[Nbval*Size+SP]);
break; break;
case cSinh: case cSinh:
skipping to change at line 3369 skipping to change at line 3769
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
Stacki[Nbval*Size+SP-1] *= Stacki[Nbval*Size+SP]; Stacki[Nbval*Size+SP-1] *= Stacki[Nbval*Size+SP];
--SP; --SP;
break; break;
case cDiv: case cDiv:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
{ {
if(Stacki[Nbval*Size+SP] == Value_t(0)) if(Stacki[Nbval*Size+SP] == Value_t(0))
{ {
mData->mEvalErrorType=DIVISION_BY_ZERO; mData->mEvalErrorType=DIVISION_BY_ZERO;
return Value_t(DIVISION_BY_ZERO); return Value_t(1);
} }
Stacki[Nbval*Size+SP-1] /= Stacki[Nbval*Size+SP]; Stacki[Nbval*Size+SP-1] /= Stacki[Nbval*Size+SP];
} }
--SP; break; --SP; break;
case cMod: case cMod:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
{ {
if(Stacki[Nbval*Size+SP] == Value_t(0)) if(Stacki[Nbval*Size+SP] == Value_t(0))
{ {
mData->mEvalErrorType=DIVISION_BY_ZERO; mData->mEvalErrorType=DIVISION_BY_ZERO;
return Value_t(DIVISION_BY_ZERO); return Value_t(0);
} }
Stacki[Nbval*Size+SP-1] = fp_mod(Stacki[Nbval*Size+SP-1], Stacki[N bval*Size+SP]); Stacki[Nbval*Size+SP-1] = fp_mod(Stacki[Nbval*Size+SP-1], Stacki[N bval*Size+SP]);
} }
--SP; --SP;
break; break;
case cEqual: case cEqual:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
Stacki[Nbval*Size+SP-1] = fp_equal(Stacki[Nbval*Size+SP-1], Stacki [Nbval*Size+SP]); Stacki[Nbval*Size+SP-1] = fp_equal(Stacki[Nbval*Size+SP-1], Stacki [Nbval*Size+SP]);
--SP; --SP;
break; break;
skipping to change at line 3538 skipping to change at line 3938
case cAbsOr: case cAbsOr:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
Stacki[Nbval*Size+SP-1] = fp_absOr(Stacki[Nbval*Size+SP-1], St acki[Nbval*Size+SP]); Stacki[Nbval*Size+SP-1] = fp_absOr(Stacki[Nbval*Size+SP-1], St acki[Nbval*Size+SP]);
--SP; break; --SP; break;
case cAbsIf: case cAbsIf:
{ {
bool valid = fp_absTruth(Stacki[SP]); bool valid = fp_absTruth(Stacki[SP]);
for(Nbval=1; Nbval<NbStack; Nbval++) for(Nbval=1; Nbval<NbStack; Nbval++)
if(valid != fp_absTruth(Stacki[Nbval*Size+SP])) if(valid != fp_absTruth(Stacki[Nbval*Size+SP]))
{ mData->mEvalErrorType=IF_FUNCT_ERROR; return Value_t(I F_FUNCT_ERROR); } { mData->mEvalErrorType=IF_FUNCT_ERROR; return Value_t(5 ); }
if(valid) if(valid)
IP += 2; IP += 2;
else else
{ {
const unsigned* buf = &byteCode[IP+1]; const unsigned* buf = &byteCode[IP+1];
IP = buf[0]; IP = buf[0];
DP = buf[1]; DP = buf[1];
} }
} }
skipping to change at line 3560 skipping to change at line 3960
break; break;
case cDup: case cDup:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
Stacki[Nbval*Size+SP+1] = Stacki[Nbval*Size+SP]; Stacki[Nbval*Size+SP+1] = Stacki[Nbval*Size+SP];
++SP; break; ++SP; break;
case cInv: case cInv:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
{ {
if(Stacki[Nbval*Size+SP] == Value_t(0)) if(Stacki[Nbval*Size+SP] == Value_t(0))
{ mData->mEvalErrorType=DIVISION_BY_ZERO; return Value_t(DIVISION_ BY_ZERO); } { mData->mEvalErrorType=DIVISION_BY_ZERO; return Value_t(1); }
Stacki[Nbval*Size+SP] = Value_t(1)/Stacki[Nbval*Size+SP]; Stacki[Nbval*Size+SP] = Value_t(1)/Stacki[Nbval*Size+SP];
} }
break; break;
case cSqr: case cSqr:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
Stacki[Nbval*Size+SP] = Stacki[Nbval*Size+SP]*Stacki[Nbval *Size+SP]; Stacki[Nbval*Size+SP] = Stacki[Nbval*Size+SP]*Stacki[Nbval *Size+SP];
break; break;
case cRDiv: case cRDiv:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
{ {
if(Stacki[Nbval*Size+SP-1] == Value_t(0)) if(Stacki[Nbval*Size+SP-1] == Value_t(0))
{ mData->mEvalErrorType=DIVISION_BY_ZERO; return Value_t(DIVISION_ BY_ZERO); } { mData->mEvalErrorType=DIVISION_BY_ZERO; return Value_t(1); }
Stacki[Nbval*Size+SP-1] = Stacki[Nbval*Size+SP] / Stacki[Nbval*Siz e+SP-1]; Stacki[Nbval*Size+SP-1] = Stacki[Nbval*Size+SP] / Stacki[Nbval*Siz e+SP-1];
} }
--SP; break; --SP; break;
case cRSub: case cRSub:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
Stacki[Nbval*Size+SP-1] = Stacki[Nbval*Size+SP] - Stacki[Nbval*S ize+SP-1]; Stacki[Nbval*Size+SP-1] = Stacki[Nbval*Size+SP] - Stacki[Nbval*S ize+SP-1];
--SP; break; --SP; break;
case cRSqrt: case cRSqrt:
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
{ {
if(Stacki[Nbval*Size+SP] == Value_t(0)) if(Stacki[Nbval*Size+SP] == Value_t(0))
{ mData->mEvalErrorType=DIVISION_BY_ZERO; return Value_t(DIVISIO N_BY_ZERO); } { mData->mEvalErrorType=DIVISION_BY_ZERO; return Value_t(1); }
Stacki[Nbval*Size+SP] = Value_t(1) / fp_sqrt(Stacki[Nbval*Size+S P]); Stacki[Nbval*Size+SP] = Value_t(1) / fp_sqrt(Stacki[Nbval*Size+S P]);
} }
break; break;
#ifdef FP_SUPPORT_COMPLEX_NUMBERS #ifdef FP_SUPPORT_COMPLEX_NUMBERS
case cReal:for(Nbval=0; Nbval<NbStack; Nbval++) case cReal:
Stacki[Nbval*Size+SP] = fp_real(Stacki[Nbval*Size+SP]); break; for(Nbval=0; Nbval<NbStack; Nbval++)
case cImag:for(Nbval=0; Nbval<NbStack; Nbval++) Stacki[Nbval*Size+SP] = fp_real(Stacki[Nbval*Size+SP]);
Stacki[Nbval*Size+SP] = fp_imag(Stacki[Nbval*Size+SP]); break; break;
case cArg: for(Nbval=0; Nbval<NbStack; Nbval++) case cImag:
Stacki[Nbval*Size+SP] = fp_arg(Stacki[Nbval*Size+SP]); break; for(Nbval=0; Nbval<NbStack; Nbval++)
case cConj:for(Nbval=0; Nbval<NbStack; Nbval++) Stacki[Nbval*Size+SP] = fp_imag(Stacki[Nbval*Size+SP]);
Stacki[Nbval*Size+SP] = fp_conj(Stacki[Nbval*Size+SP]); break; break;
case cPolar:for(Nbval=0; Nbval<NbStack; Nbval++) case cArg:
for(Nbval=0; Nbval<NbStack; Nbval++)
Stacki[Nbval*Size+SP] = fp_arg(Stacki[Nbval*Size+SP]);
break;
case cConj:
for(Nbval=0; Nbval<NbStack; Nbval++)
Stacki[Nbval*Size+SP] = fp_conj(Stacki[Nbval*Size+SP]);
break;
case cPolar:
for(Nbval=0; Nbval<NbStack; Nbval++)
Stacki[Nbval*Size+SP-1] = fp_polar(Stacki[Nbval*Size+SP-1], Stac ki[Nbval*Size+SP]); Stacki[Nbval*Size+SP-1] = fp_polar(Stacki[Nbval*Size+SP-1], Stac ki[Nbval*Size+SP]);
--SP; break; --SP;
break;
#endif #endif
case cPCall: case cPCall:
{ {
unsigned index = byteCode[++IP]; unsigned index = byteCode[++IP];
unsigned params = mData->mFuncParsers[index].mParams; unsigned params = mData->mFuncParsers[index].mParams;
double res[NbStack]; Value_t res[NbStack];
double rest=mData->mFuncParsers[index].mParserPtr->Eval2 Value_t rest=mData->mFuncParsers[index].mParserPtr->Eval2
(&(Stacki[SP-params+1]), Size, res, NbStack); (&(Stacki[SP-params+1]), Size, res, NbStack);
if (int(rest) == IF_FUNCT_ERROR) if (rest == Value_t(5))
{ {
mData->mEvalErrorType = IF_FUNCT_ERROR; mData->mEvalErrorType = IF_FUNCT_ERROR;
return IF_FUNCT_ERROR; return Value_t(mData->mEvalErrorType);
} }
if (int(rest) == VAR_OVERFLOW) if (rest == Value_t(7))
{ {
mData->mEvalErrorType = VAR_OVERFLOW; mData->mEvalErrorType = VAR_OVERFLOW;
return VAR_OVERFLOW; return Value_t(7);
} }
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
{ {
Stacki[Nbval*Size+SP - (int(params)-1)] = res[Nbval]; Stacki[Nbval*Size+SP - (int(params)-1)] = res[Nbval];
} }
SP -= int(params)-1; SP -= int(params)-1;
break; break;
} }
// Variables: // Variables:
default: default:
++SP; ++SP;
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
Stacki[Nbval*Size+SP] = Vars[byteCode[IP]+ NbVar*Nbval-VarBegin]; Stacki[Nbval*Size+SP] = Vars[byteCode[IP]+ NbVar*Nbval-VarBegin];
} }
} }
mData->mEvalErrorType=EVAL_NO_ERROR; mData->mEvalErrorType=EVAL_NO_ERROR;
for(Nbval=0; Nbval<NbStack; Nbval++) for(Nbval=0; Nbval<NbStack; Nbval++)
results[Nbval] = Stacki[Nbval*Size+SP]; results[Nbval] = Stacki[Nbval*Size+SP];
return Value_t(EVAL_NO_ERROR); return Value_t(Value_t(6));
} }
//=========================================================================== //===========================================================================
// Variable deduction // Variable deduction
//=========================================================================== //===========================================================================
namespace namespace
{ {
template<typename Value_t> template<typename Value_t>
int deduceVariables(FunctionParserBase<Value_t>& fParser, int deduceVariables(FunctionParserBase<Value_t>& fParser,
const char* funcStr, const char* funcStr,
 End of changes. 34 change blocks. 
44 lines changed or deleted 455 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)