From 43ac216bfdc6c2650309f6cf70027a4fd1cce96e Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 23 Aug 1996 14:49:47 +0000 Subject: [PATCH] Aggiunte funzioni num e str git-svn-id: svn://10.65.10.50/trunk@3431 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- include/expr.cpp | 218 ++++++++++++++++++++++++++++++----------------- include/expr.h | 61 +++++++------ 2 files changed, 176 insertions(+), 103 deletions(-) diff --git a/include/expr.cpp b/include/expr.cpp index 90f76c5ca..9a240f112 100755 --- a/include/expr.cpp +++ b/include/expr.cpp @@ -15,29 +15,24 @@ TValue::TValue(const real& val) _t = _numexpr; } -TCodearray::TCodearray(int size) : _rpn(size) -{ - clear(); -} - - void TCodearray::clear() { - _rpn.destroy(); - _last = 0; - TCode *c = new TCode(_endsym); - _rpn.add(c, _last); + destroy(); + TArray::add(new TCode(_endsym)); } void TCodearray::add(TCodesym sym, const TValue& val) { - TCode *c = new TCode(sym, val); - _rpn.add(c, _last++); - TCode *c1 = new TCode(_endsym); - _rpn.add(c1, _last); + TArray::insert(new TCode(sym, val), last()); } +TObject * TCode::dup() const +{ + TCode * o = new TCode(*this); + return o; +} + TCode& TCode::operator =(const TCode& b) { _sym = b._sym; @@ -45,26 +40,24 @@ TCode& TCode::operator =(const TCode& b) return *this; } -TVararray::TVararray(int size) : _array(size) +TObject * TVar::dup() const { - clear(); -} - + TVar * o = new TVar(*this); + return o; +} void TVararray::add(const char* name, const TValue& val) { - TVar* v = new TVar(name, val); - _array.add(v, _last++); + TArray::add(new TVar(name, val)); } void TVararray::set(const char* name, const real& val) { - for (int i = 0; i < _array.items(); i++) - if (strcmp(((TVar&) _array[i]).getname(), name) == 0) + for (int i = 0; i < items(); i++) + if (strcmp(((TVar *) objptr(i))->getname(), name) == 0) { - TValue tempval( val ); - ((TVar&) _array[i]) = tempval; + TArray::add(new TValue(val), i); return; } } @@ -73,11 +66,10 @@ void TVararray::set(const char* name, const real& val) void TVararray::set(const char* name, const char* val) { - for (int i = 0; i < _array.items(); i++) - if (strcmp(((TVar&) _array[i]).getname(), name) == 0) + for (int i = 0; i < items(); i++) + if (strcmp(((TVar *) objptr(i))->getname(), name) == 0) { - TValue tempval( val ); - ((TVar&) _array[i]) = tempval; + TArray::add(new TValue(val), i); return; } } @@ -90,11 +82,11 @@ const real& TVararray::getnum(const char* name) { int i; - for (i = 0; i < _array.items(); i++) + for (i = 0; i < items(); i++) { - if (strcmp(((TVar*) _array.objptr(i))->getname(), name) == 0) + if (strcmp(((TVar*) objptr(i))->getname(), name) == 0) { - __r = ((TVar*) _array.objptr(i))->number(); + __r = ((TVar*) objptr(i))->number(); return __r; } } @@ -106,9 +98,9 @@ const real& TVararray::getnum(const char* name) const real& TVararray::getnum(int varnum) { - if (varnum >= _array.items()) + if (varnum >= items()) fatal_box("invalid variable number : %d", varnum); - __r = ((TVar*) _array.objptr(varnum))->number(); + __r = ((TVar*) objptr(varnum))->number(); return __r; } @@ -119,10 +111,10 @@ const char* TVararray::getstring(const char* name) const char* s = NULL; int i; - for (i = 0; i < _array.items(); i++) + for (i = 0; i < items(); i++) { - if (strcmp(((TVar*) _array.objptr(i))->getname(), name) == 0) - return ((TVar*) _array.objptr(i))->string(); + if (strcmp(((TVar*) objptr(i))->getname(), name) == 0) + return ((TVar*) objptr(i))->string(); } fatal_box("Unknown variable : %s", name); return s; @@ -132,9 +124,9 @@ const char* TVararray::getstring(const char* name) const char* TVararray::getstring(int varnum) { - if (varnum >= _array.items()) + if (varnum >= items()) fatal_box("invalid variable number : %d", varnum); - return ((TVar*) _array.objptr(varnum))->string(); + return ((TVar*) objptr(varnum))->string(); } @@ -167,11 +159,24 @@ TExpression::TExpression(TTypeexp type) _code.clear(); } +TExpression::TExpression(const TExpression & expr) + : _code(expr._code), _var(expr._var), + _val(expr._val), _dirty(expr._dirty), + _type(expr._type), _original(expr._original) + +{ +} + +TObject* TExpression::dup() const +{ + TExpression* o = new TExpression(*this); + return o; +} TExpression::operator const real&() -{ - if (_dirty) eval(); +{ + if (user_func_dirty() || _dirty) eval(); _dirty = FALSE; return _val.number(); } @@ -180,7 +185,7 @@ TExpression::operator const real&() TExpression::operator const char*() { - if (_dirty) eval(); + if (user_func_dirty() || _dirty) eval(); _dirty = FALSE; return _val.string(); } @@ -201,7 +206,7 @@ void TExpression::evaluate_user_func(const char * name, int nparms, TStack & sta TExpression::operator bool() { - if (_dirty) eval(); + if (user_func_dirty() || _dirty) eval(); _dirty = FALSE; const real& r = _val.number(); return !r.is_zero(); @@ -244,10 +249,16 @@ void TExpression::eval() { TStack evalstack(50); + TBit_array types; + int type_pointer = 0; TCode instr; real o1, o2; TString s1, s2; - + + types.set(type_pointer, (_type == _numexpr)); + + TTypeexp type = _type; + _code.begin(); while (!_code.end()) { @@ -258,7 +269,7 @@ void TExpression::eval() case _endsym: break; case _variable: - if (_type == _strexpr) + if (type == _strexpr) { s1 = _var.getstring(instr.string()); evalstack.push(s1); @@ -278,7 +289,7 @@ void TExpression::eval() evalstack.push(s1); break; case _plus: - if (_type == _strexpr) + if (type == _strexpr) { s2 = (TString&) evalstack.pop(); s1 = (TString&) evalstack.pop(); @@ -312,7 +323,7 @@ void TExpression::eval() evalstack.push(-o1); break; case _and: - if (_type == _strexpr) + if (type == _strexpr) { o2 = real((const char*)(TString&)evalstack.pop()); o1 = real((const char*)(TString&)evalstack.pop()); @@ -326,7 +337,7 @@ void TExpression::eval() } break; case _or: - if (_type == _strexpr) + if (type == _strexpr) { o2 = real((const char*) (TString&)evalstack.pop()); o1 = real((const char*) (TString&)evalstack.pop()); @@ -344,7 +355,7 @@ void TExpression::eval() evalstack.push(real((o1 == ZERO) ? 1.0 : 0.0)); break; case _equal: - if (_type == _strexpr) + if (type == _strexpr) { s2 = (TString&) evalstack.pop(); s1 = (TString&) evalstack.pop(); @@ -363,7 +374,7 @@ void TExpression::eval() evalstack.push(TString((s1.match(s2)) ? "1" : "0")); break; case _noteq: - if (_type == _strexpr) + if (type == _strexpr) { s2 = (TString&) evalstack.pop(); s1 = (TString&) evalstack.pop(); @@ -377,7 +388,7 @@ void TExpression::eval() } break; case _lt: - if (_type == _strexpr) + if (type == _strexpr) { s2 = (TString&) evalstack.pop(); s1 = (TString&) evalstack.pop(); @@ -391,7 +402,7 @@ void TExpression::eval() } break; case _gt: - if (_type == _strexpr) + if (type == _strexpr) { s2 = (TString&) evalstack.pop(); s1 = (TString&) evalstack.pop(); @@ -405,7 +416,7 @@ void TExpression::eval() } break; case _lteq: - if (_type == _strexpr) + if (type == _strexpr) { s2 = (TString&) evalstack.pop(); s1 = (TString&) evalstack.pop(); @@ -419,7 +430,7 @@ void TExpression::eval() } break; case _gteq: - if (_type == _strexpr) + if (type == _strexpr) { s2 = (TString&) evalstack.pop(); s1 = (TString&) evalstack.pop(); @@ -549,18 +560,28 @@ void TExpression::eval() case _scorp: { const real percent = (real&)evalstack.pop(); - real imponibile = (real&)evalstack.pop(); - const real imposta = imponibile * percent / (percent + 100.0); - imponibile -= imposta; - evalstack.push(imponibile); + real val = (real&)evalstack.pop(); + const real calc = val * percent / (percent + 100.0); + val -= calc; + evalstack.push(val); } break; case _if: - { - s1 = (TString&)evalstack.pop(); - s2 = (TString&)evalstack.pop(); - const real cond = (real&) evalstack.pop();; - evalstack.push(cond.is_zero() ? s1 : s2); + { + if (type == _strexpr) + { + s1 = (TString&)evalstack.pop(); + s2 = (TString&)evalstack.pop(); + const real cond = (real) (TString&) evalstack.pop();; + evalstack.push(cond.is_zero() ? s1 : s2); + } + else + { + o1 = (real&)evalstack.pop(); + o2 = (real&)evalstack.pop(); + const real cond = (real&) evalstack.pop();; + evalstack.push(cond.is_zero() ? o1 : o2); + } } break; case _ansi: @@ -568,8 +589,31 @@ void TExpression::eval() const TDate d((const TString&)evalstack.pop()); const TString16 s(d.string(ANSI)); evalstack.push(s); - } + } + case _num: + type_pointer++; + types.set(type_pointer, FALSE); + type = _strexpr; + break; + case _endnum: + type_pointer--; + type = types[type_pointer] ? _numexpr : _strexpr; + if (type == _numexpr) + evalstack.push(real((TString &) evalstack.pop())); + break; + case _str: + type_pointer++; + types.set(type_pointer, TRUE); + type = _numexpr; + break; + case _endstr: + type_pointer--; + type = types[type_pointer] ? _numexpr : _strexpr; + if (type == _strexpr) + evalstack.push(TString(((real &) evalstack.pop()).string())); + break; default: + NFCHECK("operazione non valida %d", (int) instr.getsym()); break; } } @@ -586,18 +630,20 @@ HIDDEN char _tok[81]; TCodesym TExpression::tok2fun(const char* tok) const { - const int MAX_TOK = 24; + const int MAX_TOK = 26; HIDDEN const char* fnstr[MAX_TOK] = { "ANSI", "CEIL", "COS", "EXP", "EXP10", "IF", "LEFT", "LOG", "LOG10", "MAX", - "MID", "MIN", "PERC", "POW", "RIGHT", - "ROUND", "SCORP", "SIN", "SQR", "SQRT", - "SUBSTR", "TAN", "TRUNC", "UPPER" }; + "MID", "MIN", "NUM", "PERC", "POW", + "RIGHT", "ROUND", "SCORP", "SIN", "SQR", + "SQRT", "STR", "SUBSTR","TAN", "TRUNC", + "UPPER"}; HIDDEN TCodesym fntok[MAX_TOK] = { _ansi, _ceil, _cos, _exp, _exp10, _if, _left, _log, _log10, _max, - _mid, _min, _perc, _pow, _right, - _round, _scorp, _sin, _sqr, _sqrt, - _substr, _tan, _trunc, _upper }; + _mid, _min, _num, _perc, _pow, + _right, _round, _scorp, _sin, _sqr, + _sqrt, _str, _substr, _tan, _trunc, + _upper}; int f = 0, l = MAX_TOK-1, i; while (TRUE) @@ -684,12 +730,16 @@ TCodesym TExpression::__gettoken(bool reduct) switch (*_s) { case '"' : - _s++; - while ((*_s) && (*_s != '"')) - _tok[i++] = *(_s++); - _tok[i] = '\0'; - if (*_s == '"') _s++; - return _string; + case '\'' : + { + const char sep = *_s; + _s++; + while ((*_s) && (*_s != sep)) + _tok[i++] = *(_s++); + _tok[i] = '\0'; + if (*_s == sep) _s++; + return _string; + } case ',' : _s++; return _comma; @@ -805,6 +855,7 @@ TCodesym TExpression::__factor(TCodesym startsym) sym = __gettoken(); if (sym == _lpar) { + sym = __gettoken(); int nparms = 0; while ((sym = __expression(sym)) != _rpar && sym == _comma) nparms++; @@ -812,6 +863,7 @@ TCodesym TExpression::__factor(TCodesym startsym) { _code.add(_number, real(nparms)); _code.add(startsym, val); + _user_func_defined = TRUE; sym = __gettoken(); } } @@ -898,6 +950,17 @@ TCodesym TExpression::__factor(TCodesym startsym) else break; _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; + _code.add(startsym == _num ? _endnum : _endstr); + break; default: break; } @@ -960,7 +1023,8 @@ bool TExpression::compile(const char* expression, TTypeexp type) { TString sc(256); TCodesym currsym; - + + _user_func_defined = FALSE; _s = expression; _type = type; while (((currsym = __gettoken()) != _endsym) && (currsym != _invalid)) diff --git a/include/expr.h b/include/expr.h index 873d0184f..cce4806d2 100755 --- a/include/expr.h +++ b/include/expr.h @@ -57,12 +57,14 @@ enum TCodesym { _ansi, // @emem Data in ansi _if, // @emem Se(expr, val TRUE, val FALSE) _num, // @emem Converte una stringa in numero + _endnum, // @emem Termine della funzione num _str, // @emem Converte un numero in stringa + _endstr, // @emem Termine della funzione str _ceil, // @emem Arrotonda un numero all'intero successivo _trunc, // @emem Tronca i decimali _perc, // @emem Calcola la percentuale _scorp, // @emem Scorpora una percentuale - _substr, // @emem Estrae una sottostringa + _substr, // @emem Estrae una sottostringa } ; // @doc INTERNAL @@ -159,6 +161,8 @@ class TCode : public TObject // @access Public Member public: + // @cmember Duplica il codice + virtual TObject* dup() const; // @cmember Assegnamento tra oggetti TCode TCode& operator =(const TCode& b); // @cmember Inizializza simbolo e valore @@ -181,6 +185,10 @@ public: TCode(TCodesym sym, const TValue& val = nulltvalue) // @cmember Costruttore, inizializza simbolo con

