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