Finite correzzioni su expr
git-svn-id: svn://10.65.10.50/trunk@3675 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
c7d7a67725
commit
ec4bf8d8e8
561
include/expr.cpp
561
include/expr.cpp
@ -194,10 +194,7 @@ TExpression::TExpression(const char* expression, TTypeexp type)
|
|||||||
_dirty = TRUE;
|
_dirty = TRUE;
|
||||||
_type = type;
|
_type = type;
|
||||||
if (!compile(_original, type))
|
if (!compile(_original, type))
|
||||||
{
|
print_error(format("Wrong expression : %s", expression));
|
||||||
error_box("Wrong expression : %s", expression);
|
|
||||||
_code.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -213,7 +210,8 @@ TExpression::TExpression(TTypeexp type)
|
|||||||
TExpression::TExpression(const TExpression & expr)
|
TExpression::TExpression(const TExpression & expr)
|
||||||
: _code(expr._code), _var(expr._var),
|
: _code(expr._code), _var(expr._var),
|
||||||
_val(expr._val), _dirty(expr._dirty),
|
_val(expr._val), _dirty(expr._dirty),
|
||||||
_type(expr._type), _original(expr._original)
|
_type(expr._type), _original(expr._original),
|
||||||
|
_user_func_defined(expr._user_func_defined)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,8 +309,6 @@ void TExpression::eval()
|
|||||||
TBit_array types;
|
TBit_array types;
|
||||||
int type_pointer = 0;
|
int type_pointer = 0;
|
||||||
TCode instr;
|
TCode instr;
|
||||||
real o1, o2;
|
|
||||||
TString s1, s2;
|
|
||||||
|
|
||||||
types.set(type_pointer, (_type == _numexpr));
|
types.set(type_pointer, (_type == _numexpr));
|
||||||
|
|
||||||
@ -330,341 +326,335 @@ void TExpression::eval()
|
|||||||
case _variable:
|
case _variable:
|
||||||
if (type == _strexpr)
|
if (type == _strexpr)
|
||||||
{
|
{
|
||||||
s1 = _var.getstring(instr.string());
|
const TString & s1 = _var.getstring(instr.string());
|
||||||
evalstack.push(s1);
|
evalstack.push(s1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o1 = _var.getnum(instr.string());
|
const real & r1 = _var.getnum(instr.string());
|
||||||
evalstack.push(o1);
|
evalstack.push(r1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case _number:
|
case _number:
|
||||||
o1 = instr.number();
|
{
|
||||||
evalstack.push(o1);
|
const real & r1 = instr.number();
|
||||||
|
evalstack.push(r1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case _string:
|
case _string:
|
||||||
s1 = instr.string();
|
{
|
||||||
evalstack.push(s1);
|
const TString & s1 = instr.string();
|
||||||
|
evalstack.push(s1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case _plus:
|
case _plus:
|
||||||
if (type == _strexpr)
|
if (type == _strexpr)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
s2 = evalstack.pop_string();
|
|
||||||
s1 = evalstack.pop_string();
|
|
||||||
s1 << s2;
|
|
||||||
evalstack.push(s1);
|
|
||||||
*/
|
|
||||||
// Non unire le seguenti righe
|
// Non unire le seguenti righe
|
||||||
const TString& s = evalstack.pop_string();
|
const TString& s = evalstack.pop_string();
|
||||||
evalstack.peek_string() << s;
|
evalstack.peek_string() << s;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
o2 = evalstack.pop_real();
|
|
||||||
o1 = evalstack.pop_real();
|
|
||||||
evalstack.push(real(o1 + o2));
|
|
||||||
*/
|
|
||||||
// Non unire le seguenti righe
|
// Non unire le seguenti righe
|
||||||
const real& r = evalstack.pop_real();
|
const real& r = evalstack.pop_real();
|
||||||
evalstack.peek_real() += r;
|
evalstack.peek_real() += r;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case _minus:
|
case _minus:
|
||||||
o2 = evalstack.pop_real();
|
{
|
||||||
o1 = evalstack.pop_real();
|
const real& r = evalstack.pop_real();
|
||||||
evalstack.push(real(o1 - o2));
|
evalstack.peek_real() -= r;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case _multiply:
|
case _multiply:
|
||||||
o2 = evalstack.pop_real();
|
{
|
||||||
o1 = evalstack.pop_real();
|
const real& r = evalstack.pop_real();
|
||||||
evalstack.push(real(o1 * o2));
|
evalstack.peek_real() *= r;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case _divide:
|
case _divide:
|
||||||
o2 = evalstack.pop_real();
|
|
||||||
if (o2.is_zero())
|
|
||||||
{
|
{
|
||||||
print_error("Divisione per zero!");
|
real& r = evalstack.pop_real();
|
||||||
o2 = 1.0;
|
if (r.is_zero())
|
||||||
|
{
|
||||||
|
print_error("Divisione per zero!");
|
||||||
|
r = 1.0;
|
||||||
|
}
|
||||||
|
evalstack.peek_real() /= r;
|
||||||
}
|
}
|
||||||
o1 = evalstack.pop_real();
|
|
||||||
evalstack.push(real(o1 / o2));
|
|
||||||
break;
|
break;
|
||||||
case _chgs:
|
case _chgs:
|
||||||
o1 = evalstack.pop_real();
|
{
|
||||||
evalstack.push(-o1);
|
real & r = evalstack.peek_real();
|
||||||
|
r = -r;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case _and:
|
case _and:
|
||||||
if (type == _strexpr)
|
|
||||||
{
|
{
|
||||||
o2 = real((const char*)evalstack.pop_string());
|
const real & r2 = evalstack.pop_real();
|
||||||
o1 = real((const char*)evalstack.pop_string());
|
real & r1 = evalstack.peek_real();
|
||||||
evalstack.push(TString((o1 != ZERO && o2 != ZERO) ? "1" : "0"));
|
r1 = (!r1.is_zero() && !r2.is_zero()) ? 1.0 : 0.0;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
o2 = evalstack.pop_real();
|
|
||||||
o1 = evalstack.pop_real();
|
|
||||||
evalstack.push(real((o1 != ZERO && o2 != ZERO) ? 1.0 : 0.0));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case _or:
|
case _or:
|
||||||
if (type == _strexpr)
|
|
||||||
{
|
{
|
||||||
o2 = real((const char*) evalstack.pop_string());
|
const real & r2 = evalstack.pop_real();
|
||||||
o1 = real((const char*) evalstack.pop_string());
|
real & r1 = evalstack.peek_real();
|
||||||
evalstack.push(TString((o1 != ZERO || o2 != ZERO) ? "1" : "0"));
|
r1 = (r1 != ZERO || r2 != ZERO) ? 1.0 : 0.0;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
o2 = evalstack.pop_real();
|
|
||||||
o1 = evalstack.pop_real();
|
|
||||||
evalstack.push(real((o1 != ZERO || o2 != ZERO) ? 1.0 : 0.0));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case _not:
|
case _not:
|
||||||
o1 = evalstack.pop_real();
|
{
|
||||||
evalstack.push(real((o1 == ZERO) ? 1.0 : 0.0));
|
real & r1 = evalstack.peek_real();
|
||||||
|
r1 = (r1 == ZERO) ? 1.0 : 0.0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case _equal:
|
case _equal:
|
||||||
if (type == _strexpr)
|
if (type == _strexpr)
|
||||||
{
|
{
|
||||||
s2 = evalstack.pop_string();
|
const TString & s2 = evalstack.pop_string();
|
||||||
s1 = evalstack.pop_string();
|
const TString & s1 = evalstack.pop_string();
|
||||||
evalstack.push(TString((s1 == s2) ? "1" : "0"));
|
evalstack.push(real(s1 == s2 ? 1.0 : 0.0));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o2 = evalstack.pop_real();
|
const real & r2 = evalstack.pop_real();
|
||||||
o1 = evalstack.pop_real();
|
real & r1 = evalstack.peek_real();
|
||||||
evalstack.push(real((o1 == o2) ? 1.0 : 0.0));
|
r1 = (r1 == r2) ? 1.0 : 0.0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case _match:
|
case _match:
|
||||||
s2 = evalstack.pop_string();
|
{
|
||||||
s1 = evalstack.pop_string();
|
const TString & s2 = evalstack.pop_string();
|
||||||
evalstack.push(TString((s1.match(s2)) ? "1" : "0"));
|
const TString & s1 = evalstack.pop_string();
|
||||||
|
evalstack.push(real((s1.match(s2)) ? 1.0 : 0.0));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case _noteq:
|
case _noteq:
|
||||||
if (type == _strexpr)
|
if (type == _strexpr)
|
||||||
{
|
{
|
||||||
s2 = evalstack.pop_string();
|
const TString & s2 = evalstack.pop_string();
|
||||||
s1 = evalstack.pop_string();
|
TString & s1 = evalstack.pop_string();
|
||||||
evalstack.push(TString(s1 != s2 ? "1" : "0"));
|
evalstack.push(real(s1 != s2 ? 1.0 : 0.0));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o2 = evalstack.pop_real();
|
const real & r2 = evalstack.pop_real();
|
||||||
o1 = evalstack.pop_real();
|
real & r1 = evalstack.peek_real();
|
||||||
evalstack.push(real((o1 != o2) ? 1.0 : 0.0));
|
r1 = (r1 != r2) ? 1.0 : 0.0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case _lt:
|
case _lt:
|
||||||
if (type == _strexpr)
|
if (type == _strexpr)
|
||||||
{
|
{
|
||||||
s2 = evalstack.pop_string();
|
const TString & s2 = evalstack.pop_string();
|
||||||
s1 = evalstack.pop_string();
|
const TString & s1 = evalstack.peek_string();
|
||||||
evalstack.push(TString((s1 < (const char*)s2) ? "1" : "0"));
|
evalstack.push(real(s1 < s2 ? 1.0 : 0.0));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o2 = evalstack.pop_real();
|
const real & r2 = evalstack.pop_real();
|
||||||
o1 = evalstack.pop_real();
|
real & r1 = evalstack.peek_real();
|
||||||
evalstack.push(real((o1 < o2) ? 1.0 : 0.0));
|
r1 = (r1 < r2) ? 1.0 : 0.0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case _gt:
|
case _gt:
|
||||||
if (type == _strexpr)
|
if (type == _strexpr)
|
||||||
{
|
{
|
||||||
s2 = evalstack.pop_string();
|
const TString & s2 = evalstack.pop_string();
|
||||||
s1 = evalstack.pop_string();
|
const TString & s1 = evalstack.peek_string();
|
||||||
evalstack.push(TString((s1 > (const char*)s2) ? "1" : "0"));
|
evalstack.push(real(s1 > s2 ? 1.0 : 0.0));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o2 = evalstack.pop_real();
|
const real & r2 = evalstack.pop_real();
|
||||||
o1 = evalstack.pop_real();
|
real & r1 = evalstack.peek_real();
|
||||||
evalstack.push(real((o1 > o2) ? 1.0 : 0.0));
|
r1 = (r1 > r2) ? 1.0 : 0.0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case _lteq:
|
case _lteq:
|
||||||
if (type == _strexpr)
|
if (type == _strexpr)
|
||||||
{
|
{
|
||||||
s2 = evalstack.pop_string();
|
const TString & s2 = evalstack.pop_string();
|
||||||
s1 = evalstack.pop_string();
|
const TString & s1 = evalstack.peek_string();
|
||||||
evalstack.push(TString((s1 <= (const char*)s2) ? "1" : "0"));
|
evalstack.push(real(s1 <= s2 ? 1.0 : 0.0));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o2 = evalstack.pop_real();
|
const real & r2 = evalstack.pop_real();
|
||||||
o1 = evalstack.pop_real();
|
real & r1 = evalstack.peek_real();
|
||||||
evalstack.push(real((o1 <= o2) ? 1.0 : 0.0));
|
r1 = (r1 <= r2) ? 1.0 : 0.0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case _gteq:
|
case _gteq:
|
||||||
if (type == _strexpr)
|
if (type == _strexpr)
|
||||||
{
|
{
|
||||||
s2 = evalstack.pop_string();
|
const TString & s2 = evalstack.pop_string();
|
||||||
s1 = evalstack.pop_string();
|
TString & s1 = evalstack.peek_string();
|
||||||
evalstack.push(TString((s1 >= (const char*)s2) ? "1" : "0"));
|
evalstack.push(real(s1 >= s2 ? 1.0 : 0.0));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o2 = evalstack.pop_real();
|
const real & r2 = evalstack.pop_real();
|
||||||
o1 = evalstack.pop_real();
|
real & r1 = evalstack.peek_real();
|
||||||
evalstack.push(real((o1 >= o2) ? 1.0 : 0.0));
|
r1 = (r1 >= r2) ? 1.0 : 0.0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case _userfunc:
|
case _userfunc:
|
||||||
{
|
{
|
||||||
const int nparms = (int) ((real &) evalstack.pop()).integer();
|
const int nparms = (int) evalstack.pop_real().integer();
|
||||||
const int index = atoi(instr.string());
|
const int index = atoi(instr.string());
|
||||||
|
|
||||||
evaluate_user_func(index, nparms, evalstack, type);
|
evaluate_user_func(index, nparms, evalstack, type);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case _sqrt:
|
case _sqrt:
|
||||||
evalstack.push(real(sqrt(evalstack.pop_real())));
|
evalstack.peek_real() = sqrt(evalstack.peek_real());
|
||||||
break;
|
break;
|
||||||
case _sqr:
|
case _sqr:
|
||||||
evalstack.push(real(sqr(evalstack.pop_real())));
|
evalstack.peek_real() = sqr(evalstack.peek_real());
|
||||||
break;
|
break;
|
||||||
case _exp10:
|
case _exp10:
|
||||||
evalstack.push(real(exp10(evalstack.pop_real())));
|
evalstack.peek_real() = exp10(evalstack.peek_real());
|
||||||
break;
|
break;
|
||||||
case _exp:
|
case _exp:
|
||||||
evalstack.push(real(exp(evalstack.pop_real())));
|
evalstack.peek_real() = exp(evalstack.peek_real());
|
||||||
break;
|
break;
|
||||||
case _log10:
|
case _log10:
|
||||||
evalstack.push(real(log10(evalstack.pop_real())));
|
evalstack.peek_real() = log10(evalstack.peek_real());
|
||||||
break;
|
break;
|
||||||
case _log:
|
case _log:
|
||||||
evalstack.push(real(log(evalstack.pop_real())));
|
evalstack.peek_real() = log(evalstack.peek_real());
|
||||||
break;
|
break;
|
||||||
case _sin:
|
case _sin:
|
||||||
evalstack.push(real(sin(evalstack.pop_real())));
|
evalstack.peek_real() = sin(evalstack.peek_real());
|
||||||
break;
|
break;
|
||||||
case _cos:
|
case _cos:
|
||||||
evalstack.push(real(cos(evalstack.pop_real())));
|
evalstack.peek_real() = cos(evalstack.peek_real());
|
||||||
break;
|
break;
|
||||||
case _tan:
|
case _tan:
|
||||||
evalstack.push(real(tan(evalstack.pop_real())));
|
evalstack.peek_real() = tan(evalstack.peek_real());
|
||||||
break;
|
break;
|
||||||
case _left:
|
case _left:
|
||||||
o2 = evalstack.pop_real();
|
{
|
||||||
s2 = evalstack.pop_string();
|
const int len = (int)evalstack.pop_real().integer();
|
||||||
s1 = s2.left((int)o2.integer());
|
TString & s1 = evalstack.peek_string();
|
||||||
evalstack.push(s1);
|
s1 = s1.left(len);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case _right:
|
case _right:
|
||||||
o2 = evalstack.pop_real();
|
{
|
||||||
s2 = evalstack.pop_string();
|
const int len = (int)evalstack.pop_real().integer();
|
||||||
s1 = s2.right((int)o2.integer());
|
TString & s1 = evalstack.peek_string();
|
||||||
evalstack.push(s1);
|
s1 = s1.right(len);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case _mid:
|
case _mid:
|
||||||
{
|
{
|
||||||
int count = (int)evalstack.pop_real().integer();
|
int count = (int)evalstack.pop_real().integer();
|
||||||
if (count == 0) count--;
|
if (count == 0) count--;
|
||||||
int from = (int)evalstack.pop_real().integer() - 1;
|
int from = (int)evalstack.pop_real().integer() - 1;
|
||||||
if (from < 0) from = 0;
|
if (from < 0) from = 0;
|
||||||
TString& s = evalstack.peek_string();
|
TString & s1 = evalstack.peek_string();
|
||||||
s = s.mid(from, count);
|
s1 = s1.mid(from, count);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case _substr:
|
case _substr:
|
||||||
{
|
{
|
||||||
const int to = (int)evalstack.pop_real().integer();
|
const int to = (int)evalstack.pop_real().integer();
|
||||||
int from = (int)evalstack.pop_real().integer() - 1;
|
int from = (int)evalstack.pop_real().integer() - 1;
|
||||||
if (from < 0) from = 0;
|
if (from < 0) from = 0;
|
||||||
TString& s = evalstack.peek_string();
|
TString & s1 = evalstack.peek_string();
|
||||||
s = s.sub(from, to);
|
s1 = s1.sub(from, to);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case _pow:
|
case _pow:
|
||||||
o2 = evalstack.pop_real();
|
{
|
||||||
o1 = evalstack.pop_real();
|
const real & r2 = evalstack.pop_real();
|
||||||
evalstack.push(real(pow(o1, o2)));
|
real & r1 = evalstack.peek_real();
|
||||||
|
r1 = pow(r1, r2);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case _min:
|
case _min:
|
||||||
o2 = evalstack.pop_real();
|
{
|
||||||
o1 = evalstack.pop_real();
|
const real & r2 = evalstack.pop_real();
|
||||||
evalstack.push(o1 < o2 ? o1 : o2);
|
real & r1 = evalstack.peek_real();
|
||||||
|
if (r2 < r1)
|
||||||
|
r1 = r2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case _max:
|
case _max:
|
||||||
o2 = evalstack.pop_real();
|
{
|
||||||
o1 = evalstack.pop_real();
|
const real & r2 = evalstack.pop_real();
|
||||||
evalstack.push(o1 > o2 ? o1 : o2);
|
real & r1 = evalstack.peek_real();
|
||||||
|
if (r2 > r1)
|
||||||
|
r1 = r2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case _upper:
|
case _upper:
|
||||||
evalstack.peek_string().upper();
|
evalstack.peek_string().upper();
|
||||||
break;
|
break;
|
||||||
case _round:
|
case _round:
|
||||||
{
|
{
|
||||||
const int ndec = (int)evalstack.pop_real().integer();
|
const int ndec = (int)(evalstack.pop_real()).integer();
|
||||||
o1 = evalstack.pop_real();
|
real & r = evalstack.peek_real();
|
||||||
o1.round(ndec);
|
r.round(ndec);
|
||||||
evalstack.push(o1);
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case _trunc:
|
case _trunc:
|
||||||
{
|
{
|
||||||
const int ndec = (int)evalstack.pop_real().integer();
|
const int ndec = (int)(evalstack.pop_real()).integer();
|
||||||
o1 = evalstack.pop_real();
|
real & r = evalstack.peek_real();
|
||||||
o1.trunc(ndec);
|
r.trunc(ndec);
|
||||||
evalstack.push(o1);
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case _ceil:
|
case _ceil:
|
||||||
{
|
{
|
||||||
const int ndec = (int)evalstack.pop_real().integer();
|
const int ndec = (int)(evalstack.pop_real()).integer();
|
||||||
o1 = evalstack.pop_real();
|
real & r = evalstack.peek_real();
|
||||||
o1.ceil(ndec);
|
r.ceil(ndec);
|
||||||
evalstack.push(o1);
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case _perc:
|
case _perc:
|
||||||
{
|
{
|
||||||
o2 = evalstack.pop_real();
|
const real & r2 = evalstack.pop_real();
|
||||||
o1 = evalstack.pop_real();
|
real & r1 = evalstack.peek_real();
|
||||||
const real val = real(o1 * o2 / 100.0);
|
r1 = real(r1 * r2 / 100.0);
|
||||||
evalstack.push(val);
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case _scorp:
|
case _scorp:
|
||||||
{
|
{
|
||||||
const real percent = evalstack.pop_real();
|
const real & r2 = evalstack.pop_real();
|
||||||
real val = evalstack.pop_real();
|
real & r1 = evalstack.peek_real();
|
||||||
val -= val * percent / (percent + 100.0);
|
r1 -= r1 * r2 / (r2 + 100.0);
|
||||||
evalstack.push(val);
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case _if:
|
case _if:
|
||||||
{
|
{
|
||||||
if (type == _strexpr)
|
if (type == _strexpr)
|
||||||
{
|
{
|
||||||
s1 = evalstack.pop_string();
|
const TString & s1 = evalstack.pop_string();
|
||||||
s2 = evalstack.pop_string();
|
const TString & s2 = evalstack.pop_string();
|
||||||
const real cond(evalstack.pop_string());
|
const real & cond = evalstack.pop_real();
|
||||||
evalstack.push(cond.is_zero() ? s1 : s2);
|
evalstack.push(cond.is_zero() ? s1 : s2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const real & r1 = evalstack.pop_real();
|
||||||
|
const real & r2 = evalstack.pop_real();
|
||||||
|
real & cond = evalstack.peek_real();
|
||||||
|
cond = cond.is_zero() ? r1 : r2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
o1 = evalstack.pop_real();
|
|
||||||
o2 = evalstack.pop_real();
|
|
||||||
const real cond = evalstack.pop_real();
|
|
||||||
evalstack.push(cond.is_zero() ? o1 : o2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case _ansi:
|
case _ansi:
|
||||||
{
|
{
|
||||||
const TDate d(evalstack.pop_string());
|
TString & s = evalstack.peek_string();
|
||||||
const TString16 s(d.string(ANSI));
|
const TDate d(s);
|
||||||
evalstack.push(s);
|
s = d.string(ANSI);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case _num:
|
case _num:
|
||||||
type_pointer++;
|
type_pointer++;
|
||||||
types.set(type_pointer, FALSE);
|
types.set(type_pointer, FALSE);
|
||||||
@ -674,7 +664,7 @@ void TExpression::eval()
|
|||||||
type_pointer--;
|
type_pointer--;
|
||||||
type = types[type_pointer] ? _numexpr : _strexpr;
|
type = types[type_pointer] ? _numexpr : _strexpr;
|
||||||
if (type == _numexpr)
|
if (type == _numexpr)
|
||||||
evalstack.push(real(evalstack.pop_string()));
|
evalstack.peek_real();
|
||||||
break;
|
break;
|
||||||
case _str:
|
case _str:
|
||||||
type_pointer++;
|
type_pointer++;
|
||||||
@ -685,7 +675,7 @@ void TExpression::eval()
|
|||||||
type_pointer--;
|
type_pointer--;
|
||||||
type = types[type_pointer] ? _numexpr : _strexpr;
|
type = types[type_pointer] ? _numexpr : _strexpr;
|
||||||
if (type == _strexpr)
|
if (type == _strexpr)
|
||||||
evalstack.push(TString(evalstack.pop_real().string()));
|
evalstack.peek_string();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
NFCHECK("operazione non valida %d", (int) instr.getsym());
|
NFCHECK("operazione non valida %d", (int) instr.getsym());
|
||||||
@ -765,7 +755,8 @@ TCodesym TExpression::__gettoken(bool /* reduct */)
|
|||||||
if (isdigit(*_s) || (*_s == '.'))
|
if (isdigit(*_s) || (*_s == '.'))
|
||||||
{
|
{
|
||||||
sym = _number;
|
sym = _number;
|
||||||
while (isalnum(*_s) || (*_s == '_') || (*_s == '.') || (*_s == ':') ||
|
while (isalnum(*_s) || (*_s == '_') || (*_s == '.') ||
|
||||||
|
(*_s == ':') || (*_s == '@') ||
|
||||||
(sym == _number && (*_s == '-' || *_s == '[')) ||
|
(sym == _number && (*_s == '-' || *_s == '[')) ||
|
||||||
(square_bracket && (*_s == ',' || *_s == ']'))
|
(square_bracket && (*_s == ',' || *_s == ']'))
|
||||||
)
|
)
|
||||||
@ -781,7 +772,7 @@ TCodesym TExpression::__gettoken(bool /* reduct */)
|
|||||||
{
|
{
|
||||||
if (sym == _number)
|
if (sym == _number)
|
||||||
{
|
{
|
||||||
if (isalpha(*_s) || (*_s == '_') || (*_s == ':')
|
if (isalpha(*_s) || (*_s == '_') || (*_s == ':')
|
||||||
/* || (*_s == '[') || (*_s == ']') || (*_s == ',') */
|
/* || (*_s == '[') || (*_s == ']') || (*_s == ',') */
|
||||||
)
|
)
|
||||||
sym = _variable;
|
sym = _variable;
|
||||||
@ -801,8 +792,8 @@ TCodesym TExpression::__gettoken(bool /* reduct */)
|
|||||||
{
|
{
|
||||||
if (*_s == '#')
|
if (*_s == '#')
|
||||||
sym = _variable;
|
sym = _variable;
|
||||||
|
|
||||||
_tok[i++] = *(_s++);
|
_tok[i++] = *(_s++);
|
||||||
|
|
||||||
while (isalnum(*_s) || (*_s == '-') || (*_s == '[') ||
|
while (isalnum(*_s) || (*_s == '-') || (*_s == '[') ||
|
||||||
(*_s == ':') || (*_s == '_') ||
|
(*_s == ':') || (*_s == '_') ||
|
||||||
@ -940,6 +931,7 @@ TCodesym TExpression::__gettoken(bool /* reduct */)
|
|||||||
return _invalid;
|
return _invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HIDDEN int __parms_found = -1;
|
||||||
|
|
||||||
TCodesym TExpression::__factor(TCodesym startsym)
|
TCodesym TExpression::__factor(TCodesym startsym)
|
||||||
{
|
{
|
||||||
@ -987,38 +979,23 @@ TCodesym TExpression::__factor(TCodesym startsym)
|
|||||||
case _userfunc:
|
case _userfunc:
|
||||||
{
|
{
|
||||||
TValue val (_tok);
|
TValue val (_tok);
|
||||||
sym = __gettoken();
|
sym = __function();
|
||||||
if (sym == _lpar)
|
if (sym != _invalid)
|
||||||
{
|
{
|
||||||
sym = __gettoken();
|
const int index = parse_user_func((const char *) val.string(), __parms_found);
|
||||||
int nparms = sym == _rpar ? 0 : 1;
|
|
||||||
if (sym != _rpar)
|
if (index < 0)
|
||||||
{
|
{
|
||||||
while ((sym = __expression(sym)) == _comma)
|
strcpy(_tok, (const char *) val.string());
|
||||||
{
|
sym = _invalid;
|
||||||
sym = __gettoken(TRUE);
|
|
||||||
nparms++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sym == _rpar)
|
|
||||||
{
|
|
||||||
_code.add(_number, real(nparms));
|
|
||||||
const int index = parse_user_func((const char *) val.string(), nparms);
|
|
||||||
if (index < 0)
|
|
||||||
{
|
|
||||||
strcpy(_tok, (const char *) val.string());
|
|
||||||
sym = _invalid;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
val.set(format("%d", index));
|
|
||||||
_code.add(startsym, val);
|
|
||||||
_user_func_defined = TRUE;
|
|
||||||
sym = __gettoken(TRUE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sym = _invalid;
|
{
|
||||||
|
_code.add(_number, real(__parms_found));
|
||||||
|
val.set(format("%d", index));
|
||||||
|
_code.add(startsym, val);
|
||||||
|
_user_func_defined = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1032,21 +1009,8 @@ TCodesym TExpression::__factor(TCodesym startsym)
|
|||||||
case _cos:
|
case _cos:
|
||||||
case _tan:
|
case _tan:
|
||||||
case _ansi:
|
case _ansi:
|
||||||
sym = __gettoken();
|
|
||||||
if (sym == _lpar) sym = __gettoken();
|
|
||||||
else break;
|
|
||||||
sym = __expression(sym);
|
|
||||||
if (sym == _rpar) sym = __gettoken();
|
|
||||||
else break;
|
|
||||||
_code.add(startsym);
|
|
||||||
break;
|
|
||||||
case _upper:
|
case _upper:
|
||||||
sym = __gettoken();
|
sym = __function(1);
|
||||||
if (sym == _lpar) sym = __gettoken();
|
|
||||||
else break;
|
|
||||||
sym = __expression(sym);
|
|
||||||
if (sym == _rpar) sym = __gettoken();
|
|
||||||
else break;
|
|
||||||
_code.add(startsym);
|
_code.add(startsym);
|
||||||
break;
|
break;
|
||||||
case _left:
|
case _left:
|
||||||
@ -1059,57 +1023,22 @@ TCodesym TExpression::__factor(TCodesym startsym)
|
|||||||
case _trunc:
|
case _trunc:
|
||||||
case _perc:
|
case _perc:
|
||||||
case _scorp:
|
case _scorp:
|
||||||
sym = __gettoken();
|
sym = __function(2);
|
||||||
if (sym == _lpar) sym = __gettoken(TRUE);
|
|
||||||
else break;
|
|
||||||
sym = __expression(sym);
|
|
||||||
if (sym == _comma) sym = __gettoken(TRUE);
|
|
||||||
else break;
|
|
||||||
sym = __expression(sym);
|
|
||||||
if (sym == _rpar) sym = __gettoken(TRUE);
|
|
||||||
else break;
|
|
||||||
_code.add(startsym);
|
_code.add(startsym);
|
||||||
break;
|
break;
|
||||||
case _mid:
|
case _mid:
|
||||||
case _substr:
|
case _substr:
|
||||||
sym = __gettoken();
|
sym = __function(3);
|
||||||
if (sym == _lpar) sym = __gettoken(TRUE);
|
|
||||||
else break;
|
|
||||||
sym = __expression(sym);
|
|
||||||
if (sym == _comma) sym = __gettoken(TRUE);
|
|
||||||
else break;
|
|
||||||
sym = __expression(sym);
|
|
||||||
if (sym == _comma) sym = __gettoken(TRUE);
|
|
||||||
else break;
|
|
||||||
sym = __expression(sym);
|
|
||||||
if (sym == _rpar) sym = __gettoken(TRUE);
|
|
||||||
else break;
|
|
||||||
_code.add(startsym);
|
_code.add(startsym);
|
||||||
break;
|
break;
|
||||||
case _if:
|
case _if:
|
||||||
sym = __gettoken();
|
sym = __function(3);
|
||||||
if (sym == _lpar) sym = __gettoken(TRUE);
|
|
||||||
else break;
|
|
||||||
sym = __expression(sym);
|
|
||||||
if (sym == _comma) sym = __gettoken(TRUE);
|
|
||||||
else break;
|
|
||||||
sym = __expression(sym);
|
|
||||||
if (sym == _comma) sym = __gettoken(TRUE);
|
|
||||||
else break;
|
|
||||||
sym = __expression(sym);
|
|
||||||
if (sym == _rpar) sym = __gettoken(TRUE);
|
|
||||||
else break;
|
|
||||||
_code.add(startsym);
|
_code.add(startsym);
|
||||||
break;
|
break;
|
||||||
case _num:
|
case _num:
|
||||||
case _str:
|
case _str:
|
||||||
_code.add(startsym);
|
_code.add(startsym);
|
||||||
sym = __gettoken();
|
sym = __function(1);
|
||||||
if (sym == _lpar) sym = __gettoken();
|
|
||||||
else break;
|
|
||||||
sym = __expression(sym);
|
|
||||||
if (sym == _rpar) sym = __gettoken();
|
|
||||||
else break;
|
|
||||||
_code.add(startsym == _num ? _endnum : _endstr);
|
_code.add(startsym == _num ? _endnum : _endstr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1157,6 +1086,28 @@ TCodesym TExpression::__expression(TCodesym startsym)
|
|||||||
return(sym);
|
return(sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TCodesym TExpression::__function(int nparms, bool fixed_num)
|
||||||
|
{
|
||||||
|
TCodesym sym = __gettoken(TRUE);
|
||||||
|
if (sym != _lpar)
|
||||||
|
return _invalid;
|
||||||
|
__parms_found = 0;
|
||||||
|
sym = __gettoken(TRUE);
|
||||||
|
if (sym == _rpar)
|
||||||
|
return nparms <= 0 || !fixed_num ? __gettoken(TRUE) : _invalid;
|
||||||
|
__parms_found++;
|
||||||
|
while ((sym = __expression(sym)) == _comma)
|
||||||
|
{
|
||||||
|
sym = __gettoken(TRUE);
|
||||||
|
__parms_found++;
|
||||||
|
}
|
||||||
|
if (sym == _rpar)
|
||||||
|
return nparms < 0 || __parms_found == nparms || (__parms_found < nparms && !fixed_num) ?
|
||||||
|
__gettoken(TRUE) :
|
||||||
|
_invalid;
|
||||||
|
return _invalid;
|
||||||
|
}
|
||||||
|
|
||||||
bool TExpression::set(const char* expression, TTypeexp type)
|
bool TExpression::set(const char* expression, TTypeexp type)
|
||||||
{
|
{
|
||||||
_original = expression;
|
_original = expression;
|
||||||
@ -1173,50 +1124,6 @@ bool TExpression::compile(const char* expression, TTypeexp type)
|
|||||||
_user_func_defined = FALSE;
|
_user_func_defined = FALSE;
|
||||||
_s = expression;
|
_s = expression;
|
||||||
_type = type;
|
_type = type;
|
||||||
|
|
||||||
/*
|
|
||||||
TString sc(256);
|
|
||||||
while (((currsym = __gettoken()) != _endsym) && (currsym != _invalid))
|
|
||||||
{
|
|
||||||
if (currsym == _variable)
|
|
||||||
{
|
|
||||||
char *s1 = _tok;
|
|
||||||
while ((*s1) && (*s1 != '[')) s1++;
|
|
||||||
if (!*s1) sc << " " << _tok;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*s1 = '\0';
|
|
||||||
s1++;
|
|
||||||
char *s2 = s1;
|
|
||||||
while ((*s1) && (*s1 != ',')) s1++;
|
|
||||||
if (!*s1) sc << " " << _tok;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*s1 = '\0';
|
|
||||||
s1++;
|
|
||||||
int n1 = atoi(s2);
|
|
||||||
s2 = s1;
|
|
||||||
while ((*s1) && (*s1 != ']')) s1++;
|
|
||||||
if (!*s1) sc << " " << _tok;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const int n2 = atoi(s2);
|
|
||||||
sc << format(" mid(%s,%d,%d)", _tok, n1, (n2 < n1) ? 0 : n2 - n1 + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (currsym == _string)
|
|
||||||
{
|
|
||||||
const char sep (strchr(_tok, '\"') != NULL ? '\'' : '\"');
|
|
||||||
|
|
||||||
sc << sep << _tok << sep;
|
|
||||||
}
|
|
||||||
else sc << " " << _tok;
|
|
||||||
}
|
|
||||||
_s = sc;
|
|
||||||
*/
|
|
||||||
_val = real(0.0);
|
_val = real(0.0);
|
||||||
_code.clear();
|
_code.clear();
|
||||||
if (*_s == '\0')
|
if (*_s == '\0')
|
||||||
|
@ -416,12 +416,14 @@ protected:
|
|||||||
// @cmember Ritorna il prossimo token dell'espressione (se <p reduct> e' TRUE interpreta
|
// @cmember Ritorna il prossimo token dell'espressione (se <p reduct> e' TRUE interpreta
|
||||||
// la virgola come un token)
|
// la virgola come un token)
|
||||||
TCodesym __gettoken(bool reduct = FALSE);
|
TCodesym __gettoken(bool reduct = FALSE);
|
||||||
// @cmember Ritorna il prossimo fattore
|
// @cmember Esegue la compilazione di un fattore
|
||||||
TCodesym __factor(TCodesym startsym);
|
TCodesym __factor(TCodesym startsym);
|
||||||
// @cmember Ritorna il prossimo termine
|
// @cmember Esegue la compilazione di un termine
|
||||||
TCodesym __term(TCodesym startsym);
|
TCodesym __term(TCodesym startsym);
|
||||||
// @cmember Ritorna la prossima espressione
|
// @cmember Esegue la compilazione di un'espressione
|
||||||
TCodesym __expression(TCodesym startsym);
|
TCodesym __expression(TCodesym startsym);
|
||||||
|
// @cmember Esegue la compilazione di un una funzione
|
||||||
|
TCodesym __function(int nparms = -1, bool fixed_num = TRUE);
|
||||||
// @cmember Compila l'espressione
|
// @cmember Compila l'espressione
|
||||||
bool compile(const char* expression, TTypeexp type);
|
bool compile(const char* expression, TTypeexp type);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user