Finite correzzioni su expr

git-svn-id: svn://10.65.10.50/trunk@3675 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
alex 1996-09-26 15:30:49 +00:00
parent c7d7a67725
commit ec4bf8d8e8
2 changed files with 239 additions and 330 deletions

View File

@ -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')

View File

@ -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);