Aggiunte funzioni num e str

git-svn-id: svn://10.65.10.50/trunk@3431 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
alex 1996-08-23 14:49:47 +00:00
parent a1c00c753f
commit 43ac216bfd
2 changed files with 176 additions and 103 deletions

View File

@ -15,27 +15,22 @@ 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)
@ -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:
{
if (type == _strexpr)
{
s1 = (TString&)evalstack.pop();
s2 = (TString&)evalstack.pop();
const real cond = (real&) 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:
@ -569,7 +590,30 @@ void TExpression::eval()
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 '"' :
case '\'' :
{
const char sep = *_s;
_s++;
while ((*_s) && (*_s != '"'))
while ((*_s) && (*_s != sep))
_tok[i++] = *(_s++);
_tok[i] = '\0';
if (*_s == '"') _s++;
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;
}
@ -961,6 +1024,7 @@ 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))

View File

@ -57,7 +57,9 @@ 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
@ -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 <p sym> e valore con <p val>
{ set(sym, val);}
// @cmember Costruttore
TCode(const TCode & c)
// @cmember Costruttore, inizializza simbolo con <p c>
{ 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 <p step> 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 <p varnum>-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 <p varnum>-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 <p varname>
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 <p out> (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()
{}