e valore con

{ set(sym, val);} + // @cmember Costruttore + TCode(const TCode & c) + // @cmember Costruttore, inizializza simbolo con

+ { set(c._sym, c._val);} // @cmember Distruttore virtual ~TCode() {} @@ -191,20 +199,16 @@ public: // @class TCodearray | Classe per la definizione di un array di istruzioni da valutare // passo per passo in una espressione // -// @base public | TObject -class TCodearray : public TObject +// @base public | TArray +class TCodearray : public TArray // @author:(INTERNAL) Sandro // @access:(INTERNAL) Private Member { - // @cmember:(INTERNAL) Numero di istruzioni - int _last; // @cmember:(INTERNAL) Puntatore all'istruzione corrente (Istruction pointer) int _ip; - // @cmember:(INTERNAL) Array - TArray _rpn; // @access Public Member public: @@ -217,16 +221,16 @@ public: { _ip = 0;} // @cmember Incrementa l'istruction pointer TCode& step() - { return (TCode&) _rpn[end() ? _ip : _ip++];} + { return *((TCode *) objptr(end() ? _ip : _ip++));} // @cmember Ritorna TRUE se l'istruction pointer ha raggiunto il simbolo di fine codice bool end() const - { return ((TCode&) _rpn[_ip]).getsym() == _endsym;} + { return ((TCode *) objptr(_ip))->getsym() == _endsym;} // @cmember Sposta indietro l'istruction pointer di

