Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/clhep/src/Evaluator.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /externals/clhep/src/Evaluator.cc (Version 11.3.0) and /externals/clhep/src/Evaluator.cc (Version 8.2.p1)


  1 // -*- C++ -*-                                      1 
  2 // -------------------------------------------    
  3                                                   
  4 #include "CLHEP/Evaluator/Evaluator.h"            
  5                                                   
  6 #include <iostream>                               
  7 #include <sstream>                                
  8 #include <string>                                 
  9 #include <cmath>  // for std::pow()               
 10 #include <stack>                                  
 11 #include <unordered_map>                          
 12 #include <string.h>                               
 13 #include <ctype.h>                                
 14 #include <errno.h>                                
 15 #include <stdlib.h> // for strtod()               
 16                                                   
 17 using std::string;                                
 18 using std::stack;                                 
 19                                                   
 20 //--------------------------------------------    
 21 // Fix non ISO C++ compliant cast from pointer    
 22 // to void*, which is a pointer to an object      
 23 typedef void (*voidfuncptr)();                    
 24 struct Item {                                     
 25   enum { UNKNOWN, VARIABLE, EXPRESSION, FUNCTI    
 26   double variable;                                
 27   string expression;                              
 28   // Fix non ISO C++ compliant cast from point    
 29   // to void*, which is a pointer to an object    
 30   //void   *function;                             
 31   voidfuncptr function;                           
 32                                                   
 33   Item()         : what(UNKNOWN),   variable(0    
 34   Item(double x) : what(VARIABLE),  variable(x    
 35   Item(string x) : what(EXPRESSION),variable(0    
 36   Item(voidfuncptr x) : what(FUNCTION),  varia    
 37 };                                                
 38                                                   
 39 using pchar = char *;                             
 40 using dic_type = std::unordered_map<string, It    
 41                                                   
 42 struct Struct {                                   
 43   dic_type theDictionary;                         
 44   pchar    theExpression;                         
 45   pchar    thePosition;                           
 46   int      theStatus;                             
 47   double   theResult;                             
 48 };                                                
 49                                                   
 50 //--------------------------------------------    
 51 #define EVAL HepTool::Evaluator                   
 52                                                   
 53 #define REMOVE_BLANKS \                           
 54 for(pointer=name;;pointer++) if (!isspace(*poi    
 55 for(n=(int)strlen(pointer);n>0;n--) if (!isspa    
 56                                                   
 57 #define SKIP_BLANKS                      \        
 58 for(;;pointer++) {                       \        
 59   c = (pointer > end) ? '\0' : *pointer; \        
 60   if (!isspace(c)) break;                \        
 61 }                                                 
 62                                                   
 63 #define EVAL_EXIT(STATUS,POSITION) endp = POSI    
 64 #define MAX_N_PAR 5                               
 65                                                   
 66 static const char sss[MAX_N_PAR+2] = "012345";    
 67                                                   
 68 enum { ENDL, LBRA, OR, AND, EQ, NE, GE, GT, LE    
 69        PLUS, MINUS, UNARY_PLUS, UNARY_MINUS, M    
 70                                                   
 71 static int engine(pchar, pchar, double &, pcha    
 72                                                   
 73 static int variable(const string & name, doubl    
 74         const dic_type & dictionary)              
 75 /*********************************************    
 76  *                                                
 77  * Name: variable                                 
 78  * Author: Evgeni Chernyaev                       
 79  *                                                
 80  * Function: Finds value of the variable.         
 81  *           This function is used by operand(    
 82  *                                                
 83  * Parameters:                                    
 84  *   name   - name of the variable.               
 85  *   result - value of the variable.              
 86  *   dictionary - dictionary of available vari    
 87  *                                                
 88  *********************************************    
 89 {                                                 
 90   dic_type::const_iterator iter = dictionary.f    
 91   if (iter == dictionary.end())                   
 92     return EVAL::ERROR_UNKNOWN_VARIABLE;          
 93   Item item = iter->second;                       
 94   switch (item.what) {                            
 95   case Item::VARIABLE:                            
 96     result = item.variable;                       
 97     return EVAL::OK;                              
 98   case Item::EXPRESSION: {                        
 99     pchar exp_begin = (char *)(item.expression    
100     pchar exp_end   = exp_begin + strlen(exp_b    
101     if (engine(exp_begin, exp_end, result, exp    
102       return EVAL::OK;                            
103     else                                          
104       return EVAL::ERROR_CALCULATION_ERROR;       
105   }                                               
106   default:                                        
107     return EVAL::ERROR_CALCULATION_ERROR;         
108   }                                               
109 }                                                 
110                                                   
111 static int function(const string & name, stack    
112         double & result, const dic_type & dict    
113 /*********************************************    
114  *                                                
115  * Name: function                                 
116  * Author: Evgeni Chernyaev                       
117  *                                                
118  * Function: Finds value of the function.         
119  *           This function is used by operand(    
120  *                                                
121  * Parameters:                                    
122  *   name   - name of the function.               
123  *   par    - stack of parameters.                
124  *   result - value of the function.              
125  *   dictionary - dictionary of available vari    
126  *                                                
127  *********************************************    
128 {                                                 
129   unsigned long npar = par.size();                
130   if (npar > MAX_N_PAR) return EVAL::ERROR_UNK    
131                                                   
132   dic_type::const_iterator iter = dictionary.f    
133   if (iter == dictionary.end()) return EVAL::E    
134   Item item = iter->second;                       
135                                                   
136   double pp[MAX_N_PAR] = {0.0};                   
137   for(unsigned long i=0; i<npar; ++i) { pp[i]     
138   errno = 0;                                      
139   if (item.function == 0)       return EVAL::E    
140   switch (npar) {                                 
141   case 0:                                         
142     result = ((double (*)())item.function)();     
143     break;                                        
144   case 1:                                         
145     result = ((double (*)(double))item.functio    
146     break;                                        
147   case 2:                                         
148     result = ((double (*)(double,double))item.    
149     break;                                        
150   case 3:                                         
151     result = ((double (*)(double,double,double    
152       (pp[2],pp[1],pp[0]);                        
153     break;                                        
154   case 4:                                         
155     result = ((double (*)(double,double,double    
156       (pp[3],pp[2],pp[1],pp[0]);                  
157     break;                                        
158   case 5:                                         
159     result = ((double (*)(double,double,double    
160       (pp[4],pp[3],pp[2],pp[1],pp[0]);            
161     break;                                        
162   }                                               
163   return (errno == 0) ? EVAL::OK : EVAL::ERROR    
164 }                                                 
165                                                   
166 static int operand(pchar begin, pchar end, dou    
167        pchar & endp, const dic_type & dictiona    
168 /*********************************************    
169  *                                                
170  * Name: operand                                  
171  * Author: Evgeni Chernyaev                       
172  *                                                
173  * Function: Finds value of the operand. The o    
174  *           a number or a variable or a funct    
175  *           This function is used by engine()    
176  *                                                
177  * Parameters:                                    
178  *   begin  - pointer to the first character o    
179  *   end    - pointer to the last character of    
180  *   result - value of the operand.               
181  *   endp   - pointer to the character where t    
182  *   dictionary - dictionary of available vari    
183  *                                                
184  *********************************************    
185 {                                                 
186   pchar pointer = begin;                          
187   int   EVAL_STATUS;                              
188   char  c;                                        
189                                                   
190   //   G E T   N U M B E R                        
191                                                   
192   if (!isalpha(*pointer)) {                       
193     errno = 0;                                    
194     result = strtod(pointer, (char **)(&pointe    
195     if (errno == 0) {                             
196       EVAL_EXIT( EVAL::OK, --pointer );           
197     }else{                                        
198       EVAL_EXIT( EVAL::ERROR_CALCULATION_ERROR    
199     }                                             
200   }                                               
201                                                   
202   //   G E T   N A M E                            
203                                                   
204   while(pointer <= end) {                         
205     c = *pointer;                                 
206     if (c != '_' && !isalnum(c)) break;           
207     pointer++;                                    
208   }                                               
209   c = *pointer;                                   
210   *pointer = '\0';                                
211   string name(begin);                             
212   *pointer = c;                                   
213                                                   
214   //   G E T   V A R I A B L E                    
215                                                   
216   result = 0.0;                                   
217   SKIP_BLANKS;                                    
218   if (c != '(') {                                 
219     EVAL_STATUS = variable(name, result, dicti    
220     EVAL_EXIT( EVAL_STATUS, (EVAL_STATUS == EV    
221   }                                               
222                                                   
223   //   G E T   F U N C T I O N                    
224                                                   
225   stack<pchar>  pos;                // positio    
226   stack<double> par;                // paramet    
227   double        value;                            
228   pchar         par_begin = pointer+1, par_end    
229                                                   
230   for(;;pointer++) {                              
231     c = (pointer > end) ? '\0' : *pointer;        
232     switch (c) {                                  
233     case '\0':                                    
234       EVAL_EXIT( EVAL::ERROR_UNPAIRED_PARENTHE    
235     case '(':                                     
236       pos.push(pointer); break;                   
237     case ',':                                     
238       if (pos.size() == 1) {                      
239   par_end = pointer-1;                            
240   EVAL_STATUS = engine(par_begin, par_end, val    
241   if (EVAL_STATUS == EVAL::WARNING_BLANK_STRIN    
242     { EVAL_EXIT( EVAL::ERROR_EMPTY_PARAMETER,     
243   if (EVAL_STATUS != EVAL::OK)                    
244     { EVAL_EXIT( EVAL_STATUS, par_end ); }        
245   par.push(value);                                
246   par_begin = pointer + 1;                        
247       }                                           
248       break;                                      
249     case ')':                                     
250       if (pos.size() > 1) {                       
251   pos.pop();                                      
252   break;                                          
253       }else{                                      
254   par_end = pointer-1;                            
255   EVAL_STATUS = engine(par_begin, par_end, val    
256   switch (EVAL_STATUS) {                          
257   case EVAL::OK:                                  
258     par.push(value);                              
259     break;                                        
260   case EVAL::WARNING_BLANK_STRING:                
261     if (par.size() != 0)                          
262       { EVAL_EXIT( EVAL::ERROR_EMPTY_PARAMETER    
263     break;                                        
264   default:                                        
265     EVAL_EXIT( EVAL_STATUS, par_end );            
266   }                                               
267   EVAL_STATUS = function(name, par, result, di    
268   EVAL_EXIT( EVAL_STATUS, (EVAL_STATUS == EVAL    
269       }                                           
270     }                                             
271   }                                               
272 }                                                 
273                                                   
274 /*********************************************    
275  *                                                
276  * Name: maker                                    
277  * Author: Evgeni Chernyaev                       
278  *                                                
279  * Function: Executes basic arithmetic operati    
280  *           of the stack. Result is placed ba    
281  *           This function is used by engine()    
282  *                                                
283  * Parameters:                                    
284  *   op  - code of the operation.                 
285  *   val - stack of values.                       
286  *                                                
287  *********************************************    
288 static int maker(int op, stack<double> & val)     
289 {                                                 
290   if (val.size() < 2) return EVAL::ERROR_SYNTA    
291   double val2 = val.top(); val.pop();             
292   double val1 = val.top();                        
293   switch (op) {                                   
294   case OR:                                // o    
295     val.top() = (val1 || val2) ? 1. : 0.;         
296     return EVAL::OK;                              
297   case AND:                               // o    
298     val.top() = (val1 && val2) ? 1. : 0.;         
299     return EVAL::OK;                              
300   case EQ:                                // o    
301     val.top() = (val1 == val2) ? 1. : 0.;         
302     return EVAL::OK;                              
303   case NE:                                // o    
304     val.top() = (val1 != val2) ? 1. : 0.;         
305     return EVAL::OK;                              
306   case GE:                                // o    
307     val.top() = (val1 >= val2) ? 1. : 0.;         
308     return EVAL::OK;                              
309   case GT:                                // o    
310     val.top() = (val1 >  val2) ? 1. : 0.;         
311     return EVAL::OK;                              
312   case LE:                                // o    
313     val.top() = (val1 <= val2) ? 1. : 0.;         
314     return EVAL::OK;                              
315   case LT:                                // o    
316     val.top() = (val1 <  val2) ? 1. : 0.;         
317     return EVAL::OK;                              
318   case PLUS:                              // o    
319     val.top() = val1 + val2;                      
320     return EVAL::OK;                              
321   case MINUS:                             // o    
322     val.top() = val1 - val2;                      
323     return EVAL::OK;                              
324   case MULT:                              // o    
325     val.top() = val1 * val2;                      
326     return EVAL::OK;                              
327   case DIV:                               // o    
328     if (val2 == 0.0) return EVAL::ERROR_CALCUL    
329     val.top() = val1 / val2;                      
330     return EVAL::OK;                              
331   case POW:                               // o    
332     errno = 0;                                    
333     val.top() = std::pow(val1,val2);              
334     if (errno == 0) return EVAL::OK;              
335     else return EVAL::ERROR_CALCULATION_ERROR;    
336   case UNARY_PLUS:                                
337     val.top() = val1 + val2;      // val1 is z    
338     return EVAL::OK;                              
339   case UNARY_MINUS:                               
340     val.top() = val1 - val2;      // val1 is z    
341     return EVAL::OK;                              
342   default:                                        
343     return EVAL::ERROR_CALCULATION_ERROR;         
344   }                                               
345 }                                                 
346                                                   
347 /*********************************************    
348  *                                                
349  * Name: engine                                   
350  * Author: Evgeni Chernyaev                       
351  *                                                
352  * Function: Evaluates arithmetic expression.     
353  *                                                
354  * Parameters:                                    
355  *   begin  - pointer to the character string     
356  *   end    - pointer to the end of the charac    
357  *            for recursive call of engine(),     
358  *   result - result of the evaluation.           
359  *   endp   - pointer to the character where t    
360  *   dictionary - dictionary of available vari    
361  *                                                
362  *********************************************    
363 static int engine(pchar begin, pchar end, doub    
364       pchar & endp, const dic_type & dictionar    
365 {                                                 
366   enum SyntaxTableEntry {                         
367     SyntaxError = 0,                              
368     NumberVariableOrFunction = 1,                 
369     UnaryPlusOrMinus = 2,                         
370     AnyOperator = 3                               
371   };                                              
372   static const int SyntaxTable[19][19] = {        
373     //E  (  || && == != >= >  <= <  +  -  u+ u    
374     { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2    
375     { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2    
376     { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2    
377     { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2    
378     { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2    
379     { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2    
380     { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2    
381     { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2    
382     { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2    
383     { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2    
384     { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2    
385     { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2    
386     { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2    
387     { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2    
388     { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2    
389     { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2    
390     { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2    
391     { 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3    
392     { 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3    
393   };                                              
394   enum ActionTableEntry {                         
395     UnbalancedParentheses = -1,                   
396     ExpressionCompleted = 0,                      
397     HigherPrecedenceOperator = 1,                 
398     SamePrecedenceOperator = 2,                   
399     CloseProcessedParenthesesOrExpression = 3,    
400     LowerPrecedenceOperator = 4                   
401   };                                              
402   static const int ActionTable[17][18] = {        
403     //E  (  || && == != >= >  <= <  +  -  u+ u    
404     { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1    
405     {-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1    
406     { 4, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1    
407     { 4, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1    
408     { 4, 1, 4, 4, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1    
409     { 4, 1, 4, 4, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1    
410     { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1    
411     { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1    
412     { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1    
413     { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1    
414     { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 1, 1    
415     { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 1, 1    
416     { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1    
417     { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1    
418     { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1    
419     { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1    
420     { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1    
421   };                                              
422                                                   
423   stack<int>    op;                      // op    
424   stack<pchar>  pos;                     // po    
425   stack<double> val;                     // va    
426   double        value;                            
427   pchar         pointer = begin;                  
428   int           iWhat, iCur, iPrev = 0, iTop,     
429   char          c;                                
430                                                   
431   op.push(0); pos.push(pointer);         // pu    
432   SKIP_BLANKS;                                    
433   if (c == '\0') { EVAL_EXIT( EVAL::WARNING_BL    
434   for(;;pointer++) {                              
435                                                   
436     //   N E X T   T O K E N                      
437                                                   
438     c = (pointer > end) ? '\0' : *pointer;        
439     if (isspace(c)) continue;            // sk    
440     switch (c) {                                  
441     case '\0': iCur = ENDL; break;                
442     case '(':  iCur = LBRA; break;                
443     case '|':                                     
444       if (*(pointer+1) == '|') {                  
445   pointer++; iCur = OR; break;                    
446       }else{                                      
447         EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMB    
448       }                                           
449     case '&':                                     
450       if (*(pointer+1) == '&') {                  
451   pointer++; iCur = AND; break;                   
452       }else{                                      
453         EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMB    
454       }                                           
455     case '=':                                     
456       if (*(pointer+1) == '=') {                  
457   pointer++; iCur = EQ; break;                    
458       }else{                                      
459         EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMB    
460       }                                           
461     case '!':                                     
462       if (*(pointer+1) == '=') {                  
463   pointer++; iCur = NE; break;                    
464       }else{                                      
465         EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMB    
466       }                                           
467     case '>':                                     
468       if (*(pointer+1) == '=') { pointer++; iC    
469       break;                                      
470     case '<':                                     
471       if (*(pointer+1) == '=') { pointer++; iC    
472       break;                                      
473     case '+':  iCur = PLUS;  break;               
474     case '-':  iCur = MINUS; break;               
475     case '*':                                     
476       if (*(pointer+1) == '*') { pointer++; iC    
477       break;                                      
478     case '/':  iCur = DIV;  break;                
479     case '^':  iCur = POW;  break;                
480     case ')':  iCur = RBRA; break;                
481     default:                                      
482       if (c == '.' || isalnum(c)) {               
483         iCur = VALUE; break;                      
484       }else{                                      
485         EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMB    
486       }                                           
487     }                                             
488                                                   
489     //   S Y N T A X   A N A L I S Y S            
490                                                   
491     iWhat = SyntaxTable[iPrev][iCur];             
492     iPrev = iCur;                                 
493     switch (iWhat) {                              
494     case 0:                             // syn    
495       EVAL_EXIT( EVAL::ERROR_SYNTAX_ERROR, poi    
496     case 1:                             // ope    
497       EVAL_STATUS = operand(pointer, end, valu    
498       if (EVAL_STATUS != EVAL::OK) { EVAL_EXIT    
499       val.push(value);                            
500       continue;                                   
501     case 2:                             // una    
502       val.push(0.0);                              
503       if (iCur == PLUS)  iCur = UNARY_PLUS;       
504       if (iCur == MINUS) iCur = UNARY_MINUS;      
505       // Note that for syntax purposes, ordina    
506       // Thus iPrev need not change when we en    
507     case 3: default:                    // nex    
508       break;                                      
509     }                                             
510                                                   
511     //   N E X T   O P E R A T O R                
512                                                   
513     for(;;) {                                     
514       if (op.size() == 0) { EVAL_EXIT( EVAL::E    
515       iTop = op.top();                            
516       switch (ActionTable[iTop][iCur]) {          
517       case -1:                           // sy    
518   if (op.size() > 1) pointer = pos.top();         
519   EVAL_EXIT( EVAL::ERROR_UNPAIRED_PARENTHESIS,    
520       case 0:                            // la    
521         if (val.size() == 1) {                    
522     result = val.top();                           
523     EVAL_EXIT( EVAL::OK, pointer );               
524   }else{                                          
525     EVAL_EXIT( EVAL::ERROR_SYNTAX_ERROR, point    
526   }                                               
527       case 1:                           // pus    
528   op.push(iCur); pos.push(pointer);               
529   break;                                          
530       case 2:                           // exe    
531         EVAL_STATUS = maker(iTop, val); // put    
532         if (EVAL_STATUS != EVAL::OK) {            
533     EVAL_EXIT( EVAL_STATUS, pos.top() );          
534   }                                               
535   op.top() = iCur; pos.top() = pointer;           
536   break;                                          
537       case 3:                           // del    
538         op.pop(); pos.pop();                      
539   break;                                          
540       case 4: default:                  // exe    
541         EVAL_STATUS = maker(iTop, val); // del    
542         if (EVAL_STATUS != EVAL::OK) {  // rep    
543     EVAL_EXIT( EVAL_STATUS, pos.top() );          
544   }                                               
545   op.pop(); pos.pop();                            
546         continue;                                 
547       }                                           
548       break;                                      
549     }                                             
550   }                                               
551 }                                                 
552                                                   
553 //--------------------------------------------    
554 static void setItem(const char * prefix, const    
555         const Item & item, Struct * s) {          
556                                                   
557   if (name == 0 || *name == '\0') {               
558     s->theStatus = EVAL::ERROR_NOT_A_NAME;        
559     return;                                       
560   }                                               
561                                                   
562   //   R E M O V E   L E A D I N G   A N D   T    
563                                                   
564   const char * pointer; int n; REMOVE_BLANKS;     
565                                                   
566   //   C H E C K   N A M E                        
567                                                   
568   if (n == 0) {                                   
569     s->theStatus = EVAL::ERROR_NOT_A_NAME;        
570     return;                                       
571   }                                               
572   for(int i=0; i<n; i++) {                        
573     char c = *(pointer+i);                        
574     if (c != '_' && !isalnum(c)) {                
575       s->theStatus = EVAL::ERROR_NOT_A_NAME;      
576       return;                                     
577     }                                             
578   }                                               
579                                                   
580   //   A D D   I T E M   T O   T H E   D I C T    
581                                                   
582   string item_name = prefix + string(pointer,n    
583   dic_type::iterator iter = (s->theDictionary)    
584   if (iter != (s->theDictionary).end()) {         
585     iter->second = item;                          
586     if (item_name == name) {                      
587       s->theStatus = EVAL::WARNING_EXISTING_VA    
588     }else{                                        
589       s->theStatus = EVAL::WARNING_EXISTING_FU    
590     }                                             
591   }else{                                          
592     (s->theDictionary)[item_name] = item;         
593     s->theStatus = EVAL::OK;                      
594   }                                               
595 }                                                 
596                                                   
597 //--------------------------------------------    
598 namespace HepTool {                               
599                                                   
600 //--------------------------------------------    
601 Evaluator::Evaluator() {                          
602   Struct * s = new Struct();                      
603   p = (void *) s;                                 
604   s->theExpression = 0;                           
605   s->thePosition   = 0;                           
606   s->theStatus     = OK;                          
607   s->theResult     = 0.0;                         
608 }                                                 
609                                                   
610 //--------------------------------------------    
611 Evaluator::~Evaluator() {                         
612   delete (Struct *)(p);                           
613 }                                                 
614                                                   
615 //--------------------------------------------    
616 double Evaluator::evaluate(const char * expres    
617   Struct * s = (Struct *)(p);                     
618   if (s->theExpression != 0) { delete[] s->the    
619   s->theExpression = 0;                           
620   s->thePosition   = 0;                           
621   s->theStatus     = WARNING_BLANK_STRING;        
622   s->theResult     = 0.0;                         
623   if (expression != 0) {                          
624     s->theExpression = new char[strlen(express    
625     strcpy(s->theExpression, expression);         
626     s->theStatus = engine(s->theExpression,       
627         s->theExpression+strlen(expression)-1,    
628         s->theResult,                             
629         s->thePosition,                           
630         s->theDictionary);                        
631   }                                               
632   return s->theResult;                            
633 }                                                 
634                                                   
635 //--------------------------------------------    
636 int Evaluator::status() const {                   
637   return ((Struct *)(p))->theStatus;              
638 }                                                 
639                                                   
640 //--------------------------------------------    
641 int Evaluator::error_position() const {           
642   return int(((Struct *)(p))->thePosition - ((    
643 }                                                 
644                                                   
645 //--------------------------------------------    
646 void Evaluator::print_error() const {             
647   Struct * s = (Struct *) p;                      
648   if(s->theStatus != OK) {                        
649       std::cerr << error_name() << std::endl;     
650   }                                               
651   return;                                         
652 }                                                 
653                                                   
654 //--------------------------------------------    
655 std::string Evaluator::error_name() const         
656 {                                                 
657   char prefix[] = "Evaluator : ";                 
658   std::ostringstream errn;                        
659   Struct * s = (Struct *) p;                      
660   switch (s->theStatus) {                         
661   case ERROR_NOT_A_NAME:                          
662     errn << prefix << "invalid name";             
663     break;                                        
664   case ERROR_SYNTAX_ERROR:                        
665     errn << prefix << "syntax error";             
666     break;                                        
667   case ERROR_UNPAIRED_PARENTHESIS:                
668     errn << prefix << "unpaired parenthesis";     
669     break;                                        
670   case ERROR_UNEXPECTED_SYMBOL:                   
671     errn << prefix << "unexpected symbol";        
672     break;                                        
673   case ERROR_UNKNOWN_VARIABLE:                    
674     errn << prefix << "unknown variable";         
675     break;                                        
676   case ERROR_UNKNOWN_FUNCTION:                    
677     errn << prefix << "unknown function";         
678     break;                                        
679   case ERROR_EMPTY_PARAMETER:                     
680     errn << prefix << "empty parameter in func    
681     break;                                        
682   case ERROR_CALCULATION_ERROR:                   
683     errn << prefix << "calculation error";        
684     break;                                        
685   default:                                        
686     errn << " ";                                  
687   }                                               
688   return errn.str();                              
689 }                                                 
690                                                   
691 //--------------------------------------------    
692 void Evaluator::setVariable(const char * name,    
693 { setItem("", name, Item(value), (Struct *)p);    
694                                                   
695 void Evaluator::setVariable(const char * name,    
696 { setItem("", name, Item(expression), (Struct     
697                                                   
698 //--------------------------------------------    
699 // Fix non ISO C++ compliant cast from pointer    
700 // to void*, which is a pointer to an object      
701 void Evaluator::setFunction(const char * name,    
702           double (*fun)())                        
703 { setItem("0", name, Item(reinterpret_cast<voi    
704                                                   
705 void Evaluator::setFunction(const char * name,    
706           double (*fun)(double))                  
707 { setItem("1", name, Item(reinterpret_cast<voi    
708                                                   
709 void Evaluator::setFunction(const char * name,    
710           double (*fun)(double,double))           
711 { setItem("2", name, Item(reinterpret_cast<voi    
712                                                   
713 void Evaluator::setFunction(const char * name,    
714           double (*fun)(double,double,double))    
715 { setItem("3", name, Item(reinterpret_cast<voi    
716                                                   
717 void Evaluator::setFunction(const char * name,    
718           double (*fun)(double,double,double,d    
719 { setItem("4", name, Item(reinterpret_cast<voi    
720                                                   
721 void Evaluator::setFunction(const char * name,    
722           double (*fun)(double,double,double,d    
723 { setItem("5", name, Item(reinterpret_cast<voi    
724                                                   
725 //--------------------------------------------    
726 bool Evaluator::findVariable(const char * name    
727   if (name == 0 || *name == '\0') return false    
728   const char * pointer; int n; REMOVE_BLANKS;     
729   if (n == 0) return false;                       
730   Struct * s = (Struct *)(p);                     
731   return                                          
732     ((s->theDictionary).find(string(pointer,n)    
733     false : true;                                 
734 }                                                 
735                                                   
736 //--------------------------------------------    
737 bool Evaluator::findFunction(const char * name    
738   if (name == 0 || *name == '\0')    return fa    
739   if (npar < 0  || npar > MAX_N_PAR) return fa    
740   const char * pointer; int n; REMOVE_BLANKS;     
741   if (n == 0) return false;                       
742   Struct * s = (Struct *)(p);                     
743   return ((s->theDictionary).find(sss[npar]+st    
744     (s->theDictionary).end()) ? false : true;     
745 }                                                 
746                                                   
747 //--------------------------------------------    
748 void Evaluator::removeVariable(const char * na    
749   if (name == 0 || *name == '\0') return;         
750   const char * pointer; int n; REMOVE_BLANKS;     
751   if (n == 0) return;                             
752   Struct * s = (Struct *)(p);                     
753   (s->theDictionary).erase(string(pointer,n));    
754 }                                                 
755                                                   
756 //--------------------------------------------    
757 void Evaluator::removeFunction(const char * na    
758   if (name == 0 || *name == '\0')    return;      
759   if (npar < 0  || npar > MAX_N_PAR) return;      
760   const char * pointer; int n; REMOVE_BLANKS;     
761   if (n == 0) return;                             
762   Struct * s = (Struct *)(p);                     
763   (s->theDictionary).erase(sss[npar]+string(po    
764 }                                                 
765                                                   
766 //--------------------------------------------    
767 void Evaluator::clear() {                         
768   Struct * s = (Struct *) p;                      
769   s->theDictionary.clear();                       
770   s->theExpression = 0;                           
771   s->thePosition   = 0;                           
772   s->theStatus     = OK;                          
773   s->theResult     = 0.0;                         
774 }                                                 
775                                                   
776 //--------------------------------------------    
777 } // namespace HepTool                            
778