00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
00040 readIntegerNumberDecimal (value);
00041
00042
00043 char currentChar = *_ExprPtr;
00044 if (currentChar == '.')
00045 {
00046
00047 _ExprPtr++;
00048 currentChar = *_ExprPtr;
00049 if (currentChar < '0' || currentChar > '9')
00050 return NumberSyntaxError;
00051
00052
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
00068 register double regValue = 0;
00069
00070
00071 char currentChar = *_ExprPtr;
00072 if ((currentChar >= '0') && (currentChar <= '9'))
00073 {
00074 regValue += (currentChar - '0');
00075 _ExprPtr++;
00076 currentChar = *_ExprPtr;
00077
00078
00079 while ((currentChar >= '0') && (currentChar <= '9'))
00080 {
00081 regValue *= 10;
00082 regValue += (currentChar - '0');
00083
00084
00085 _ExprPtr++;
00086 currentChar = *_ExprPtr;
00087 }
00088 }
00089
00090
00091 value = regValue;
00092 }
00093
00094
00095
00096 CEvalNumExpr::TReturnState CEvalNumExpr::getNextToken (TToken &token)
00097 {
00098
00099 uint8 currentChar = *_ExprPtr;
00100
00101
00102 while ((currentChar!=0) && (currentChar<=0x20))
00103 {
00104 _ExprPtr++;
00105 currentChar = *_ExprPtr;
00106 }
00107
00108
00109 if (currentChar <= 128)
00110 {
00111
00112 _Op = _OperatorArray[currentChar];
00113
00114
00115 if (_Op != NotOperator)
00116 {
00117
00118 token = Operator;
00119
00120
00121 if (_Op != ExtOperator)
00122 {
00123
00124 _ExprPtr++;
00125 return NoError;
00126 }
00127 else
00128 {
00129
00130 char secondChar = *(_ExprPtr+1);
00131
00132
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
00254 return UnkownOperator;
00255 }
00256 }
00257
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
00282 else if ((currentChar >= '0') && (currentChar <= '9') || (currentChar == '.'))
00283 {
00284
00285 token = Number;
00286
00287
00288 char secondChar = *(_ExprPtr+1);
00289
00290
00291 if ((currentChar == '0') && (secondChar == 'x'))
00292 {
00293
00294 _ExprPtr +=2;
00295 currentChar = *_ExprPtr;
00296
00297
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
00314 return NumberSyntaxError;
00315 }
00316 _ExprPtr++;
00317 currentChar = *_ExprPtr;
00318
00319
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
00340 break;
00341 }
00342
00343
00344 _ExprPtr++;
00345 currentChar = *_ExprPtr;
00346 }
00347
00348
00349 _Value = regValue;
00350
00351
00352 return NoError;
00353 }
00354
00355 else if ((currentChar == '0') && (secondChar >= '0') && (secondChar <= '9'))
00356 {
00357
00358 _ExprPtr ++;
00359 currentChar = *_ExprPtr;
00360
00361
00362 register double regValue = 0;
00363
00364
00365 if (currentChar > '7')
00366 return NumberSyntaxError;
00367
00368
00369 regValue += (currentChar - '0');
00370 _ExprPtr++;
00371 currentChar = *_ExprPtr;
00372
00373
00374 while ((currentChar >= '0') && (currentChar <= '9'))
00375 {
00376
00377 if (currentChar > '7')
00378 return NumberSyntaxError;
00379
00380 regValue *= 8;
00381 regValue += (currentChar - '0');
00382
00383
00384 _ExprPtr++;
00385 currentChar = *_ExprPtr;
00386 }
00387
00388
00389 _Value = regValue;
00390
00391
00392 return NoError;
00393 }
00394
00395 else
00396 {
00397
00398 TReturnState state = readDecimal (_Value);
00399 if (state == NoError)
00400 {
00401
00402 currentChar = *_ExprPtr;
00403 if ( (currentChar == 'e') || (currentChar == 'E') )
00404 {
00405
00406 _ExprPtr++;
00407
00408
00409 bool negative = false;
00410 if (*_ExprPtr == '-')
00411 {
00412 negative = true;
00413 _ExprPtr++;
00414 }
00415
00416
00417 double exponent;
00418 state = readDecimal (exponent);
00419 if (state == NoError)
00420 {
00421
00422 if (negative)
00423 exponent = -exponent;
00424
00425
00426 _Value *= pow (10.0, exponent);
00427 }
00428 else
00429 {
00430 return state;
00431 }
00432 }
00433
00434
00435 return NoError;
00436 }
00437 else
00438 {
00439 return state;
00440 }
00441 }
00442 }
00443
00444 else if (currentChar == '"')
00445 {
00446
00447 _ExprPtr++;
00448 currentChar = *_ExprPtr;
00449 const char *start = _ExprPtr;
00450 while ( (currentChar != 0) && (currentChar != '"') )
00451 {
00452 _ExprPtr++;
00453 currentChar = *_ExprPtr;
00454 }
00455
00456
00457 if (currentChar == 0)
00458 return MustBeDoubleQuote;
00459
00460
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
00478 _ExprPtr++;
00479 token = String;
00480 return NoError;
00481 }
00482 }
00483
00484
00485 const char *start = _ExprPtr;
00486 while ( (currentChar >= 128) || _StringChar[currentChar] )
00487 {
00488 _ExprPtr++;
00489 currentChar = *_ExprPtr;
00490 }
00491
00492
00493 if (((_ExprPtr - start) == 2) && (start[0] == 'p') && (start[1] == 'i'))
00494 {
00495 token = Number;
00496 _Value = 3.1415926535897932384626433832795;
00497 return NoError;
00498 }
00499
00500 else if (((_ExprPtr - start) == 1) && (start[0] == 'e'))
00501 {
00502 token = Number;
00503 _Value = 2.7182818284590452353602874713527;
00504 return NoError;
00505 }
00506
00507
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
00525 uint begin = 0;
00526 uint end = ReservedWordCount-1;
00527 sint result = strcmp (_InternalStringPtr, _ReservedWord[begin]);
00528 if ( result >= 0 )
00529 {
00530
00531 if ( result == 0 )
00532 {
00533 end = begin;
00534 }
00535
00536 result = strcmp (_InternalStringPtr, _ReservedWord[end]);
00537 if (result <= 0)
00538 {
00539
00540 if ( result == 0 )
00541 {
00542 begin = end;
00543 }
00544
00545
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
00568 if (end == begin)
00569 {
00570
00571 _ReservedWordFound = (TReservedWord)begin;
00572 token = _ReservedWordToken[begin];
00573
00574
00575 return NoError;
00576 }
00577 }
00578
00579
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
00590 _ExprPtr = expression;
00591
00592 TToken nextToken;
00593 TReturnState error = evalExpression (result, nextToken, userData);
00594 if (error == NoError)
00595 {
00596
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
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
00629 TReturnState error = getNextToken (nextToken);
00630 if (error != NoError)
00631 return error;
00632 while (1)
00633 {
00634
00635 uint unaryOpCount = 0;
00636 TOperator resultUnaryOp[InternalOperator];
00637 vector<TOperator> resultUnaryOpSup;
00638
00639
00640 double value;
00641
00642
00643 if ( (nextToken == Operator) && ( (_Op == Minus) || (_Op == Not) || (_Op == Tilde) ) )
00644 {
00645
00646 if (unaryOpCount<InternalOperator)
00647 resultUnaryOp[unaryOpCount] = _Op;
00648 else
00649 resultUnaryOpSup.push_back (_Op);
00650 unaryOpCount++;
00651
00652
00653 error = getNextToken (nextToken);
00654 if (error != NoError)
00655 return error;
00656 }
00657
00658
00659 if (nextToken == Open)
00660 {
00661
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
00672 error = getNextToken (nextToken);
00673 if (error != NoError)
00674 return error;
00675 }
00676
00677 else if ( (nextToken == Function1) || (nextToken == Function2) )
00678 {
00679 TToken backupedToken = nextToken;
00680
00681
00682 TReservedWord reservedWord = _ReservedWordFound;
00683
00684
00685 error = getNextToken (nextToken);
00686 if (error == NoError)
00687 {
00688
00689 if (nextToken != Open)
00690 {
00691 return MustBeOpen;
00692 }
00693
00694
00695 double arg0;
00696 error = evalExpression (arg0, nextToken, userData);
00697 if (error == NoError)
00698 {
00699
00700 if (backupedToken == Function2)
00701 {
00702 if (nextToken == Coma)
00703 {
00704
00705 double arg1;
00706 error = evalExpression (arg1, nextToken, userData);
00707 if (error == NoError)
00708 {
00709
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
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
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
00822 nlstop
00823 }
00824 }
00825 else
00826 return MustBeClose;
00827 }
00828 }
00829 else
00830 return error;
00831 }
00832 else
00833 return error;
00834
00835
00836 error = getNextToken (nextToken);
00837 if (error != NoError)
00838 return error;
00839 }
00840 else if (nextToken == Number)
00841 {
00842
00843 value = _Value;
00844
00845
00846 error = getNextToken (nextToken);
00847 if (error != NoError)
00848 return error;
00849 }
00850 else if (nextToken == String)
00851 {
00852
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
00868 error = getNextToken (nextToken);
00869 if (error == NoError)
00870 {
00871
00872 if (nextToken == Open)
00873 {
00874
00875 double arg0;
00876 error = evalExpression (arg0, nextToken, userData);
00877 if (error == NoError)
00878 {
00879 if (nextToken == Coma)
00880 {
00881
00882 double arg1;
00883 error = evalExpression (arg1, nextToken, userData);
00884 if (error == NoError)
00885 {
00886
00887 if (nextToken == Close)
00888 {
00889
00890 error = evalFunction (internalStringPtr, arg0, arg1, value);
00891 if (error != NoError)
00892 return error;
00893
00894
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
00910 error = evalFunction (internalStringPtr, arg0, value);
00911 if (error != NoError)
00912 return error;
00913
00914
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
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
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
00959 nlstop
00960 }
00961 }
00962
00963
00964 if (exprCount < InternalOperator)
00965 result[exprCount] = value;
00966 else
00967 resultSup.push_back (value);
00968 exprCount++;
00969
00970
00971
00972 if (nextToken == Operator)
00973 {
00974
00975 if (opCount < InternalOperator)
00976 resultOp[opCount] = _Op;
00977 else
00978 resultOpSup.push_back (_Op);
00979 opCount++;
00980 }
00981 else
00982 {
00983
00984 break;
00985 }
00986
00987
00988 error = getNextToken (nextToken);
00989 }
00990
00991
00992 uint index = 1;
00993 while (exprCount != 1)
00994 {
00995
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
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
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
01082 uint i = index;
01083 for (; i<exprCount-1; i++)
01084 {
01085
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
01094 i = index-1;
01095 for (; i<opCount-1; i++)
01096 {
01097
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
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
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
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",
01200 "acos",
01201 "asin",
01202 "atan",
01203 "atan2",
01204 "ceil",
01205 "cos",
01206 "cosh",
01207 "exp",
01208 "exponent",
01209 "floor",
01210 "int",
01211 "log",
01212 "log10",
01213 "mantissa",
01214 "max",
01215 "min",
01216 "pow",
01217 "rand",
01218 "round",
01219 "sin",
01220 "sinh",
01221 "sq",
01222 "sqrt",
01223 "tan",
01224 "tanh",
01225 };
01226
01227
01228
01229 const CEvalNumExpr::TToken CEvalNumExpr::_ReservedWordToken[ReservedWordCount] =
01230 {
01231 Function1,
01232 Function1,
01233 Function1,
01234 Function1,
01235 Function2,
01236 Function1,
01237 Function1,
01238 Function1,
01239 Function1,
01240 Function1,
01241 Function1,
01242 Function1,
01243 Function1,
01244 Function1,
01245 Function1,
01246 Function2,
01247 Function2,
01248 Function2,
01249 Function2,
01250 Function1,
01251 Function1,
01252 Function1,
01253 Function1,
01254 Function1,
01255 Function1,
01256 Function1,
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,
01291 0,
01292 1,
01293 1,
01294 1,
01295 2,
01296 2,
01297 3,
01298 3,
01299 3,
01300 3,
01301 4,
01302 4,
01303 4,
01304 4,
01305 5,
01306 5,
01307 6,
01308 7,
01309 8,
01310 9,
01311 10,
01312 11,
01313 0xffffffff,
01314 20,
01315 };
01316
01317
01318
01319 }