passi (si ferma // quando trova l'inizio del puntatore) void backtrace(int step = 1) { if (_ip > step) _ip -= step; else begin(); } - // @cmember Costruttore. Crea un array di 10 elementi - TCodearray(int size = 50); + // @cmember Costruttore. Crea un array di 50 elementi + TCodearray(int size = 50) : TArray(size), _ip(0) {} // @cmember Distruttore virtual ~TCodearray() {} @@ -251,6 +255,8 @@ class TVar : public TObject // @access Public Member public: + // @cmember Duplica la variabile + virtual TObject* dup() const; // @cmember Assegnamento di una stringa all'oggetto Tval const char* operator =(const char* val) @@ -291,7 +297,7 @@ public: TVar(const char* name, const TValue& val = nulltvalue) { _name = name; _val = val;} // @cmember Costruttore (assegna l'oggetto TVal passato) - TVar(TVar& v) + TVar(const TVar & v) { _name = v._name; _val = v._val;} // @cmember Distruttore virtual ~TVar() @@ -303,31 +309,26 @@ public: // @class TVararray | Classe per la definizione di un array di variabili da // valutare nell'esspressione // -// @base public | TObject -class TVararray : public TObject +// @base public | TArray +class TVararray : public TArray // @author:(INTERNAL) Sandro // @access:(INTERNAL) Private Member { - // @cmember:(INTERNAL) Numero di variabili - int _last; - // @cmember:(INTERNAL) Array - TArray _array; - // @access Public Member public: // @cmember Cancella il contenuto dell'array void clear() - { _last = 0; } + { destroy();} // @cmember Aggiunge un oggetto TVar void add(const TVar& var); // @cmember Aggiunge un nome di variabile e il suo valore void add(const char* name, const TValue& val = nulltvalue); // @cmember Ritorna il nome della variabile di posto varnum const char* varname(int varnum) const - { return varnum < _array.items() ? ((TVar&) _array[varnum]).getname() : "";} + { return varnum < items() ? ((TVar *) objptr(varnum))->getname() : "";} // @cmember Setta l'oggetto TVararray con il nome e il valore della variabile void set(const char* varname, const real& val); @@ -336,11 +337,11 @@ public: void set(const char* varname, const char* val); // @cmember Setta l'elemnto dell varaibile

-esima al valore passato void set(int varnum, const real& val) - { if (varnum < _array.items()) ((TVar&) _array[varnum]) = val;} + { if (varnum < items()) *((TVar *) objptr(varnum)) = val;} // @cmember Setta l'elemnto dell varaibile

-esima al valore passato // come stringa void set(int varnum, const char* val) - { if (varnum < _array.items()) ((TVar&) _array[varnum]) = val;} + { if (varnum < items()) *((TVar *) objptr(varnum)) = val;} // @cmember Ritorna il valore della variabile con nome

const real& getnum(const char* varname); @@ -353,10 +354,10 @@ public: // @cmember Ritorna il numero di variabili utilizzate int numvar() const - { return _last;} + { return items();} // @cmember Costruttore - TVararray(int size = 10); + TVararray(int size = 10) : TArray(size) {} // @cmember Distruttore virtual ~TVararray() {} @@ -385,6 +386,8 @@ class TExpression : public TObject TValue _val; // @cmember:(INTERNAL) TRUE se l'espressione e' stata modificata bool _dirty; + // @cmember:(INTERNAL) TRUE se l'espressione ha almeno una funzione urente + bool _user_func_defined; // @cmember:(INTERNAL) Tipo dell'espressione TTypeexp _type; // @cmember:(INTERNAL) Stringa originale @@ -392,6 +395,8 @@ class TExpression : public TObject // @access Protected Member protected: + // @cmember funzione utente da ricalcolare + virtual bool user_func_dirty() { return _user_func_defined;} // @cmember Valuta (calcola) l'espressione void eval(); // @cmember Converte una stringa in un nome di funzione o _invalid se non esiste @@ -411,10 +416,12 @@ protected: protected: // TObject // @cmember Stampa l'espressione su

(serve per implementare l'insertore) virtual void print_on(ostream& out) const ; - virtual void evaluate_user_func(const char* name, int nparms, TStack& stack) const; + virtual void evaluate_user_func(const char * name, int nparms, TStack & stack) const ; // @access Public Member public: + // @cmember Duplica l'espressione + virtual TObject* dup() const; // @cmember operator const | real& | | Ritorna il valore real dell'espressione operator const real&(); // @cmember operator const | char* | | Ritorna il valore dell'espressione come stringa @@ -456,6 +463,8 @@ public: TExpression(const char* expression, TTypeexp type = _numexpr); // @cmember Costruttore (assegna il tipo dell'istruzione) TExpression(TTypeexp type = _numexpr); + // @cmember Costruttore di copia + TExpression(const TExpression & expr); // @cmember Distruttore virtual ~TExpression() {}