From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/eval__num__expr_8cpp-source.html | 1388 +++++++++++++++++++++ 1 file changed, 1388 insertions(+) create mode 100644 docs/doxygen/nel/eval__num__expr_8cpp-source.html (limited to 'docs/doxygen/nel/eval__num__expr_8cpp-source.html') diff --git a/docs/doxygen/nel/eval__num__expr_8cpp-source.html b/docs/doxygen/nel/eval__num__expr_8cpp-source.html new file mode 100644 index 00000000..d84d6662 --- /dev/null +++ b/docs/doxygen/nel/eval__num__expr_8cpp-source.html @@ -0,0 +1,1388 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# Home   # nevrax.com   
+ + + + +
Nevrax
+ + + + + + + + + + +
+ + +
+ Nevrax.org
+ + + + + + + +
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
+
+ + +
+ + +
+Docs + +
+  + + + + + +
Documentation 
+ +
+Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  
+

eval_num_expr.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2000, 2001 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NeL Network Services.
+00010  * NEVRAX NeL Network Services is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NeL Network Services is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NeL Network Services; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+00024  */
+00025 
+00026 #include "stdmisc.h"
+00027 
+00028 #include "nel/misc/eval_num_expr.h"
+00029 
+00030 namespace NLMISC
+00031 {
+00032 
+00033 using namespace std;
+00034 
+00035 // ***************************************************************************
+00036 
+00037 CEvalNumExpr::TReturnState CEvalNumExpr::readDecimal (double &value)
+00038 {
+00039         // Read first integer value
+00040         readIntegerNumberDecimal (value);
+00041 
+00042         // Dot ?
+00043         char currentChar = *_ExprPtr;
+00044         if (currentChar == '.')
+00045         {
+00046                 // Next char
+00047                 _ExprPtr++;
+00048                 currentChar = *_ExprPtr;
+00049                 if (currentChar < '0' || currentChar > '9')
+00050                         return NumberSyntaxError;
+00051 
+00052                 // Read the decimal part
+00053                 const char *start = _ExprPtr;
+00054                 double fract;
+00055                 readIntegerNumberDecimal (fract);
+00056                 fract /= (double)pow (10 ,(_ExprPtr-start));
+00057                 value += fract;
+00058         }
+00059 
+00060         return NoError;
+00061 }
+00062 
+00063 // ***************************************************************************
+00064 
+00065 void CEvalNumExpr::readIntegerNumberDecimal (double &value)
+00066 {
+00067         // Registered values
+00068         register double regValue = 0;
+00069 
+00070         // Read the first value
+00071         char currentChar = *_ExprPtr;
+00072         if ((currentChar >= '0') && (currentChar <= '9'))
+00073         {
+00074                 regValue += (currentChar - '0');
+00075                 _ExprPtr++;
+00076                 currentChar = *_ExprPtr;
+00077 
+00078                 // For each values
+00079                 while ((currentChar >= '0') && (currentChar <= '9'))
+00080                 {
+00081                         regValue *= 10;
+00082                         regValue += (currentChar - '0');
+00083 
+00084                         // Next char
+00085                         _ExprPtr++;
+00086                         currentChar = *_ExprPtr;
+00087                 }
+00088         }
+00089         
+00090         // Store value
+00091         value = regValue;
+00092 }
+00093 
+00094 // ***************************************************************************
+00095 
+00096 CEvalNumExpr::TReturnState CEvalNumExpr::getNextToken (TToken &token)
+00097 {
+00098         // Get the current char
+00099         uint8 currentChar = *_ExprPtr;
+00100 
+00101         // Skip space
+00102         while ((currentChar!=0) && (currentChar<=0x20))
+00103         {
+00104                 _ExprPtr++;
+00105                 currentChar = *_ExprPtr;
+00106         }
+00107 
+00108         // Can be an operator ?
+00109         if (currentChar <= 128)
+00110         {
+00111                 // Get the operator
+00112                 _Op = _OperatorArray[currentChar];
+00113 
+00114                 // Is an operator ?
+00115                 if (_Op != NotOperator)
+00116                 {
+00117                         // It is an operator
+00118                         token = Operator;
+00119 
+00120                         // Is a 2 characters operator ?
+00121                         if (_Op != ExtOperator)
+00122                         {
+00123                                 // Return next character
+00124                                 _ExprPtr++;
+00125                                 return NoError;
+00126                         }
+00127                         else
+00128                         {
+00129                                 // Have a second character ?
+00130                                 char secondChar = *(_ExprPtr+1);
+00131 
+00132                                 // What kind of 1st character
+00133                                 switch (currentChar)
+00134                                 {
+00135                                 case '!':
+00136                                         if (secondChar == '=')
+00137                                         {
+00138                                                 _Op = NotEqual;
+00139                                                 _ExprPtr+=2;
+00140                                                 return NoError;
+00141                                         }
+00142                                         else
+00143                                         {
+00144                                                 _Op = Not;
+00145                                                 _ExprPtr++;
+00146                                                 return NoError;
+00147                                         }
+00148                                 case '&':
+00149                                         if (secondChar == '&')
+00150                                         {
+00151                                                 _Op = LogicalAnd;
+00152                                                 _ExprPtr+=2;
+00153                                                 return NoError;
+00154                                         }
+00155                                         else
+00156                                         {
+00157                                                 _Op = And;
+00158                                                 _ExprPtr+=1;
+00159                                                 return NoError;
+00160                                         }
+00161                                 case '-':
+00162                                         if (secondChar == '>')
+00163                                         {
+00164                                                 _Op = SRightShift;
+00165                                                 _ExprPtr+=2;
+00166                                                 return NoError;
+00167                                         }
+00168                                         else
+00169                                         {
+00170                                                 _Op = Minus;
+00171                                                 _ExprPtr++;
+00172                                                 return NoError;
+00173                                         }
+00174                                 case '<':
+00175                                         if (secondChar == '<')
+00176                                         {
+00177                                                 _Op = ULeftShift;
+00178                                                 _ExprPtr+=2;
+00179                                                 return NoError;
+00180                                         }
+00181                                         else if (secondChar == '=')
+00182                                         {
+00183                                                 _Op = InferiorEqual;
+00184                                                 _ExprPtr+=2;
+00185                                                 return NoError;
+00186                                         }
+00187                                         else if (secondChar == '-')
+00188                                         {
+00189                                                 _Op = SLeftShift;
+00190                                                 _ExprPtr+=2;
+00191                                                 return NoError;
+00192                                         }
+00193                                         else
+00194                                         {
+00195                                                 _Op = Inferior;
+00196                                                 _ExprPtr+=1;
+00197                                                 return NoError;
+00198                                         }
+00199                                 case '=':
+00200                                         if (secondChar == '=')
+00201                                         {
+00202                                                 _Op = Equal;
+00203                                                 _ExprPtr+=2;
+00204                                                 return NoError;
+00205                                         }
+00206                                 case '>':
+00207                                         if (secondChar == '>')
+00208                                         {
+00209                                                 _Op = URightShift;
+00210                                                 _ExprPtr+=2;
+00211                                                 return NoError;
+00212                                         }
+00213                                         else if (secondChar == '=')
+00214                                         {
+00215                                                 _Op = SuperiorEqual;
+00216                                                 _ExprPtr+=2;
+00217                                                 return NoError;
+00218                                         }
+00219                                         else
+00220                                         {
+00221                                                 _Op = Superior;
+00222                                                 _ExprPtr+=1;
+00223                                                 return NoError;
+00224                                         }
+00225                                 case '^':
+00226                                         if (secondChar == '^')
+00227                                         {
+00228                                                 _Op = LogicalXor;
+00229                                                 _ExprPtr+=2;
+00230                                                 return NoError;
+00231                                         }
+00232                                         else
+00233                                         {
+00234                                                 _Op = Xor;
+00235                                                 _ExprPtr+=1;
+00236                                                 return NoError;
+00237                                         }
+00238                                 case '|':
+00239                                         if (secondChar == '|')
+00240                                         {
+00241                                                 _Op = LogicalOr;
+00242                                                 _ExprPtr+=2;
+00243                                                 return NoError;
+00244                                         }
+00245                                         else
+00246                                         {
+00247                                                 _Op = Or;
+00248                                                 _ExprPtr+=1;
+00249                                                 return NoError;
+00250                                         }
+00251                                 }
+00252 
+00253                                 // Can't found the operator
+00254                                 return UnkownOperator;
+00255                         }
+00256                 }
+00257                 // Is End, '(', ')', '.' ?
+00258                 else if (currentChar == 0)
+00259                 {
+00260                         token = End;
+00261                         return NoError;
+00262                 }
+00263                 else if (currentChar == '(')
+00264                 {
+00265                         _ExprPtr++;
+00266                         token = Open;
+00267                         return NoError;
+00268                 }
+00269                 else if (currentChar == ')')
+00270                 {
+00271                         _ExprPtr++;
+00272                         token = Close;
+00273                         return NoError;
+00274                 }
+00275                 else if (currentChar == ',')
+00276                 {
+00277                         _ExprPtr++;
+00278                         token = Coma;
+00279                         return NoError;
+00280                 }
+00281                 // Is a number ?
+00282                 else if ((currentChar >= '0') && (currentChar <= '9') || (currentChar == '.'))
+00283                 {
+00284                         // This is a number
+00285                         token = Number;
+00286 
+00287                         // Have a second character ?
+00288                         char secondChar = *(_ExprPtr+1);
+00289 
+00290                         // Is an hexadecimal value ?
+00291                         if ((currentChar == '0') && (secondChar == 'x'))
+00292                         {
+00293                                 // Go to the number
+00294                                 _ExprPtr +=2;
+00295                                 currentChar = *_ExprPtr;
+00296 
+00297                                 // Registered values
+00298                                 register double regValue = 0;
+00299                                 if ((currentChar >= '0') && (currentChar <= '9'))
+00300                                 {
+00301                                         regValue += (currentChar - '0');
+00302                                 }
+00303                                 else if ((currentChar >= 'a') && (currentChar <= 'f'))
+00304                                 {
+00305                                         regValue += (currentChar - 'a' + 10);
+00306                                 }
+00307                                 else if ((currentChar >= 'A') && (currentChar <= 'F'))
+00308                                 {
+00309                                         regValue += (currentChar - 'A' + 10);
+00310                                 }
+00311                                 else
+00312                                 {
+00313                                         // Number syntax error
+00314                                         return NumberSyntaxError;
+00315                                 }
+00316                                 _ExprPtr++;
+00317                                 currentChar = *_ExprPtr;
+00318 
+00319                                 // For each values
+00320                                 while (1)
+00321                                 {
+00322                                         if ((currentChar >= '0') && (currentChar <= '9'))
+00323                                         {
+00324                                                 regValue *= 16;
+00325                                                 regValue += (currentChar - '0');
+00326                                         }
+00327                                         else if ((currentChar >= 'a') && (currentChar <= 'f'))
+00328                                         {
+00329                                                 regValue *= 16;
+00330                                                 regValue += (currentChar - 'a' + 10);
+00331                                         }
+00332                                         else if ((currentChar >= 'A') && (currentChar <= 'F'))
+00333                                         {
+00334                                                 regValue *= 16;
+00335                                                 regValue += (currentChar - 'A' + 10);
+00336                                         }
+00337                                         else
+00338                                         {
+00339                                                 // Stop
+00340                                                 break;
+00341                                         }
+00342 
+00343                                         // Next char
+00344                                         _ExprPtr++;
+00345                                         currentChar = *_ExprPtr;
+00346                                 }
+00347                                 
+00348                                 // Store value
+00349                                 _Value = regValue;
+00350 
+00351                                 // Number ok
+00352                                 return NoError;
+00353                         }
+00354                         // Is an octal value ?
+00355                         else if ((currentChar == '0') && (secondChar >= '0') && (secondChar <= '9'))
+00356                         {
+00357                                 // Go to the number
+00358                                 _ExprPtr ++;
+00359                                 currentChar = *_ExprPtr;
+00360 
+00361                                 // Registered values
+00362                                 register double regValue = 0;
+00363 
+00364                                 // Check octal number
+00365                                 if (currentChar > '7')
+00366                                         return NumberSyntaxError;
+00367 
+00368                                 // Read the first value
+00369                                 regValue += (currentChar - '0');
+00370                                 _ExprPtr++;
+00371                                 currentChar = *_ExprPtr;
+00372 
+00373                                 // For each values
+00374                                 while ((currentChar >= '0') && (currentChar <= '9'))
+00375                                 {
+00376                                         // Check octal number
+00377                                         if (currentChar > '7')
+00378                                                 return NumberSyntaxError;
+00379 
+00380                                         regValue *= 8;
+00381                                         regValue += (currentChar - '0');
+00382 
+00383                                         // Next char
+00384                                         _ExprPtr++;
+00385                                         currentChar = *_ExprPtr;
+00386                                 }
+00387                                 
+00388                                 // Store value
+00389                                 _Value = regValue;
+00390 
+00391                                 // Number ok
+00392                                 return NoError;
+00393                         }
+00394                         // It is a decimal value
+00395                         else
+00396                         {
+00397                                 // Read value
+00398                                 TReturnState state = readDecimal (_Value);
+00399                                 if (state == NoError)
+00400                                 {
+00401                                         // Exponent ?
+00402                                         currentChar = *_ExprPtr;
+00403                                         if ( (currentChar == 'e') || (currentChar == 'E') )
+00404                                         {
+00405                                                 // Next char
+00406                                                 _ExprPtr++;
+00407 
+00408                                                 // Minus ?
+00409                                                 bool negative = false;
+00410                                                 if (*_ExprPtr == '-')
+00411                                                 {
+00412                                                         negative = true;
+00413                                                         _ExprPtr++;
+00414                                                 }
+00415 
+00416                                                 // Read value
+00417                                                 double exponent;
+00418                                                 state = readDecimal (exponent);
+00419                                                 if (state == NoError)
+00420                                                 {
+00421                                                         // Negative value ?
+00422                                                         if (negative)
+00423                                                                 exponent = -exponent;
+00424 
+00425                                                         // Raise 10 at the power of
+00426                                                         _Value *= pow (10.0, exponent);
+00427                                                 }
+00428                                                 else
+00429                                                 {
+00430                                                         return state;
+00431                                                 }
+00432                                         }
+00433 
+00434                                         // Number ok
+00435                                         return NoError;
+00436                                 }
+00437                                 else
+00438                                 {
+00439                                         return state;
+00440                                 }
+00441                         }
+00442                 }
+00443                 // Is a string ?
+00444                 else if (currentChar == '"')
+00445                 {
+00446                         // Look for the end of the string
+00447                         _ExprPtr++;
+00448                         currentChar = *_ExprPtr;
+00449                         const char *start = _ExprPtr;
+00450                         while ( (currentChar != 0) && (currentChar != '"') )
+00451                         {
+00452                                 _ExprPtr++;
+00453                                 currentChar = *_ExprPtr;
+00454                         }
+00455                         
+00456                         // End reached ?
+00457                         if (currentChar == 0)
+00458                                 return MustBeDoubleQuote;
+00459 
+00460                         // This is a user string, copy the string
+00461                         uint size = _ExprPtr - start;
+00462                         if (size >= (InternalStringLen-1))
+00463                         {
+00464                                 _InternalStlString.resize (size);
+00465                                 uint i;
+00466                                 for (i=0; i<size; i++)
+00467                                         _InternalStlString[i] = start[i];
+00468                                 _InternalStringPtr = _InternalStlString.c_str ();
+00469                         }
+00470                         else
+00471                         {
+00472                                 memcpy (_InternalString, start, size);
+00473                                 _InternalString[size] = 0;
+00474                                 _InternalStringPtr = _InternalString;
+00475                         }
+00476 
+00477                         // Token
+00478                         _ExprPtr++;
+00479                         token = String;
+00480                         return NoError;
+00481                 }
+00482         }
+00483 
+00484         // Read a string
+00485         const char *start = _ExprPtr;
+00486         while ( (currentChar >= 128) || _StringChar[currentChar] )
+00487         {
+00488                 _ExprPtr++;
+00489                 currentChar = *_ExprPtr;
+00490         }
+00491 
+00492         // Is pi ?
+00493         if (((_ExprPtr - start) == 2) && (start[0] == 'p') && (start[1] == 'i'))
+00494         {
+00495                 token = Number;
+00496                 _Value = 3.1415926535897932384626433832795;
+00497                 return NoError;
+00498         }
+00499         // Is e ?
+00500         else if (((_ExprPtr - start) == 1) && (start[0] == 'e'))
+00501         {
+00502                 token = Number;
+00503                 _Value = 2.7182818284590452353602874713527;
+00504                 return NoError;
+00505         }
+00506 
+00507         // This is a user string, copy the string
+00508         uint size = _ExprPtr - start;
+00509         if (size >= (InternalStringLen-1))
+00510         {
+00511                 _InternalStlString.resize (size);
+00512                 uint i;
+00513                 for (i=0; i<size; i++)
+00514                         _InternalStlString[i] = start[i];
+00515                 _InternalStringPtr = _InternalStlString.c_str ();
+00516         }
+00517         else
+00518         {
+00519                 memcpy (_InternalString, start, size);
+00520                 _InternalString[size] = 0;
+00521                 _InternalStringPtr = _InternalString;
+00522         }
+00523 
+00524         // Search for a reserved word ?
+00525         uint begin = 0;
+00526         uint end = ReservedWordCount-1;
+00527         sint result = strcmp (_InternalStringPtr, _ReservedWord[begin]);
+00528         if ( result >= 0 )
+00529         {
+00530                 // The first is the good ?
+00531                 if ( result == 0 )
+00532                 {
+00533                         end = begin;
+00534                 }
+00535 
+00536                 result = strcmp (_InternalStringPtr, _ReservedWord[end]);
+00537                 if (result <= 0)
+00538                 {
+00539                         // The last is the good ?
+00540                         if ( result == 0 )
+00541                         {
+00542                                 begin = end;
+00543                         }
+00544 
+00545                         // While there is a middle..
+00546                         while ((end - begin) > 1)
+00547                         {
+00548                                 uint middle = begin + (end - begin) / 2;
+00549                                 result = strcmp (_InternalStringPtr, _ReservedWord[middle]);
+00550                                 if (result == 0)
+00551                                 {
+00552                                         begin = middle;
+00553                                         end = middle;
+00554                                         break;
+00555                                 }
+00556                                 else if (result < 0)
+00557                                 {
+00558                                         end = middle;
+00559                                 }
+00560                                 else
+00561                                 {
+00562                                         begin = middle;
+00563                                 }
+00564                         }
+00565                 }
+00566 
+00567                 // Found ?
+00568                 if (end == begin)
+00569                 {
+00570                         // Return the token
+00571                         _ReservedWordFound = (TReservedWord)begin;
+00572                         token = _ReservedWordToken[begin];
+00573 
+00574                         // Ok
+00575                         return NoError;
+00576                 }
+00577         }
+00578 
+00579         // Token
+00580         token = String;
+00581         return NoError;
+00582 }
+00583 
+00584 // ***************************************************************************
+00585 
+00586 CEvalNumExpr::TReturnState CEvalNumExpr::evalExpression (const char *expression, double &result, 
+00587                                                                                                                  int *errorIndex, uint32 userData)
+00588 {
+00589         // Init the ptr
+00590         _ExprPtr = expression;
+00591 
+00592         TToken nextToken;
+00593         TReturnState error = evalExpression (result, nextToken, userData);
+00594         if (error == NoError)
+00595         {
+00596                 // The end ?
+00597                 if (nextToken == End)
+00598                         return NoError;
+00599                 else
+00600                 {
+00601                         if (errorIndex)
+00602                                 *errorIndex = _ExprPtr - expression;
+00603                         return MustBeEnd;
+00604                 }
+00605         }
+00606         else
+00607         {
+00608                 if (errorIndex)
+00609                         *errorIndex = _ExprPtr - expression;
+00610                 return error;
+00611         }
+00612 }
+00613 
+00614 // ***************************************************************************
+00615 
+00616 CEvalNumExpr::TReturnState CEvalNumExpr::evalExpression (double &finalResult, TToken &nextToken, uint32 userData)
+00617 {
+00618         // Array of result
+00619 
+00620         uint exprCount = 0;
+00621         double result[InternalOperator];
+00622         vector<double> resultSup;
+00623 
+00624         uint opCount = 0;
+00625         TOperator resultOp[InternalOperator];
+00626         vector<TOperator> resultOpSup;
+00627 
+00628         // Read a token
+00629         TReturnState error = getNextToken (nextToken);
+00630         if (error != NoError)
+00631                 return error;
+00632         while (1)
+00633         {
+00634                 // Unary opertor
+00635                 uint unaryOpCount = 0;
+00636                 TOperator resultUnaryOp[InternalOperator];
+00637                 vector<TOperator> resultUnaryOpSup;
+00638                 
+00639                 // Current value
+00640                 double value;
+00641 
+00642                 // Unary operator ?
+00643                 if ( (nextToken == Operator) && ( (_Op == Minus) || (_Op == Not) || (_Op == Tilde) ) )
+00644                 {
+00645                         // Push the unary operator
+00646                         if (unaryOpCount<InternalOperator)
+00647                                 resultUnaryOp[unaryOpCount] = _Op;
+00648                         else
+00649                                 resultUnaryOpSup.push_back (_Op);
+00650                         unaryOpCount++;
+00651 
+00652                         // Read next token
+00653                         error = getNextToken (nextToken);
+00654                         if (error != NoError)
+00655                                 return error;
+00656                 }
+00657 
+00658                 // Parenthesis ?
+00659                 if (nextToken == Open)
+00660                 {
+00661                         // Eval sub expression
+00662                         error = evalExpression (value, nextToken, userData);
+00663                         if (error == NoError)
+00664                         {
+00665                                 if (nextToken != Close)
+00666                                         return MustBeClose;
+00667                         }       
+00668                         else
+00669                                 return error;
+00670 
+00671                         // Get next token
+00672                         error = getNextToken (nextToken);
+00673                         if (error != NoError)
+00674                                 return error;
+00675                 }
+00676                 // This is a function ?
+00677                 else if ( (nextToken == Function1) || (nextToken == Function2) )
+00678                 {
+00679                         TToken backupedToken = nextToken;
+00680 
+00681                         // Get the function
+00682                         TReservedWord reservedWord = _ReservedWordFound;
+00683 
+00684                         // Read a token
+00685                         error = getNextToken (nextToken);
+00686                         if (error == NoError)
+00687                         {
+00688                                 // Open ?
+00689                                 if (nextToken != Open)
+00690                                 {
+00691                                         return MustBeOpen;
+00692                                 }
+00693 
+00694                                 // Eval an expression
+00695                                 double arg0;
+00696                                 error = evalExpression (arg0, nextToken, userData);
+00697                                 if (error == NoError)
+00698                                 {
+00699                                         // 2 arg ?
+00700                                         if (backupedToken == Function2)
+00701                                         {
+00702                                                 if (nextToken == Coma)
+00703                                                 {
+00704                                                         // Second argument
+00705                                                         double arg1;
+00706                                                         error = evalExpression (arg1, nextToken, userData);
+00707                                                         if (error == NoError)
+00708                                                         {
+00709                                                                 // Final with close ?
+00710                                                                 if (nextToken == Close)
+00711                                                                 {
+00712                                                                         switch (reservedWord)
+00713                                                                         {
+00714                                                                         case Atan2:
+00715                                                                                 value = atan2 (arg0, arg1);
+00716                                                                                 break;
+00717                                                                         case Max:
+00718                                                                                 value = (arg0>arg1) ? arg0 : arg1;
+00719                                                                                 break;
+00720                                                                         case Min:
+00721                                                                                 value = (arg0<arg1) ? arg0 : arg1;
+00722                                                                                 break;
+00723                                                                         case Pow:
+00724                                                                                 value = pow (arg0, arg1);
+00725                                                                                 break;
+00726                                                                         case Rand:
+00727                                                                                 value = arg0 + (arg1-arg0) * (double)rand () / (double)(RAND_MAX+1);
+00728                                                                                 break;
+00729                                                                         default:
+00730                                                                                 // Can't be hear after getToken
+00731                                                                                 nlstop;
+00732                                                                         }                                                                               
+00733                                                                 }
+00734                                                                 else
+00735                                                                         return MustBeClose;
+00736                                                         }
+00737                                                         else
+00738                                                                 return error;
+00739                                                 }
+00740                                                 else
+00741                                                         return MustBeComa;
+00742                                         }
+00743                                         else
+00744                                         {
+00745                                                 if (nextToken == Close)
+00746                                                 {
+00747                                                         // Eval the function
+00748                                                         switch (reservedWord)
+00749                                                         {
+00750                                                         case Abs:
+00751                                                                 value = fabs (arg0);
+00752                                                                 break;
+00753                                                         case Acos:
+00754                                                                 value = acos (arg0);
+00755                                                                 break;
+00756                                                         case Asin:
+00757                                                                 value = asin (arg0);
+00758                                                                 break;
+00759                                                         case Atan:
+00760                                                                 value = atan (arg0);
+00761                                                                 break;
+00762                                                         case Ceil:
+00763                                                                 value = ceil (arg0);
+00764                                                                 break;
+00765                                                         case Cosh:
+00766                                                                 value = cosh (arg0);
+00767                                                                 break;
+00768                                                         case Cos:
+00769                                                                 value = cos (arg0);
+00770                                                                 break;
+00771                                                         case Exponent:
+00772                                                                 {
+00773                                                                         int exponent;
+00774                                                                         frexp( arg0, &exponent);
+00775                                                                         value = (double)exponent;
+00776                                                                 }
+00777                                                                 break;
+00778                                                         case Exp:
+00779                                                                 value = exp (arg0);
+00780                                                                 break;
+00781                                                         case Floor:
+00782                                                                 value = floor (arg0);
+00783                                                                 break;
+00784                                                         case Int:
+00785                                                                 value = (double)(int)(arg0);
+00786                                                                 break;
+00787                                                         case Log10:
+00788                                                                 value = log10 (arg0);
+00789                                                                 break;
+00790                                                         case Log:
+00791                                                                 value = log (arg0);
+00792                                                                 break;
+00793                                                         case Mantissa:
+00794                                                                 {
+00795                                                                         int exponent;
+00796                                                                         value = frexp( arg0, &exponent);
+00797                                                                 }
+00798                                                                 break;
+00799                                                         case Round:
+00800                                                                 value = floor (arg0 + 0.5);
+00801                                                                 break;
+00802                                                         case Sinh:
+00803                                                                 value = sinh (arg0);
+00804                                                                 break;
+00805                                                         case Sin:
+00806                                                                 value = sin (arg0);
+00807                                                                 break;
+00808                                                         case Sqrt:
+00809                                                                 value = sqrt (arg0);
+00810                                                                 break;
+00811                                                         case Sq:
+00812                                                                 value = arg0 * arg0;
+00813                                                                 break;
+00814                                                         case Tanh:
+00815                                                                 value = tanh (arg0);
+00816                                                                 break;
+00817                                                         case Tan:
+00818                                                                 value = tan (arg0);
+00819                                                                 break;
+00820                                                         default:
+00821                                                                 // Can't be hear after getToken
+00822                                                                 nlstop
+00823                                                         }
+00824                                                 }
+00825                                                 else
+00826                                                         return MustBeClose;
+00827                                         }
+00828                                 }
+00829                                 else
+00830                                         return error;
+00831                         }
+00832                         else
+00833                                 return error;
+00834 
+00835                         // Get next token
+00836                         error = getNextToken (nextToken);
+00837                         if (error != NoError)
+00838                                 return error;
+00839                 }
+00840                 else if (nextToken == Number)
+00841                 {
+00842                         // Save the internal value
+00843                         value = _Value;
+00844 
+00845                         // Get next token
+00846                         error = getNextToken (nextToken);
+00847                         if (error != NoError)
+00848                                 return error;
+00849                 }
+00850                 else if (nextToken == String)
+00851                 {
+00852                         // Copy the string
+00853                         char                    internalString[InternalStringLen];
+00854                         std::string             internalStlString;
+00855                         const char              *internalStringPtr;
+00856                         if (strlen (_InternalStringPtr) >= InternalStringLen-1)
+00857                         {
+00858                                 internalStlString = _InternalStringPtr;
+00859                                 internalStringPtr = internalStlString.c_str ();
+00860                         }
+00861                         else
+00862                         {
+00863                                 strcpy (internalString ,_InternalStringPtr);
+00864                                 internalStringPtr = internalString;
+00865                         }
+00866 
+00867                         // Read a token
+00868                         error = getNextToken (nextToken);
+00869                         if (error == NoError)
+00870                         {
+00871                                 // Open ?
+00872                                 if (nextToken == Open)
+00873                                 {
+00874                                         // Eval an expression
+00875                                         double arg0;
+00876                                         error = evalExpression (arg0, nextToken, userData);
+00877                                         if (error == NoError)
+00878                                         {
+00879                                                 if (nextToken == Coma)
+00880                                                 {
+00881                                                         // Second argument
+00882                                                         double arg1;
+00883                                                         error = evalExpression (arg1, nextToken, userData);
+00884                                                         if (error == NoError)
+00885                                                         {
+00886                                                                 // Final with close ?
+00887                                                                 if (nextToken == Close)
+00888                                                                 {
+00889                                                                         // Eval the function
+00890                                                                         error = evalFunction (internalStringPtr, arg0, arg1, value);
+00891                                                                         if (error != NoError)
+00892                                                                                 return error;
+00893 
+00894                                                                         // Get next token
+00895                                                                         error = getNextToken (nextToken);
+00896                                                                         if (error != NoError)
+00897                                                                                 return error;
+00898                                                                 }
+00899                                                                 else
+00900                                                                         return MustBeClose;
+00901                                                         }
+00902                                                         else
+00903                                                                 return error;
+00904                                                 }
+00905                                                 else
+00906                                                 {
+00907                                                         if (nextToken == Close)
+00908                                                         {
+00909                                                                 // Eval the function
+00910                                                                 error = evalFunction (internalStringPtr, arg0, value);
+00911                                                                 if (error != NoError)
+00912                                                                         return error;
+00913 
+00914                                                                 // Get next token
+00915                                                                 error = getNextToken (nextToken);
+00916                                                                 if (error != NoError)
+00917                                                                         return error;
+00918                                                         }
+00919                                                         else
+00920                                                                 return MustBeClose;
+00921                                                 }
+00922                                         }
+00923                                         else
+00924                                                 return error;
+00925                                 }
+00926                                 else
+00927                                 {
+00928                                         // This is a user value
+00929                                         error = evalValue (internalStringPtr, value, userData);
+00930                                         if (error != NoError)
+00931                                                 return error;
+00932                                 }
+00933                         }
+00934                         else
+00935                                 return error;
+00936                 }
+00937                 else
+00938                 {
+00939                         return MustBeExpression;
+00940                 }
+00941 
+00942                 // Eval unary operator
+00943                 sint i;
+00944                 for (i=unaryOpCount-1; i>=0; i--)
+00945                 {
+00946                         switch ((i<InternalOperator)?resultUnaryOp[i]:resultUnaryOpSup[i-InternalOperator])
+00947                         {
+00948                         case Not:
+00949                                 value = (double)(uint)((floor (value+0.5)==0.0));
+00950                                 break;
+00951                         case Tilde:
+00952                                 value = (double)~((uint)floor (value+0.5));
+00953                                 break;
+00954                         case Minus:
+00955                                 value = -value;
+00956                                 break;
+00957                         default:
+00958                                 // Can't be hear after getToken
+00959                                 nlstop
+00960                         }
+00961                 }
+00962 
+00963                 // Push the value
+00964                 if (exprCount < InternalOperator)
+00965                         result[exprCount] = value;
+00966                 else
+00967                         resultSup.push_back (value);
+00968                 exprCount++;
+00969 
+00970                 // Look for an operator
+00971                 // Operator ?
+00972                 if (nextToken == Operator)
+00973                 {
+00974                         // Yes, push it
+00975                         if (opCount < InternalOperator)
+00976                                 resultOp[opCount] = _Op;
+00977                         else
+00978                                 resultOpSup.push_back (_Op);
+00979                         opCount++;
+00980                 }
+00981                 else 
+00982                 {
+00983                         // Exit the evaluate loop
+00984                         break;
+00985                 }
+00986 
+00987                 // Next token
+00988                 error = getNextToken (nextToken);
+00989         }
+00990 
+00991         // Reduce the expression
+00992         uint index = 1;
+00993         while (exprCount != 1)
+00994         {
+00995                 // Reduct ?
+00996                 TOperator before = (((index-1)<InternalOperator)?resultOp[index-1]:resultOpSup[index-1-InternalOperator]);
+00997                 TOperator after = (index < opCount)?(((index)<InternalOperator)?resultOp[index]:resultOpSup[index-InternalOperator]):NotOperator;
+00998                 if ((index == opCount) || (_OperatorPrecedence[before] <= _OperatorPrecedence[after]))
+00999                 {
+01000                         // Eval the value
+01001                         double &v0 = ((index-1)<InternalOperator)?result[index-1]:resultSup[index-1-InternalOperator];
+01002                         double &v1 = ((index)<InternalOperator)?result[index]:resultSup[index-InternalOperator];
+01003 
+01004                         // Choose the operator
+01005                         switch (before)
+01006                         {
+01007                         case Not:
+01008                         case Tilde:
+01009                                 return NotUnaryOperator;
+01010                         case Mul:
+01011                                 v0 *= v1;
+01012                                 break;
+01013                         case Div:
+01014                                 v0 /= v1;
+01015                                 break;
+01016                         case Remainder:
+01017                                 v0 = fmod (v0, v1);
+01018                                 break;
+01019                         case Plus:
+01020                                 v0 += v1;
+01021                                 break;
+01022                         case Minus:
+01023                                 v0 -= v1;
+01024                                 break;
+01025                         case ULeftShift:
+01026                                 v0 = (double)(((uint)floor (v0 + 0.5))<<((uint)floor (v1 + 0.5)));
+01027                                 break;
+01028                         case URightShift:
+01029                                 v0 = (double)(((uint)floor (v0 + 0.5))>>((uint)floor (v1 + 0.5)));
+01030                                 break;
+01031                         case SLeftShift:
+01032                                 v0 = (double)(((sint)floor (v0 + 0.5))<<((sint)floor (v1 + 0.5)));
+01033                                 break;
+01034                         case SRightShift:
+01035                                 v0 = (double)(((sint)floor (v0 + 0.5))>>((sint)floor (v1 + 0.5)));
+01036                                 break;
+01037                         case Inferior:
+01038                                 v0 = (v0<v1)?1.0:0.0;
+01039                                 break;
+01040                         case InferiorEqual:
+01041                                 v0 = (v0<=v1)?1.0:0.0;
+01042                                 break;
+01043                         case Superior:
+01044                                 v0 = (v0>v1)?1.0:0.0;
+01045                                 break;
+01046                         case SuperiorEqual:
+01047                                 v0 = (v0>=v1)?1.0:0.0;
+01048                                 break;
+01049                         case Equal:
+01050                                 v0 = (v0==v1)?1.0:0.0;
+01051                                 break;
+01052                         case NotEqual:
+01053                                 v0 = (v0!=v1)?1.0:0.0;
+01054                                 break;
+01055                         case And:
+01056                                 v0 = (double)(((uint)floor (v0 + 0.5)) & ((uint)floor (v1 + 0.5)));
+01057                                 break;
+01058                         case Or:
+01059                                 v0 = (double)(((uint)floor (v0 + 0.5)) | ((uint)floor (v1 + 0.5)));
+01060                                 break;
+01061                         case Xor:
+01062                                 v0 = (double)(((uint)floor (v0 + 0.5)) ^ ((uint)floor (v1 + 0.5)));
+01063                                 break;
+01064                         case LogicalAnd:
+01065                                 v0 = (double)(uint)((floor (v0 + 0.5) != 0.0) && (floor (v1 + 0.5) != 0.0));
+01066                                 break;
+01067                         case LogicalOr:
+01068                                 v0 = (double)(uint)((floor (v0 + 0.5) != 0.0) || (floor (v1 + 0.5) != 0.0));
+01069                                 break;
+01070                         case LogicalXor:
+01071                                 {
+01072                                         bool b0 = floor (v0 + 0.5) != 0.0;
+01073                                         bool b1 = floor (v1 + 0.5) != 0.0;
+01074                                         v0 = (double)(uint)((b0&&!b1) || ((!b0)&&b1));
+01075                                 }
+01076                                 break;
+01077                         default:
+01078                                 nlassert (0);
+01079                         }
+01080 
+01081                         // Decal others values
+01082                         uint i = index;
+01083                         for (; i<exprCount-1; i++)
+01084                         {
+01085                                 // Copy
+01086                                 if (i<InternalOperator)
+01087                                         result[i] = (i+1<InternalOperator)?result[i+1]:resultSup[i+1-InternalOperator];
+01088                                 else 
+01089                                         resultSup[i-InternalOperator] = (i+1<InternalOperator)?result[i+1]:resultSup[i+1-InternalOperator];
+01090                         }
+01091                         exprCount--;
+01092 
+01093                         // Decal operators
+01094                         i = index-1;
+01095                         for (; i<opCount-1; i++)
+01096                         {
+01097                                 // Copy
+01098                                 if (i<InternalOperator)
+01099                                         resultOp[i] = (i+1<InternalOperator)?resultOp[i+1]:resultOpSup[i+1-InternalOperator];
+01100                                 else 
+01101                                         resultOpSup[i-InternalOperator] = (i+1<InternalOperator)?resultOp[i+1]:resultOpSup[i+1-InternalOperator];
+01102                                         
+01103                         }
+01104                         opCount--;
+01105 
+01106                         // Last one ?
+01107                         if (index > 1)
+01108                                 index--;
+01109                 }
+01110                 else
+01111                         index++;
+01112         }
+01113 
+01114         finalResult = result[0];
+01115         return NoError;
+01116 }
+01117 
+01118 // ***************************************************************************
+01119 
+01120 bool CEvalNumExpr::internalCheck ()
+01121 {
+01122         for (uint i=0; i<ReservedWordCount-1; i++)
+01123                 if (strcmp (_ReservedWord[i], _ReservedWord[i+1]) >= 0)
+01124                 {
+01125                         nlassert (0);
+01126                         return false;
+01127                 }
+01128         return true;
+01129 }
+01130 
+01131 // ***************************************************************************
+01132 
+01133 // ASCII TABLE
+01134 
+01135 /*
+01136 0 NUL   SOH             STX             ETX             EOT             ENQ             ACK             BEL             BS              TAB             LF              VT              FF              CR              SO              SI 
+01137 1 DLE   DC1             DC2             DC3             DC4             NAK             SYN             ETB             CAN             EM              SUB             ESC             FS              GS              RS              US 
+01138 2               !               "               #               $               %               &               '               (               )               *               +               ,               -               .               / 
+01139 3 0             1               2               3               4               5               6               7               8               9               :               ;               <               =               >               ? 
+01140 4 @             A               B               C               D               E               F               G               H               I               J               K               L               M               N               O 
+01141 5 P             Q               R               S               T               U               V               W               X               Y               Z               [               \               ]               ^               _ 
+01142 6 `             a               b               c               d               e               f               g               h               i               j               k               l               m               n               o 
+01143 7 p             q               r               s               t               u               v               w               x               y               z               {               |               }               ~
+01144 */
+01145 
+01146 // ***************************************************************************
+01147 
+01148 const CEvalNumExpr::TOperator   CEvalNumExpr::_OperatorArray[128] = 
+01149 {
+01150         NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator,
+01151         NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator,
+01152         NotOperator, ExtOperator, NotOperator, NotOperator, NotOperator, Remainder,   ExtOperator, NotOperator, NotOperator, NotOperator, Mul,             Plus,                NotOperator, ExtOperator, NotOperator, Div,
+01153         NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, ExtOperator, ExtOperator, ExtOperator, NotOperator,
+01154         NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator,
+01155         NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, ExtOperator, NotOperator,
+01156         NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator,
+01157         NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, ExtOperator, NotOperator, Tilde,       NotOperator,
+01158 };
+01159 
+01160 // ***************************************************************************
+01161 
+01162 const bool CEvalNumExpr::_StringChar[128] = 
+01163 {
+01164         false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
+01165         false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
+01166         false, false, true,  true,  true,  false, false, true,  false, false, false, false, false, false, false, false,
+01167         true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  false, false, false, true,
+01168         true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,
+01169         true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  false,  true,
+01170         true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,
+01171         true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  true,  false, true,  false, true,
+01172 };
+01173 
+01174 // ***************************************************************************
+01175 
+01176 CEvalNumExpr::TReturnState CEvalNumExpr::evalValue (const char *value, double &result, uint32 userData)
+01177 {
+01178         return UnkownValue;
+01179 }
+01180 
+01181 // ***************************************************************************
+01182 
+01183 CEvalNumExpr::TReturnState CEvalNumExpr::evalFunction (const char *funcName, double arg0, double &result)
+01184 {
+01185         return UnkownFunction;
+01186 }
+01187 
+01188 // ***************************************************************************
+01189 
+01190 CEvalNumExpr::TReturnState CEvalNumExpr::evalFunction (const char *funcName, double arg0, double arg1, double &result)
+01191 {
+01192         return UnkownFunction;
+01193 }
+01194 
+01195 // ***************************************************************************
+01196 
+01197 const char *CEvalNumExpr::_ReservedWord[ReservedWordCount] =
+01198 {
+01199         "abs", // Abs
+01200         "acos", // Acos
+01201         "asin", // Asin
+01202         "atan", // Atan
+01203         "atan2", // Atan2
+01204         "ceil", // Ceil
+01205         "cos",  // Cos
+01206         "cosh", // Cosh
+01207         "exp", // Exp
+01208         "exponent", // Exponent
+01209         "floor", // Floor
+01210         "int", // Int
+01211         "log", // Log
+01212         "log10", // Log10
+01213         "mantissa", // Mantissa
+01214         "max", // Max
+01215         "min", // Min
+01216         "pow", // Pow
+01217         "rand", // Rand
+01218         "round", // Round
+01219         "sin", // Sin
+01220         "sinh", // Sinh
+01221         "sq", // Sq
+01222         "sqrt", // Sqrt
+01223         "tan", // Tan
+01224         "tanh", // Tanh
+01225 };
+01226 
+01227 // ***************************************************************************
+01228 
+01229 const CEvalNumExpr::TToken CEvalNumExpr::_ReservedWordToken[ReservedWordCount] =
+01230 {
+01231         Function1, // Abs
+01232         Function1, // Acos
+01233         Function1, // Asin
+01234         Function1, // Atan
+01235         Function2, // Atan2
+01236         Function1, // Ceil
+01237         Function1, // Cos
+01238         Function1, // Cosh
+01239         Function1, // Exp
+01240         Function1, // Exponent
+01241         Function1, // Floor
+01242         Function1, // Int
+01243         Function1, // Log
+01244         Function1, // Log10
+01245         Function1, // Mantissa
+01246         Function2, // Max
+01247         Function2, // Min
+01248         Function2, // Pow
+01249         Function2, // Rand
+01250         Function1, // Round
+01251         Function1, // Sin
+01252         Function1, // Sinh
+01253         Function1, // Sq
+01254         Function1, // Sqrt
+01255         Function1, // Tan
+01256         Function1, // Tanh
+01257 };
+01258 
+01259 // ***************************************************************************
+01260 
+01261 const char *CEvalNumExpr::_ErrorString[ReturnValueCount]=
+01262 {
+01263         "No error",
+01264         "Unkown value",
+01265         "Error during user defined value evaluation",
+01266         "Unkown function",
+01267         "Error during user defined function evaluation",
+01268         "Syntax error in a number expression",
+01269         "Unkown operator",
+01270         "Should be a open parentesis",
+01271         "Should be a close parentesis",
+01272         "Should be a coma character",
+01273         "Should be an expression",
+01274         "Should not be an unary operator",
+01275         "Should be the end of the expression",
+01276         "Should be a double quote",
+01277 };
+01278 
+01279 // ***************************************************************************
+01280 
+01281 const char* CEvalNumExpr::getErrorString (TReturnState state) const
+01282 {
+01283         return _ErrorString[state];
+01284 }
+01285 
+01286 // ***************************************************************************
+01287 
+01288 const int CEvalNumExpr::_OperatorPrecedence[]=
+01289 {
+01290         0,      // Not
+01291         0,      // Tilde
+01292         1,      // Mul
+01293         1,      // Div
+01294         1,      // Remainder
+01295         2,      // Plus
+01296         2,      // Minus
+01297         3,      // ULeftShift
+01298         3,      // URightShift
+01299         3,      // SLeftShift
+01300         3,      // SRightShift
+01301         4,      // Inferior
+01302         4,      // InferiorEqual
+01303         4,      // Superior
+01304         4,      // SuperiorEqual
+01305         5,      // Equal
+01306         5,      // NotEqual
+01307         6,      // And
+01308         7,      // Or
+01309         8,      // Xor
+01310         9,      // LogicalAnd
+01311         10,     // LogicalOr
+01312         11,     // LogicalXor
+01313         0xffffffff,     // OperatorCount
+01314         20,     // NotOperator
+01315 };
+01316 
+01317 // ***************************************************************************
+01318 
+01319 }
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1