diff --git a/include/expr.cpp b/include/expr.cpp index f9889b083..5e30a65a8 100755 --- a/include/expr.cpp +++ b/include/expr.cpp @@ -525,7 +525,7 @@ void TExpression::eval() evaluate_user_func(index, nparms, evalstack, type); } break; - case _sqrt: + case _sqrt: evalstack.push(real(sqrt(evalstack.pop_real()))); break; case _sqr: @@ -566,21 +566,21 @@ void TExpression::eval() break; case _mid: { - int count = (int)((const real&)evalstack.pop()).integer(); + int count = (int)evalstack.pop_real().integer(); if (count == 0) count--; - int from = (int)((const real&)evalstack.pop()).integer() - 1; + int from = (int)evalstack.pop_real().integer() - 1; if (from < 0) from = 0; - const TString& s = ((const TString&)evalstack.pop()).mid(from, count); - evalstack.push(s); + TString& s = evalstack.peek_string(); + s = s.mid(from, count); } break; case _substr: { - const int to = (int)((const real&)evalstack.pop()).integer(); - int from = (int)((const real&)evalstack.pop()).integer() - 1; + const int to = (int)evalstack.pop_real().integer(); + int from = (int)evalstack.pop_real().integer() - 1; if (from < 0) from = 0; - const TString& s = ((const TString&)evalstack.pop()).sub(from, to); - evalstack.push(s); + TString& s = evalstack.peek_string(); + s = s.sub(from, to); } break; case _pow: @@ -589,8 +589,8 @@ void TExpression::eval() evalstack.push(real(pow(o1, o2))); break; case _min: - o2 = (real&)evalstack.pop(); - o1 = (real&)evalstack.pop(); + o2 = evalstack.pop_real(); + o1 = evalstack.pop_real(); evalstack.push(o1 < o2 ? o1 : o2); break; case _max: @@ -599,16 +599,11 @@ void TExpression::eval() evalstack.push(o1 > o2 ? o1 : o2); break; case _upper: -/* - s1 = evalstack.pop_string(); - s1.upper(); - evalstack.push(s1); -*/ evalstack.peek_string().upper(); break; case _round: { - const int ndec = (int)(evalstack.pop_real()).integer(); + const int ndec = (int)evalstack.pop_real().integer(); o1 = evalstack.pop_real(); o1.round(ndec); evalstack.push(o1); @@ -616,7 +611,7 @@ void TExpression::eval() break; case _trunc: { - const int ndec = (int)(evalstack.pop_real()).integer(); + const int ndec = (int)evalstack.pop_real().integer(); o1 = evalstack.pop_real(); o1.trunc(ndec); evalstack.push(o1); @@ -624,7 +619,7 @@ void TExpression::eval() break; case _ceil: { - const int ndec = (int)(evalstack.pop_real()).integer(); + const int ndec = (int)evalstack.pop_real().integer(); o1 = evalstack.pop_real(); o1.ceil(ndec); evalstack.push(o1); @@ -640,8 +635,8 @@ void TExpression::eval() break; case _scorp: { - const real percent = (real&)evalstack.pop(); - real val = (real&)evalstack.pop(); + const real percent = evalstack.pop_real(); + real val = evalstack.pop_real(); val -= val * percent / (percent + 100.0); evalstack.push(val); } @@ -657,16 +652,16 @@ void TExpression::eval() } else { - o1 = (real&)evalstack.pop(); - o2 = (real&)evalstack.pop(); - const real cond = (real&)evalstack.pop(); + 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((const TString&)evalstack.pop()); + const TDate d(evalstack.pop_string()); const TString16 s(d.string(ANSI)); evalstack.push(s); } @@ -679,7 +674,7 @@ void TExpression::eval() type_pointer--; type = types[type_pointer] ? _numexpr : _strexpr; if (type == _numexpr) - evalstack.push(real((TString &) evalstack.pop())); + evalstack.push(real(evalstack.pop_string())); break; case _str: type_pointer++; @@ -690,7 +685,7 @@ void TExpression::eval() type_pointer--; type = types[type_pointer] ? _numexpr : _strexpr; if (type == _strexpr) - evalstack.push(TString(((real &) evalstack.pop()).string())); + evalstack.push(TString(evalstack.pop_real().string())); break; default: NFCHECK("operazione non valida %d", (int) instr.getsym()); @@ -724,22 +719,24 @@ TCodesym TExpression::tok2fun(const char* tok) const "SQRT", "STR", "SUBSTR","TAN", "TRUNC", "UPPER"}; - HIDDEN TCodesym fntok[MAX_TOK] = { _ansi, _ceil, _cos, _exp, _exp10, - _if, _left, _log, _log10, _max, - _mid, _min, _num, _perc, _pow, - _right, _round, _scorp, _sin, _sqr, - _sqrt, _str, _substr, _tan, _trunc, + HIDDEN TCodesym fntok[MAX_TOK] = { _ansi, _ceil, _cos, _exp, _exp10, + _if, _left, _log, _log10, _max, + _mid, _min, _num, _perc, _pow, + _right, _round, _scorp, _sin, _sqr, + _sqrt, _str, _substr, _tan, _trunc, _upper}; - int f = 0, l = MAX_TOK-1, i; + int f = 0, l = MAX_TOK-1, i = MAX_TOK/2; while (TRUE) { -// i = (f+l)>>1; - i = (toupper(*tok) - *fnstr[f]) * (l-f+1) / (*fnstr[l] - *fnstr[f] + 1); +// i = (f+l)>>1; + i = f + (toupper(*tok) - *fnstr[f]) * (l - f + 1) / (*fnstr[l] - *fnstr[f] + 1); + if (i < f || i > l) return _invalid; - + const int cmp = stricmp(tok, fnstr[i]); + if (cmp == 0) break; if (cmp > 0) f = i+1; @@ -763,20 +760,15 @@ TCodesym TExpression::__gettoken(bool /* reduct */) while (isspace(*_s)) _s++; if (!*_s) return _endsym; -/* - if ((reduct) && (*_s == ',')) - { - _s++; - return _comma; - } -*/ + bool square_bracket = FALSE; - if (isdigit(*_s) || (*_s == '.') /* || (*_s == ',') */) + if (isdigit(*_s) || (*_s == '.')) { sym = _number; - while (isalnum(*_s) || (*_s == '-') || (*_s == '[') || - (*_s == ']') || (*_s == '.') || (*_s == ':') || - (*_s == '_') || (sym == _variable && (*_s == ','))) + while (isalnum(*_s) || (*_s == '_') || (*_s == '.') || (*_s == ':') || + (sym == _number && (*_s == '-' || *_s == '[')) || + (square_bracket && (*_s == ',' || *_s == ']')) + ) { if (*_s == '-') { @@ -789,10 +781,16 @@ TCodesym TExpression::__gettoken(bool /* reduct */) { if (sym == _number) { - if (isalpha(*_s) || (*_s == '[') || (*_s == ']') || - (*_s == ',') || (*_s == ':') || (*_s == '_')) + if (isalpha(*_s) || (*_s == '_') || (*_s == ':') + /* || (*_s == '[') || (*_s == ']') || (*_s == ',') */ + ) sym = _variable; - } + } + else + { + if (sym == _variable && *_s == '[') + square_bracket = TRUE; + } _tok[i++] = *(_s++); } } @@ -800,27 +798,47 @@ TCodesym TExpression::__gettoken(bool /* reduct */) return sym; } if (isalpha(*_s) || (*_s == '#') || (*_s == '_')) - { + { + if (*_s == '#') + sym = _variable; + _tok[i++] = *(_s++); + while (isalnum(*_s) || (*_s == '-') || (*_s == '[') || - (*_s == ']') || (*_s == ':') || (*_s == ',') || (*_s == '_')) + (*_s == ':') || (*_s == '_') || + (square_bracket && (*_s == ',' || *_s == ']')) + ) { if (*_s == '-') { - if (_s[1] != '>') break; + if (_s[1] != '>') + break; // Non e' una -> (freccia) _tok[i++] = *(_s++); - } + sym = _variable; + } + else + { + if (*_s == '[') + { + sym = _variable; + square_bracket = TRUE; + } + } _tok[i++] = *(_s++); } _tok[i] = '\0'; - sym = tok2fun(_tok); // Guy was here! - if (sym != _invalid) - return sym; - - for (const char * p = _s; isspace(*p); p++); - if (*p == '(') - return _userfunc; + if (sym != _variable) // So gia' tutto, inutile controllare oltre + { + sym = tok2fun(_tok); + if (sym != _invalid) + return sym; + + for (const char * p = _s; isspace(*p); p++); + if (*p == '(') + return _userfunc; + } + return _variable; } switch (*_s) @@ -952,7 +970,7 @@ TCodesym TExpression::__factor(TCodesym startsym) if (quadra) { _code.add(_number, real(from)); - _code.add(_number, real(to > from ? to-from+1 : 0)); + _code.add(_number, real(to >= from ? to-from+1 : 0)); _code.add(_mid); } for (int i = numvar()-1 ; i >= 0; i--)