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