00001
00002
00003
00004
00005 #include "CLHEP/Evaluator/Evaluator.h"
00006
00007 #include <iostream>
00008 #include <sstream>
00009 #include <cmath>
00010 #include "CLHEP/Evaluator/stack.icc"
00011 #include "CLHEP/Evaluator/string.icc"
00012 #include "CLHEP/Evaluator/hash_map.icc"
00013 #include <string.h>
00014 #include <ctype.h>
00015 #include <errno.h>
00016 #include <stdlib.h>
00017
00018
00019
00020
00021 typedef void (*voidfuncptr)();
00022 struct Item {
00023 enum { UNKNOWN, VARIABLE, EXPRESSION, FUNCTION } what;
00024 double variable;
00025 string expression;
00026
00027
00028
00029 voidfuncptr function;
00030
00031 Item() : what(UNKNOWN), variable(0),expression(), function(0) {}
00032 Item(double x) : what(VARIABLE), variable(x),expression(), function(0) {}
00033 Item(string x) : what(EXPRESSION),variable(0),expression(x),function(0) {}
00034 Item(voidfuncptr x) : what(FUNCTION), variable(0),expression(), function(x) {}
00035 };
00036
00037 typedef char * pchar;
00038 typedef hash_map<string,Item> dic_type;
00039
00040 struct Struct {
00041 dic_type theDictionary;
00042 pchar theExpression;
00043 pchar thePosition;
00044 int theStatus;
00045 double theResult;
00046 };
00047
00048
00049 #define EVAL HepTool::Evaluator
00050
00051 #define REMOVE_BLANKS \
00052 for(pointer=name;;pointer++) if (!isspace(*pointer)) break; \
00053 for(n=strlen(pointer);n>0;n--) if (!isspace(*(pointer+n-1))) break
00054
00055 #define SKIP_BLANKS \
00056 for(;;pointer++) { \
00057 c = (pointer > end) ? '\0' : *pointer; \
00058 if (!isspace(c)) break; \
00059 }
00060
00061 #define EVAL_EXIT(STATUS,POSITION) endp = POSITION; return STATUS
00062 #define MAX_N_PAR 5
00063
00064 static const char sss[MAX_N_PAR+2] = "012345";
00065
00066 enum { ENDL, LBRA, OR, AND, EQ, NE, GE, GT, LE, LT,
00067 PLUS, MINUS, UNARY_PLUS, UNARY_MINUS, MULT, DIV, POW, RBRA, VALUE };
00068
00069 static int engine(pchar, pchar, double &, pchar &, const dic_type &);
00070
00071 static int variable(const string & name, double & result,
00072 const dic_type & dictionary)
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 {
00088 dic_type::const_iterator iter = dictionary.find(name);
00089 if (iter == dictionary.end())
00090 return EVAL::ERROR_UNKNOWN_VARIABLE;
00091 Item item = iter->second;
00092 switch (item.what) {
00093 case Item::VARIABLE:
00094 result = item.variable;
00095 return EVAL::OK;
00096 case Item::EXPRESSION: {
00097 pchar exp_begin = (char *)(item.expression.c_str());
00098 pchar exp_end = exp_begin + strlen(exp_begin) - 1;
00099 if (engine(exp_begin, exp_end, result, exp_end, dictionary) == EVAL::OK)
00100 return EVAL::OK;
00101 }
00102 default:
00103 return EVAL::ERROR_CALCULATION_ERROR;
00104 }
00105 }
00106
00107 static int function(const string & name, stack<double> & par,
00108 double & result, const dic_type & dictionary)
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 {
00125 int npar = par.size();
00126 if (npar > MAX_N_PAR) return EVAL::ERROR_UNKNOWN_FUNCTION;
00127
00128 dic_type::const_iterator iter = dictionary.find(sss[npar]+name);
00129 if (iter == dictionary.end()) return EVAL::ERROR_UNKNOWN_FUNCTION;
00130 Item item = iter->second;
00131
00132 double pp[MAX_N_PAR];
00133 for(int i=0; i<npar; i++) { pp[i] = par.top(); par.pop(); }
00134 errno = 0;
00135 if (item.function == 0) return EVAL::ERROR_CALCULATION_ERROR;
00136 switch (npar) {
00137 case 0:
00138 result = ((double (*)())item.function)();
00139 break;
00140 case 1:
00141 result = ((double (*)(double))item.function)(pp[0]);
00142 break;
00143 case 2:
00144 result = ((double (*)(double,double))item.function)(pp[1], pp[0]);
00145 break;
00146 case 3:
00147 result = ((double (*)(double,double,double))item.function)
00148 (pp[2],pp[1],pp[0]);
00149 break;
00150 case 4:
00151 result = ((double (*)(double,double,double,double))item.function)
00152 (pp[3],pp[2],pp[1],pp[0]);
00153 break;
00154 case 5:
00155 result = ((double (*)(double,double,double,double,double))item.function)
00156 (pp[4],pp[3],pp[2],pp[1],pp[0]);
00157 break;
00158 }
00159 return (errno == 0) ? EVAL::OK : EVAL::ERROR_CALCULATION_ERROR;
00160 }
00161
00162 static int operand(pchar begin, pchar end, double & result,
00163 pchar & endp, const dic_type & dictionary)
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 {
00182 pchar pointer = begin;
00183 int EVAL_STATUS;
00184 char c;
00185
00186
00187
00188 if (!isalpha(*pointer)) {
00189 errno = 0;
00190 result = strtod(pointer, (char **)(&pointer));
00191 if (errno == 0) {
00192 EVAL_EXIT( EVAL::OK, --pointer );
00193 }else{
00194 EVAL_EXIT( EVAL::ERROR_CALCULATION_ERROR, begin );
00195 }
00196 }
00197
00198
00199
00200 while(pointer <= end) {
00201 c = *pointer;
00202 if (c != '_' && !isalnum(c)) break;
00203 pointer++;
00204 }
00205 c = *pointer;
00206 *pointer = '\0';
00207 string name(begin);
00208 *pointer = c;
00209
00210
00211
00212 result = 0.0;
00213 SKIP_BLANKS;
00214 if (c != '(') {
00215 EVAL_STATUS = variable(name, result, dictionary);
00216 EVAL_EXIT( EVAL_STATUS, (EVAL_STATUS == EVAL::OK) ? --pointer : begin);
00217 }
00218
00219
00220
00221 stack<pchar> pos;
00222 stack<double> par;
00223 double value;
00224 pchar par_begin = pointer+1, par_end;
00225
00226 for(;;pointer++) {
00227 c = (pointer > end) ? '\0' : *pointer;
00228 switch (c) {
00229 case '\0':
00230 EVAL_EXIT( EVAL::ERROR_UNPAIRED_PARENTHESIS, pos.top() );
00231 case '(':
00232 pos.push(pointer); break;
00233 case ',':
00234 if (pos.size() == 1) {
00235 par_end = pointer-1;
00236 EVAL_STATUS = engine(par_begin, par_end, value, par_end, dictionary);
00237 if (EVAL_STATUS == EVAL::WARNING_BLANK_STRING)
00238 { EVAL_EXIT( EVAL::ERROR_EMPTY_PARAMETER, --par_end ); }
00239 if (EVAL_STATUS != EVAL::OK)
00240 { EVAL_EXIT( EVAL_STATUS, par_end ); }
00241 par.push(value);
00242 par_begin = pointer + 1;
00243 }
00244 break;
00245 case ')':
00246 if (pos.size() > 1) {
00247 pos.pop();
00248 break;
00249 }else{
00250 par_end = pointer-1;
00251 EVAL_STATUS = engine(par_begin, par_end, value, par_end, dictionary);
00252 switch (EVAL_STATUS) {
00253 case EVAL::OK:
00254 par.push(value);
00255 break;
00256 case EVAL::WARNING_BLANK_STRING:
00257 if (par.size() != 0)
00258 { EVAL_EXIT( EVAL::ERROR_EMPTY_PARAMETER, --par_end ); }
00259 break;
00260 default:
00261 EVAL_EXIT( EVAL_STATUS, par_end );
00262 }
00263 EVAL_STATUS = function(name, par, result, dictionary);
00264 EVAL_EXIT( EVAL_STATUS, (EVAL_STATUS == EVAL::OK) ? pointer : begin);
00265 }
00266 }
00267 }
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 static int maker(int op, stack<double> & val)
00285 {
00286 if (val.size() < 2) return EVAL::ERROR_SYNTAX_ERROR;
00287 double val2 = val.top(); val.pop();
00288 double val1 = val.top();
00289 switch (op) {
00290 case OR:
00291 val.top() = (val1 || val2) ? 1. : 0.;
00292 return EVAL::OK;
00293 case AND:
00294 val.top() = (val1 && val2) ? 1. : 0.;
00295 return EVAL::OK;
00296 case EQ:
00297 val.top() = (val1 == val2) ? 1. : 0.;
00298 return EVAL::OK;
00299 case NE:
00300 val.top() = (val1 != val2) ? 1. : 0.;
00301 return EVAL::OK;
00302 case GE:
00303 val.top() = (val1 >= val2) ? 1. : 0.;
00304 return EVAL::OK;
00305 case GT:
00306 val.top() = (val1 > val2) ? 1. : 0.;
00307 return EVAL::OK;
00308 case LE:
00309 val.top() = (val1 <= val2) ? 1. : 0.;
00310 return EVAL::OK;
00311 case LT:
00312 val.top() = (val1 < val2) ? 1. : 0.;
00313 return EVAL::OK;
00314 case PLUS:
00315 val.top() = val1 + val2;
00316 return EVAL::OK;
00317 case MINUS:
00318 val.top() = val1 - val2;
00319 return EVAL::OK;
00320 case MULT:
00321 val.top() = val1 * val2;
00322 return EVAL::OK;
00323 case DIV:
00324 if (val2 == 0.0) return EVAL::ERROR_CALCULATION_ERROR;
00325 val.top() = val1 / val2;
00326 return EVAL::OK;
00327 case POW:
00328 errno = 0;
00329 val.top() = std::pow(val1,val2);
00330 if (errno == 0) return EVAL::OK;
00331 case UNARY_PLUS:
00332 val.top() = val1 + val2;
00333 return EVAL::OK;
00334 case UNARY_MINUS:
00335 val.top() = val1 - val2;
00336 return EVAL::OK;
00337 default:
00338 return EVAL::ERROR_CALCULATION_ERROR;
00339 }
00340 }
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 static int engine(pchar begin, pchar end, double & result,
00359 pchar & endp, const dic_type & dictionary)
00360 {
00361 enum SyntaxTableEntry {
00362 SyntaxError = 0,
00363 NumberVariableOrFunction = 1,
00364 UnaryPlusOrMinus = 2,
00365 AnyOperator = 3
00366 };
00367 static const int SyntaxTable[19][19] = {
00368
00369 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
00370 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
00371 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
00372 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
00373 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
00374 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
00375 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
00376 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
00377 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
00378 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
00379 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
00380 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
00381 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
00382 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
00383 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
00384 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
00385 { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 },
00386 { 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0 },
00387 { 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0 }
00388 };
00389 enum ActionTableEntry {
00390 UnbalancedParentheses = -1,
00391 ExpressionCompleted = 0,
00392 HigherPrecedenceOperator = 1,
00393 SamePrecedenceOperator = 2,
00394 CloseProcessedParenthesesOrExpression = 3,
00395 LowerPrecedenceOperator = 4
00396 };
00397 static const int ActionTable[17][18] = {
00398
00399 { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1 },
00400 {-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3 },
00401 { 4, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4 },
00402 { 4, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4 },
00403 { 4, 1, 4, 4, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4 },
00404 { 4, 1, 4, 4, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4 },
00405 { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 4 },
00406 { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 4 },
00407 { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 4 },
00408 { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 4 },
00409 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 1, 1, 1, 1, 1, 4 },
00410 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 1, 1, 1, 1, 1, 4 },
00411 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4, 4, 1, 4 },
00412 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4, 4, 1, 4 },
00413 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 2, 2, 1, 4 },
00414 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 2, 2, 1, 4 },
00415 { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4, 4, 4, 4 }
00416 };
00417
00418 stack<int> op;
00419 stack<pchar> pos;
00420 stack<double> val;
00421 double value;
00422 pchar pointer = begin;
00423 int iWhat, iCur, iPrev = 0, iTop, EVAL_STATUS;
00424 char c;
00425
00426 op.push(0); pos.push(pointer);
00427 SKIP_BLANKS;
00428 if (c == '\0') { EVAL_EXIT( EVAL::WARNING_BLANK_STRING, begin ); }
00429 for(;;pointer++) {
00430
00431
00432
00433 c = (pointer > end) ? '\0' : *pointer;
00434 if (isspace(c)) continue;
00435 switch (c) {
00436 case '\0': iCur = ENDL; break;
00437 case '(': iCur = LBRA; break;
00438 case '|':
00439 if (*(pointer+1) == '|') {
00440 pointer++; iCur = OR; break;
00441 }else{
00442 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer );
00443 }
00444 case '&':
00445 if (*(pointer+1) == '&') {
00446 pointer++; iCur = AND; break;
00447 }else{
00448 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer );
00449 }
00450 case '=':
00451 if (*(pointer+1) == '=') {
00452 pointer++; iCur = EQ; break;
00453 }else{
00454 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer );
00455 }
00456 case '!':
00457 if (*(pointer+1) == '=') {
00458 pointer++; iCur = NE; break;
00459 }else{
00460 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer );
00461 }
00462 case '>':
00463 if (*(pointer+1) == '=') { pointer++; iCur = GE; } else { iCur = GT; }
00464 break;
00465 case '<':
00466 if (*(pointer+1) == '=') { pointer++; iCur = LE; } else { iCur = LT; }
00467 break;
00468 case '+': iCur = PLUS; break;
00469 case '-': iCur = MINUS; break;
00470 case '*':
00471 if (*(pointer+1) == '*') { pointer++; iCur = POW; }else{ iCur = MULT; }
00472 break;
00473 case '/': iCur = DIV; break;
00474 case '^': iCur = POW; break;
00475 case ')': iCur = RBRA; break;
00476 default:
00477 if (c == '.' || isalnum(c)) {
00478 iCur = VALUE; break;
00479 }else{
00480 EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer );
00481 }
00482 }
00483
00484
00485
00486 iWhat = SyntaxTable[iPrev][iCur];
00487 iPrev = iCur;
00488 switch (iWhat) {
00489 case 0:
00490 EVAL_EXIT( EVAL::ERROR_SYNTAX_ERROR, pointer );
00491 case 1:
00492 EVAL_STATUS = operand(pointer, end, value, pointer, dictionary);
00493 if (EVAL_STATUS != EVAL::OK) { EVAL_EXIT( EVAL_STATUS, pointer ); }
00494 val.push(value);
00495 continue;
00496 case 2:
00497 val.push(0.0);
00498 if (iCur == PLUS) iCur = UNARY_PLUS;
00499 if (iCur == MINUS) iCur = UNARY_MINUS;
00500
00501
00502 case 3: default:
00503 break;
00504 }
00505
00506
00507
00508 for(;;) {
00509 if (op.size() == 0) { EVAL_EXIT( EVAL::ERROR_SYNTAX_ERROR, pointer ); }
00510 iTop = op.top();
00511 switch (ActionTable[iTop][iCur]) {
00512 case -1:
00513 if (op.size() > 1) pointer = pos.top();
00514 EVAL_EXIT( EVAL::ERROR_UNPAIRED_PARENTHESIS, pointer );
00515 case 0:
00516 if (val.size() == 1) {
00517 result = val.top();
00518 EVAL_EXIT( EVAL::OK, pointer );
00519 }else{
00520 EVAL_EXIT( EVAL::ERROR_SYNTAX_ERROR, pointer );
00521 }
00522 case 1:
00523 op.push(iCur); pos.push(pointer);
00524 break;
00525 case 2:
00526 EVAL_STATUS = maker(iTop, val);
00527 if (EVAL_STATUS != EVAL::OK) {
00528 EVAL_EXIT( EVAL_STATUS, pos.top() );
00529 }
00530 op.top() = iCur; pos.top() = pointer;
00531 break;
00532 case 3:
00533 op.pop(); pos.pop();
00534 break;
00535 case 4: default:
00536 EVAL_STATUS = maker(iTop, val);
00537 if (EVAL_STATUS != EVAL::OK) {
00538 EVAL_EXIT( EVAL_STATUS, pos.top() );
00539 }
00540 op.pop(); pos.pop();
00541 continue;
00542 }
00543 break;
00544 }
00545 }
00546 }
00547
00548
00549 static void setItem(const char * prefix, const char * name,
00550 const Item & item, Struct * s) {
00551
00552 if (name == 0 || *name == '\0') {
00553 s->theStatus = EVAL::ERROR_NOT_A_NAME;
00554 return;
00555 }
00556
00557
00558
00559 const char * pointer; int n; REMOVE_BLANKS;
00560
00561
00562
00563 if (n == 0) {
00564 s->theStatus = EVAL::ERROR_NOT_A_NAME;
00565 return;
00566 }
00567 for(int i=0; i<n; i++) {
00568 char c = *(pointer+i);
00569 if (c != '_' && !isalnum(c)) {
00570 s->theStatus = EVAL::ERROR_NOT_A_NAME;
00571 return;
00572 }
00573 }
00574
00575
00576
00577 string item_name = prefix + string(pointer,n);
00578 dic_type::iterator iter = (s->theDictionary).find(item_name);
00579 if (iter != (s->theDictionary).end()) {
00580 iter->second = item;
00581 if (item_name == name) {
00582 s->theStatus = EVAL::WARNING_EXISTING_VARIABLE;
00583 }else{
00584 s->theStatus = EVAL::WARNING_EXISTING_FUNCTION;
00585 }
00586 }else{
00587 (s->theDictionary)[item_name] = item;
00588 s->theStatus = EVAL::OK;
00589 }
00590 }
00591
00592
00593 namespace HepTool {
00594
00595
00596 Evaluator::Evaluator() {
00597 Struct * s = new Struct();
00598 p = (void *) s;
00599 s->theExpression = 0;
00600 s->thePosition = 0;
00601 s->theStatus = OK;
00602 s->theResult = 0.0;
00603 }
00604
00605
00606 Evaluator::~Evaluator() {
00607 delete (Struct *)(p);
00608 }
00609
00610
00611 double Evaluator::evaluate(const char * expression) {
00612 Struct * s = (Struct *)(p);
00613 if (s->theExpression != 0) { delete[] s->theExpression; }
00614 s->theExpression = 0;
00615 s->thePosition = 0;
00616 s->theStatus = WARNING_BLANK_STRING;
00617 s->theResult = 0.0;
00618 if (expression != 0) {
00619 s->theExpression = new char[strlen(expression)+1];
00620 strcpy(s->theExpression, expression);
00621 s->theStatus = engine(s->theExpression,
00622 s->theExpression+strlen(expression)-1,
00623 s->theResult,
00624 s->thePosition,
00625 s->theDictionary);
00626 }
00627 return s->theResult;
00628 }
00629
00630
00631 int Evaluator::status() const {
00632 return ((Struct *)(p))->theStatus;
00633 }
00634
00635
00636 int Evaluator::error_position() const {
00637 return ((Struct *)(p))->thePosition - ((Struct *)(p))->theExpression;
00638 }
00639
00640
00641 void Evaluator::print_error() const {
00642 Struct * s = (Struct *) p;
00643 if(s->theStatus != OK) {
00644 std::cerr << error_name() << std::endl;
00645 }
00646 return;
00647 }
00648
00649
00650 std::string Evaluator::error_name() const
00651 {
00652 char prefix[] = "Evaluator : ";
00653 std::ostringstream errn;
00654 Struct * s = (Struct *) p;
00655 switch (s->theStatus) {
00656 case ERROR_NOT_A_NAME:
00657 errn << prefix << "invalid name";
00658 break;
00659 case ERROR_SYNTAX_ERROR:
00660 errn << prefix << "syntax error";
00661 break;
00662 case ERROR_UNPAIRED_PARENTHESIS:
00663 errn << prefix << "unpaired parenthesis";
00664 break;
00665 case ERROR_UNEXPECTED_SYMBOL:
00666 errn << prefix << "unexpected symbol";
00667 break;
00668 case ERROR_UNKNOWN_VARIABLE:
00669 errn << prefix << "unknown variable";
00670 break;
00671 case ERROR_UNKNOWN_FUNCTION:
00672 errn << prefix << "unknown function";
00673 break;
00674 case ERROR_EMPTY_PARAMETER:
00675 errn << prefix << "empty parameter in function call";
00676 break;
00677 case ERROR_CALCULATION_ERROR:
00678 errn << prefix << "calculation error";
00679 break;
00680 default:
00681 errn << " ";
00682 }
00683 return errn.str();
00684 }
00685
00686
00687 void Evaluator::setVariable(const char * name, double value)
00688 { setItem("", name, Item(value), (Struct *)p); }
00689
00690 void Evaluator::setVariable(const char * name, const char * expression)
00691 { setItem("", name, Item(expression), (Struct *)p); }
00692
00693
00694
00695
00696 void Evaluator::setFunction(const char * name,
00697 double (*fun)())
00698 { setItem("0", name, Item(reinterpret_cast<voidfuncptr>(fun)), (Struct *)p); }
00699
00700 void Evaluator::setFunction(const char * name,
00701 double (*fun)(double))
00702 { setItem("1", name, Item(reinterpret_cast<voidfuncptr>(fun)), (Struct *)p); }
00703
00704 void Evaluator::setFunction(const char * name,
00705 double (*fun)(double,double))
00706 { setItem("2", name, Item(reinterpret_cast<voidfuncptr>(fun)), (Struct *)p); }
00707
00708 void Evaluator::setFunction(const char * name,
00709 double (*fun)(double,double,double))
00710 { setItem("3", name, Item(reinterpret_cast<voidfuncptr>(fun)), (Struct *)p); }
00711
00712 void Evaluator::setFunction(const char * name,
00713 double (*fun)(double,double,double,double))
00714 { setItem("4", name, Item(reinterpret_cast<voidfuncptr>(fun)), (Struct *)p); }
00715
00716 void Evaluator::setFunction(const char * name,
00717 double (*fun)(double,double,double,double,double))
00718 { setItem("5", name, Item(reinterpret_cast<voidfuncptr>(fun)), (Struct *)p); }
00719
00720
00721 bool Evaluator::findVariable(const char * name) const {
00722 if (name == 0 || *name == '\0') return false;
00723 const char * pointer; int n; REMOVE_BLANKS;
00724 if (n == 0) return false;
00725 Struct * s = (Struct *)(p);
00726 return
00727 ((s->theDictionary).find(string(pointer,n)) == (s->theDictionary).end()) ?
00728 false : true;
00729 }
00730
00731
00732 bool Evaluator::findFunction(const char * name, int npar) const {
00733 if (name == 0 || *name == '\0') return false;
00734 if (npar < 0 || npar > MAX_N_PAR) return false;
00735 const char * pointer; int n; REMOVE_BLANKS;
00736 if (n == 0) return false;
00737 Struct * s = (Struct *)(p);
00738 return ((s->theDictionary).find(sss[npar]+string(pointer,n)) ==
00739 (s->theDictionary).end()) ? false : true;
00740 }
00741
00742
00743 void Evaluator::removeVariable(const char * name) {
00744 if (name == 0 || *name == '\0') return;
00745 const char * pointer; int n; REMOVE_BLANKS;
00746 if (n == 0) return;
00747 Struct * s = (Struct *)(p);
00748 (s->theDictionary).erase(string(pointer,n));
00749 }
00750
00751
00752 void Evaluator::removeFunction(const char * name, int npar) {
00753 if (name == 0 || *name == '\0') return;
00754 if (npar < 0 || npar > MAX_N_PAR) return;
00755 const char * pointer; int n; REMOVE_BLANKS;
00756 if (n == 0) return;
00757 Struct * s = (Struct *)(p);
00758 (s->theDictionary).erase(sss[npar]+string(pointer,n));
00759 }
00760
00761
00762 void Evaluator::clear() {
00763 Struct * s = (Struct *) p;
00764 s->theDictionary.clear();
00765 s->theExpression = 0;
00766 s->thePosition = 0;
00767 s->theStatus = OK;
00768 s->theResult = 0.0;
00769 }
00770
00771
00772 }