expr.cpp Aggiunte nuove funzioni.

stack.cpp      Aggiunto metodo peek.
CV: ----------------------------------------------------------------------


git-svn-id: svn://10.65.10.50/trunk@3429 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
guy 1996-08-23 12:58:19 +00:00
parent a4b9a8e833
commit 60fa7010c1
4 changed files with 176 additions and 51 deletions

View File

@ -11,7 +11,8 @@
TValue::TValue(const real& val) TValue::TValue(const real& val)
{ {
_r = val; _r = val;
_s = val.string( ); _s = val.string();
_t = _numexpr;
} }
TCodearray::TCodearray(int size) : _rpn(size) TCodearray::TCodearray(int size) : _rpn(size)
@ -45,14 +46,12 @@ TCode& TCode::operator =(const TCode& b)
} }
TVararray::TVararray(int size) : _array(size) TVararray::TVararray(int size) : _array(size)
{ {
clear(); clear();
} }
void TVararray::add(const char* name, const TValue& val) void TVararray::add(const char* name, const TValue& val)
{ {
TVar* v = new TVar(name, val); TVar* v = new TVar(name, val);
_array.add(v, _last++); _array.add(v, _last++);
@ -190,7 +189,7 @@ TExpression::operator const char*()
void TExpression::print_on(ostream& out) const void TExpression::print_on(ostream& out) const
{ out << _original; } { out << _original; }
void TExpression::evaluate_user_func(const char * name, int nparms, TStack & stack) void TExpression::evaluate_user_func(const char * name, int nparms, TStack & stack) const
{ {
NFCHECK("Unknown function : %s ", name); NFCHECK("Unknown function : %s ", name);
@ -246,7 +245,7 @@ void TExpression::eval()
{ {
TStack evalstack(50); TStack evalstack(50);
TCode instr; TCode instr;
real o1, o2, zero(0.00); real o1, o2;
TString s1, s2; TString s1, s2;
_code.begin(); _code.begin();
@ -315,15 +314,15 @@ void TExpression::eval()
case _and: case _and:
if (_type == _strexpr) if (_type == _strexpr)
{ {
o2 = real((const char*) (TString&)evalstack.pop()); o2 = real((const char*)(TString&)evalstack.pop());
o1 = real((const char*) (TString&)evalstack.pop()); o1 = real((const char*)(TString&)evalstack.pop());
evalstack.push(TString((o1 != zero && o2 != zero) ? "1" : "0")); evalstack.push(TString((o1 != ZERO && o2 != ZERO) ? "1" : "0"));
} }
else else
{ {
o2 = (real&) evalstack.pop(); o2 = (real&) evalstack.pop();
o1 = (real&) evalstack.pop(); o1 = (real&) evalstack.pop();
evalstack.push(real((o1 != zero && o2 != zero) ? 1.0 : 0.0)); evalstack.push(real((o1 != ZERO && o2 != ZERO) ? 1.0 : 0.0));
} }
break; break;
case _or: case _or:
@ -331,18 +330,18 @@ void TExpression::eval()
{ {
o2 = real((const char*) (TString&)evalstack.pop()); o2 = real((const char*) (TString&)evalstack.pop());
o1 = real((const char*) (TString&)evalstack.pop()); o1 = real((const char*) (TString&)evalstack.pop());
evalstack.push(TString((o1 != zero || o2 != zero) ? "1" : "0")); evalstack.push(TString((o1 != ZERO || o2 != ZERO) ? "1" : "0"));
} }
else else
{ {
o2 = (real&) evalstack.pop(); o2 = (real&) evalstack.pop();
o1 = (real&) evalstack.pop(); o1 = (real&) evalstack.pop();
evalstack.push(real((o1 != zero || o2 != zero) ? 1.0 : 0.0)); evalstack.push(real((o1 != ZERO || o2 != ZERO) ? 1.0 : 0.0));
} }
break; break;
case _not: case _not:
o1 = (real&) evalstack.pop(); o1 = (real&) evalstack.pop();
evalstack.push(real((o1 == zero) ? 1.0 : 0.0)); evalstack.push(real((o1 == ZERO) ? 1.0 : 0.0));
break; break;
case _equal: case _equal:
if (_type == _strexpr) if (_type == _strexpr)
@ -488,6 +487,14 @@ void TExpression::eval()
evalstack.push(s); evalstack.push(s);
} }
break; break;
case _substr:
{
const int to = (int)((const real&)evalstack.pop()).integer();
const int from = (int)((const real&)evalstack.pop()).integer() - 1;
const TString& s = ((const TString&)evalstack.pop()).sub(from, to);
evalstack.push(s);
}
break;
case _pow: case _pow:
o2 = (real&) evalstack.pop(); o2 = (real&) evalstack.pop();
o1 = (real&) evalstack.pop(); o1 = (real&) evalstack.pop();
@ -516,6 +523,46 @@ void TExpression::eval()
evalstack.push(o1); evalstack.push(o1);
} }
break; break;
case _trunc:
{
const int ndec = (int)((real&) evalstack.pop()).integer();
o1 = (real&) evalstack.pop();
o1.trunc(ndec);
evalstack.push(o1);
}
break;
case _ceil:
{
const int ndec = (int)((real&) evalstack.pop()).integer();
o1 = (real&) evalstack.pop();
o1.ceil(ndec);
evalstack.push(o1);
}
break;
case _perc:
{
o1 = (real&) evalstack.pop();
o2 = (real&) evalstack.pop();
evalstack.push(real(o1 * o2 / 100.0));
}
break;
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);
}
break;
case _if:
{
s1 = (TString&)evalstack.pop();
s2 = (TString&)evalstack.pop();
const real cond = (real&) evalstack.pop();;
evalstack.push(cond.is_zero() ? s1 : s2);
}
break;
case _ansi: case _ansi:
{ {
const TDate d((const TString&)evalstack.pop()); const TDate d((const TString&)evalstack.pop());
@ -526,29 +573,55 @@ void TExpression::eval()
break; break;
} }
} }
if (_type == _strexpr)
_val = (const char*) (TString&) evalstack.pop();
else
_val = (real&) evalstack.pop();
if (_type == _strexpr)
_val = (TString&)evalstack.pop();
else
_val = (real&)evalstack.pop();
} }
HIDDEN const char* _s; HIDDEN const char* _s;
HIDDEN char _tok[81]; HIDDEN char _tok[81];
HIDDEN const char* _fntable[] = { "sqrt", "sqr", "exp10", "exp", "log10",
"log", "sin", "cos", "tan", "left",
"right", "pow", "min", "max", "mid", "upper",
"round", "ansi", NULL };
HIDDEN TCodesym _fntok[] = { _sqrt, _sqr, _exp10, _exp, _log10, _log, TCodesym TExpression::tok2fun(const char* tok) const
_sin, _cos, _tan, _left, _right, _pow, {
_min, _max, _mid, _upper, _round, _ansi}; const int MAX_TOK = 24;
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" };
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 };
int f = 0, l = MAX_TOK-1, i;
while (TRUE)
{
i = (f+l)>>1;
const int cmp = stricmp(tok, fnstr[i]);
if (cmp == 0)
break;
if (cmp > 0) f = i+1;
else l = i-1;
if (f > l)
{
i = -1;
break;
}
}
return i >= 0 ? fntok[i] : _invalid;
}
TCodesym TExpression::__gettoken(bool reduct) TCodesym TExpression::__gettoken(bool reduct)
{ {
TCodesym sym = _invalid; TCodesym sym = _invalid;
int i = 0; int i = 0;
_tok[0] = '\0'; _tok[0] = '\0';
@ -598,13 +671,14 @@ TCodesym TExpression::__gettoken(bool reduct)
_tok[i++] = *(_s++); _tok[i++] = *(_s++);
} }
_tok[i] = '\0'; _tok[i] = '\0';
TString s(_tok);
s.lower(); sym = tok2fun(_tok); // Guy was here!
for ( int j = 0; _fntable[j] != NULL; j++) if (sym != _invalid)
if (s == _fntable[j]) return _fntok[j]; return sym;
for (const char * p = _s; *p && *p == ' '; p++);
for (const char * p = _s; isspace(*p); p++);
if (*p == '(') if (*p == '(')
return _userfunc; return _userfunc;
return _variable; return _variable;
} }
switch (*_s) switch (*_s)
@ -703,9 +777,8 @@ TCodesym TExpression::__gettoken(bool reduct)
TCodesym TExpression::__factor(TCodesym startsym) TCodesym TExpression::__factor(TCodesym startsym)
{ {
TCodesym sym = _invalid; TCodesym sym = _invalid;
switch (startsym) switch (startsym)
{ {
@ -729,7 +802,6 @@ TCodesym TExpression::__factor(TCodesym startsym)
case _userfunc: case _userfunc:
{ {
TValue val (_tok); TValue val (_tok);
sym = __gettoken(); sym = __gettoken();
if (sym == _lpar) if (sym == _lpar)
{ {
@ -779,6 +851,10 @@ TCodesym TExpression::__factor(TCodesym startsym)
case _min: case _min:
case _max: case _max:
case _round: case _round:
case _ceil:
case _trunc:
case _perc:
case _scorp:
sym = __gettoken(); sym = __gettoken();
if (sym == _lpar) sym = __gettoken(TRUE); if (sym == _lpar) sym = __gettoken(TRUE);
else break; else break;
@ -791,6 +867,7 @@ TCodesym TExpression::__factor(TCodesym startsym)
_code.add(startsym); _code.add(startsym);
break; break;
case _mid: case _mid:
case _substr:
sym = __gettoken(); sym = __gettoken();
if (sym == _lpar) sym = __gettoken(TRUE); if (sym == _lpar) sym = __gettoken(TRUE);
else break; else break;
@ -806,6 +883,21 @@ TCodesym TExpression::__factor(TCodesym startsym)
else break; else break;
_code.add(startsym); _code.add(startsym);
break; 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();
else break;
_code.add(startsym);
break;
default: default:
break; break;
} }
@ -814,7 +906,6 @@ TCodesym TExpression::__factor(TCodesym startsym)
TCodesym TExpression::__term(TCodesym startsym) TCodesym TExpression::__term(TCodesym startsym)
{ {
TCodesym sym; TCodesym sym;

View File

@ -54,8 +54,16 @@ enum TCodesym {
_mid, // @emem Media degli elementi _mid, // @emem Media degli elementi
_upper, // @emem Trasformazione in maiuscolo _upper, // @emem Trasformazione in maiuscolo
_round, // @emem Arrotondamento _round, // @emem Arrotondamento
_ansi } ; // @emem Data in ansi _ansi, // @emem Data in ansi
_if, // @emem Se(expr, val TRUE, val FALSE)
_num, // @emem Converte una stringa in numero
_str, // @emem Converte un numero in stringa
_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
} ;
// @doc INTERNAL // @doc INTERNAL
// @enum TTypeexp | Tipi di espressioni definiti // @enum TTypeexp | Tipi di espressioni definiti
@ -79,30 +87,39 @@ enum TCodesym {
real _r; real _r;
// @cmember:(INTERNAL) Valore in formato stringa // @cmember:(INTERNAL) Valore in formato stringa
TString _s; TString _s;
// @cmember:(INTERNAL) Tipo preferito
TTypeexp _t;
// @access Public Member // @access Public Member
public: public:
// @cmember Assegnamento tra oggetti TValue // @cmember Assegnamento tra oggetti TValue
TValue& operator =(const TValue& val) TValue& operator =(const TValue& val)
{ _s = val._s; _r = val._r; return *this;} { _s = val._s; _r = val._r; _t = val._t; return *this; }
// @cmember Assegnamento di una stringa
TValue& operator =(const TString& s)
{ _s = s; _r = real(s); _t = _strexpr; return *this; }
// @cmember Assegnamento di un numero
TValue& operator =(const real& r)
{ _s = r.string(); _r = r; _t = _numexpr; return *this; }
// @cmember Ritorna il valore numerico // @cmember Ritorna il valore numerico
const real& number() const const real& number() const
{ return _r;} { return _r; }
// @cmember Ritorna il valore come stringa // @cmember Ritorna il valore come stringa
const char* string() const const char* string() const
{ return (const char*) _s;} { return (const char*) _s;}
// @cmember Setta il valore passato come real // @cmember Setta il valore passato come real
void set(const real& val) void set(const real& val)
{ _r = val; _s = val.string();} { _r = val; _s = val.string(); _t = _numexpr; }
// @cmember Setta il valore passato come stringa // @cmember Setta il valore passato come stringa
void set(const char* val) void set(const char* val)
{ _s = val; _r = real(val);} { _s = val; _r = real(val); _t = _strexpr; }
// @cmember Setta il valore passato come stringa
TTypeexp type() const { return _t; }
// @cmember Costruttore. Inizializza TValue con un reale // @cmember Costruttore. Inizializza TValue con un reale
TValue(const real& val); TValue(const real& val);
// @cmember Costruttore. Inizializza TValue con una stringa // @cmember Costruttore. Inizializza TValue con una stringa
TValue(const char* val) TValue(const char* val)
{ _s = val; _r = real(val);} { _s = val; _r = real(val); _t = _strexpr; }
// @cmember Costruttore. Inizializza TValue con un altro TValue // @cmember Costruttore. Inizializza TValue con un altro TValue
TValue(const TValue& val) TValue(const TValue& val)
{ *this = val; } { *this = val; }
@ -377,6 +394,8 @@ class TExpression : public TObject
protected: protected:
// @cmember Valuta (calcola) l'espressione // @cmember Valuta (calcola) l'espressione
void eval(); void eval();
// @cmember Converte una stringa in un nome di funzione o _invalid se non esiste
TCodesym tok2fun(const char* tok) const;
// @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);
@ -392,7 +411,7 @@ protected:
protected: // TObject protected: // TObject
// @cmember Stampa l'espressione su <p out> (serve per implementare l'insertore) // @cmember Stampa l'espressione su <p out> (serve per implementare l'insertore)
virtual void print_on(ostream& out) const ; virtual void print_on(ostream& out) const ;
virtual void evaluate_user_func(const char * name, int nparms, TStack & stack); virtual void evaluate_user_func(const char* name, int nparms, TStack& stack) const;
// @access Public Member // @access Public Member
public: public:

View File

@ -8,9 +8,19 @@ void TStack::push(const TObject& o)
add(o, _sp++); add(o, _sp++);
} }
void TStack::push(TObject* o)
{
add(o, _sp++);
}
TObject& TStack::pop() TObject& TStack::pop()
{ {
CHECK(count() > 0, "Stack underflow!"); CHECK(count() > 0, "Stack underflow!");
return (*this)[--_sp]; return (*this)[--_sp];
} }
TObject& TStack::peek(int depth) const
{
CHECK(depth > _sp, "Stack underflow!");
return (*this)[_sp-depth-1];
}

View File

@ -12,7 +12,7 @@
// @base public | TArray // @base public | TArray
class TStack : private TArray class TStack : private TArray
// @author:(INTERNAL) Sandro // @author:(INTERNAL) Alex
// @access:(INTERNAL) Private Member // @access:(INTERNAL) Private Member
{ {
@ -21,16 +21,21 @@ class TStack : private TArray
// @access Public Member // @access Public Member
public: public:
// @cmember Costruttore. Chaima il costruttore di <c TArray>
TStack(int size);
// @cmember Ritorna il puntatore allo stack // @cmember Ritorna il puntatore allo stack
int count() const int count() const
{ return _sp; } { return _sp; }
// @cmember Aggiunge un oggetto sullo stack // @cmember Aggiunge un oggetto sullo stack
void push(const TObject&); void push(const TObject& o);
// @cmember Aggiunge un oggetto sullo stack
void push(TObject* o);
// @cmember Ritorna il primo oggetto sulla cima dello stack // @cmember Ritorna il primo oggetto sulla cima dello stack
TObject& pop(); TObject& pop();
// @cmember Ritorna l'oggetto ad una data profondita' nello stack
TObject& peek(int depth = 0) const;
// @cmember Costruttore. Chiama il costruttore di <c TArray>
TStack(int size = 16);
// @cmember Distruttore. Chiama il distruttore di <c TArray>
virtual ~TStack() { }
}; };
#endif #endif