Linux multi-monitor fullscreen support
[ryzomcore.git] / nel / src / misc / eval_num_expr.cpp
blob8cde36a48e1289086ad3e3a9ca2dadcf10a9b654
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2016-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "stdmisc.h"
22 #include "nel/misc/eval_num_expr.h"
23 #include "nel/misc/debug.h"
25 #ifdef DEBUG_NEW
26 #define new DEBUG_NEW
27 #endif
29 namespace NLMISC
32 using namespace std;
34 // ***************************************************************************
36 CEvalNumExpr::TReturnState CEvalNumExpr::readDecimal (double &value)
38 // Read first integer value
39 readIntegerNumberDecimal (value);
41 // Dot ?
42 char currentChar = *_ExprPtr;
43 if (currentChar == '.')
45 // Next char
46 _ExprPtr++;
47 currentChar = *_ExprPtr;
48 if (currentChar < '0' || currentChar > '9')
49 return NumberSyntaxError;
51 // Read the decimal part
52 const char *start = _ExprPtr;
53 double fract;
54 readIntegerNumberDecimal (fract);
55 fract /= (double)pow (10.0,(sint)(_ExprPtr-start));
56 value += fract;
59 return NoError;
62 // ***************************************************************************
64 void CEvalNumExpr::readIntegerNumberDecimal (double &value)
66 // Registered values
67 register double regValue = 0;
69 // Read the first value
70 char currentChar = *_ExprPtr;
71 if ((currentChar >= '0') && (currentChar <= '9'))
73 regValue += (currentChar - '0');
74 _ExprPtr++;
75 currentChar = *_ExprPtr;
77 // For each values
78 while ((currentChar >= '0') && (currentChar <= '9'))
80 regValue *= 10;
81 regValue += (currentChar - '0');
83 // Next char
84 _ExprPtr++;
85 currentChar = *_ExprPtr;
89 // Store value
90 value = regValue;
93 // ***************************************************************************
95 CEvalNumExpr::TReturnState CEvalNumExpr::getNextToken (TToken &token)
97 // Get the current char
98 uint8 currentChar = *_ExprPtr;
100 // Skip space
101 while ((currentChar!=0) && (currentChar<=0x20))
103 _ExprPtr++;
104 currentChar = *_ExprPtr;
107 // Can be an operator ?
108 if (currentChar <= 128)
110 // Get the operator
111 _Op = _OperatorArray[currentChar];
113 // Is an operator ?
114 if (_Op != NotOperator)
116 // It is an operator
117 token = Operator;
119 // Is a 2 characters operator ?
120 if (_Op != ExtOperator)
122 // Return next character
123 _ExprPtr++;
124 return NoError;
126 else
128 // Have a second character ?
129 char secondChar = *(_ExprPtr+1);
131 // What kind of 1st character
132 switch (currentChar)
134 case '!':
135 if (secondChar == '=')
137 _Op = NotEqual;
138 _ExprPtr+=2;
139 return NoError;
141 else
143 _Op = Not;
144 _ExprPtr++;
145 return NoError;
147 case '&':
148 if (secondChar == '&')
150 _Op = LogicalAnd;
151 _ExprPtr+=2;
152 return NoError;
154 else
156 _Op = And;
157 _ExprPtr+=1;
158 return NoError;
160 case '-':
161 if (secondChar == '>')
163 _Op = SRightShift;
164 _ExprPtr+=2;
165 return NoError;
167 else
169 _Op = Minus;
170 _ExprPtr++;
171 return NoError;
173 case '<':
174 if (secondChar == '<')
176 _Op = ULeftShift;
177 _ExprPtr+=2;
178 return NoError;
180 else if (secondChar == '=')
182 _Op = InferiorEqual;
183 _ExprPtr+=2;
184 return NoError;
186 else if (secondChar == '-')
188 _Op = SLeftShift;
189 _ExprPtr+=2;
190 return NoError;
192 else
194 _Op = Inferior;
195 _ExprPtr+=1;
196 return NoError;
198 case '=':
199 if (secondChar == '=')
201 _Op = Equal;
202 _ExprPtr+=2;
203 return NoError;
205 case '>':
206 if (secondChar == '>')
208 _Op = URightShift;
209 _ExprPtr+=2;
210 return NoError;
212 else if (secondChar == '=')
214 _Op = SuperiorEqual;
215 _ExprPtr+=2;
216 return NoError;
218 else
220 _Op = Superior;
221 _ExprPtr+=1;
222 return NoError;
224 case '^':
225 if (secondChar == '^')
227 _Op = LogicalXor;
228 _ExprPtr+=2;
229 return NoError;
231 else
233 _Op = Xor;
234 _ExprPtr+=1;
235 return NoError;
237 case '|':
238 if (secondChar == '|')
240 _Op = LogicalOr;
241 _ExprPtr+=2;
242 return NoError;
244 else
246 _Op = Or;
247 _ExprPtr+=1;
248 return NoError;
252 // Can't found the operator
253 return UnknownOperator;
256 // Is End, '(', ')', '.' ?
257 else if (currentChar == 0)
259 token = End;
260 return NoError;
262 else if (currentChar == '(')
264 _ExprPtr++;
265 token = Open;
266 return NoError;
268 else if (currentChar == ')')
270 _ExprPtr++;
271 token = Close;
272 return NoError;
274 else if (currentChar == ',')
276 _ExprPtr++;
277 token = Coma;
278 return NoError;
280 // Is a number ?
281 else if (((currentChar >= '0') && (currentChar <= '9')) || (currentChar == '.'))
283 // This is a number
284 token = Number;
286 // Have a second character ?
287 char secondChar = *(_ExprPtr+1);
289 // Is an hexadecimal value ?
290 if ((currentChar == '0') && (secondChar == 'x'))
292 // Go to the number
293 _ExprPtr +=2;
294 currentChar = *_ExprPtr;
296 // Registered values
297 register double regValue = 0;
298 if ((currentChar >= '0') && (currentChar <= '9'))
300 regValue += (currentChar - '0');
302 else if ((currentChar >= 'a') && (currentChar <= 'f'))
304 regValue += (currentChar - 'a' + 10);
306 else if ((currentChar >= 'A') && (currentChar <= 'F'))
308 regValue += (currentChar - 'A' + 10);
310 else
312 // Number syntax error
313 return NumberSyntaxError;
315 _ExprPtr++;
316 currentChar = *_ExprPtr;
318 // For each values
319 for(;;)
321 if ((currentChar >= '0') && (currentChar <= '9'))
323 regValue *= 16;
324 regValue += (currentChar - '0');
326 else if ((currentChar >= 'a') && (currentChar <= 'f'))
328 regValue *= 16;
329 regValue += (currentChar - 'a' + 10);
331 else if ((currentChar >= 'A') && (currentChar <= 'F'))
333 regValue *= 16;
334 regValue += (currentChar - 'A' + 10);
336 else
338 // Stop
339 break;
342 // Next char
343 _ExprPtr++;
344 currentChar = *_ExprPtr;
347 // Store value
348 _Value = regValue;
350 // Number ok
351 return NoError;
353 // Is an octal value ?
354 else if ((currentChar == '0') && (secondChar >= '0') && (secondChar <= '9'))
356 // Go to the number
357 _ExprPtr ++;
358 currentChar = *_ExprPtr;
360 // Registered values
361 register double regValue = 0;
363 // Check octal number
364 if (currentChar > '7')
365 return NumberSyntaxError;
367 // Read the first value
368 regValue += (currentChar - '0');
369 _ExprPtr++;
370 currentChar = *_ExprPtr;
372 // For each values
373 while ((currentChar >= '0') && (currentChar <= '9'))
375 // Check octal number
376 if (currentChar > '7')
377 return NumberSyntaxError;
379 regValue *= 8;
380 regValue += (currentChar - '0');
382 // Next char
383 _ExprPtr++;
384 currentChar = *_ExprPtr;
387 // Store value
388 _Value = regValue;
390 // Number ok
391 return NoError;
393 // It is a decimal value
394 else
396 // Read value
397 TReturnState state = readDecimal (_Value);
398 if (state == NoError)
400 // Exponent ?
401 currentChar = *_ExprPtr;
402 if ( (currentChar == 'e') || (currentChar == 'E') )
404 // Next char
405 _ExprPtr++;
407 // Minus ?
408 bool negative = false;
409 if (*_ExprPtr == '-')
411 negative = true;
412 _ExprPtr++;
415 // Read value
416 double exponent;
417 state = readDecimal (exponent);
418 if (state == NoError)
420 // Negative value ?
421 if (negative)
422 exponent = -exponent;
424 // Raise 10 at the power of
425 _Value *= pow (10.0, exponent);
427 else
429 return state;
433 // Number ok
434 return NoError;
436 else
438 return state;
442 // Is a string ?
443 else if (currentChar == '"')
445 // Look for the end of the string
446 _ExprPtr++;
447 currentChar = *_ExprPtr;
448 const char *start = _ExprPtr;
449 while ( (currentChar != 0) && (currentChar != '"') )
451 _ExprPtr++;
452 currentChar = *_ExprPtr;
455 // End reached ?
456 if (currentChar == 0)
457 return MustBeDoubleQuote;
459 // This is a user string, copy the string
460 uint size = (uint)(_ExprPtr - start);
461 if (size >= (InternalStringLen-1))
463 _InternalStlString.resize (size);
464 uint i;
465 for (i=0; i<size; i++)
466 _InternalStlString[i] = start[i];
467 _InternalStringPtr = _InternalStlString.c_str ();
469 else
471 memcpy (_InternalString, start, size);
472 _InternalString[size] = 0;
473 _InternalStringPtr = _InternalString;
476 // Token
477 _ExprPtr++;
478 token = String;
479 return NoError;
483 // Read a string
484 const char *start = _ExprPtr;
485 while ( (currentChar >= 128) || _StringChar[currentChar] )
487 _ExprPtr++;
488 currentChar = *_ExprPtr;
491 // Is pi ?
492 if (((_ExprPtr - start) == 2) && (start[0] == 'p') && (start[1] == 'i'))
494 token = Number;
495 _Value = 3.1415926535897932384626433832795;
496 return NoError;
498 // Is e ?
499 else if (((_ExprPtr - start) == 1) && (start[0] == 'e'))
501 token = Number;
502 _Value = 2.7182818284590452353602874713527;
503 return NoError;
506 // This is a user string, copy the string
507 uint size = (uint)(_ExprPtr - start);
508 if (size >= (InternalStringLen-1))
510 _InternalStlString.resize (size);
511 uint i;
512 for (i=0; i<size; i++)
513 _InternalStlString[i] = start[i];
514 _InternalStringPtr = _InternalStlString.c_str ();
516 else
518 memcpy (_InternalString, start, size);
519 _InternalString[size] = 0;
520 _InternalStringPtr = _InternalString;
523 // Search for a reserved word ?
524 uint begin = 0;
525 uint end = ReservedWordCount-1;
526 sint result = strcmp (_InternalStringPtr, _ReservedWord[begin]);
527 if ( result >= 0 )
529 // The first is the good ?
530 if ( result == 0 )
532 end = begin;
535 result = strcmp (_InternalStringPtr, _ReservedWord[end]);
536 if (result <= 0)
538 // The last is the good ?
539 if ( result == 0 )
541 begin = end;
544 // While there is a middle..
545 while ((end - begin) > 1)
547 uint middle = begin + (end - begin) / 2;
548 result = strcmp (_InternalStringPtr, _ReservedWord[middle]);
549 if (result == 0)
551 begin = middle;
552 end = middle;
553 break;
555 else if (result < 0)
557 end = middle;
559 else
561 begin = middle;
566 // Found ?
567 if (end == begin)
569 // Return the token
570 _ReservedWordFound = (TReservedWord)begin;
571 token = _ReservedWordToken[begin];
573 // Ok
574 return NoError;
578 // Token
579 token = String;
580 return NoError;
583 // ***************************************************************************
585 CEvalNumExpr::TReturnState CEvalNumExpr::evalExpression (const char *expression, double &result,
586 int *errorIndex, uint32 userData)
588 // Init the ptr
589 _ExprPtr = expression;
591 TToken nextToken;
592 TReturnState error = evalExpression (result, nextToken, userData);
593 if (error == NoError)
595 // The end ?
596 if (nextToken == End)
597 return NoError;
598 else
600 if (errorIndex)
601 *errorIndex = (int)(_ExprPtr - expression);
602 return MustBeEnd;
605 else
607 if (errorIndex)
608 *errorIndex = (int)(_ExprPtr - expression);
609 return error;
613 // ***************************************************************************
615 CEvalNumExpr::TReturnState CEvalNumExpr::evalExpression (double &finalResult, TToken &nextToken, uint32 userData)
617 // Array of result
619 uint exprCount = 0;
620 double result[InternalOperator];
621 vector<double> resultSup;
623 uint opCount = 0;
624 TOperator resultOp[InternalOperator];
625 vector<TOperator> resultOpSup;
627 // Read a token
628 TReturnState error = getNextToken (nextToken);
629 if (error != NoError)
630 return error;
631 for(;;)
633 // Unary opertor
634 uint unaryOpCount = 0;
635 TOperator resultUnaryOp[InternalOperator];
636 vector<TOperator> resultUnaryOpSup;
638 // init table
639 for (uint i = 0; i < (uint)InternalOperator; ++i) resultUnaryOp[i] = NotOperator;
641 // Current value
642 double value;
644 // Unary operator ?
645 if ( (nextToken == Operator) && ( (_Op == Minus) || (_Op == Not) || (_Op == Tilde) ) )
647 // Push the unary operator
648 if (unaryOpCount<InternalOperator)
649 resultUnaryOp[unaryOpCount] = _Op;
650 else
651 resultUnaryOpSup.push_back (_Op);
652 unaryOpCount++;
654 // Read next token
655 error = getNextToken (nextToken);
656 if (error != NoError)
657 return error;
660 // Parenthesis ?
661 if (nextToken == Open)
663 // Eval sub expression
664 error = evalExpression (value, nextToken, userData);
665 if (error == NoError)
667 if (nextToken != Close)
668 return MustBeClose;
670 else
671 return error;
673 // Get next token
674 error = getNextToken (nextToken);
675 if (error != NoError)
676 return error;
678 // This is a function ?
679 else if ( (nextToken == Function1) || (nextToken == Function2) )
681 TToken backupedToken = nextToken;
683 // Get the function
684 TReservedWord reservedWord = _ReservedWordFound;
686 // Read a token
687 error = getNextToken (nextToken);
688 if (error == NoError)
690 // Open ?
691 if (nextToken != Open)
693 return MustBeOpen;
696 // Eval an expression
697 double arg0;
698 error = evalExpression (arg0, nextToken, userData);
699 if (error == NoError)
701 // 2 arg ?
702 if (backupedToken == Function2)
704 if (nextToken == Coma)
706 // Second argument
707 double arg1;
708 error = evalExpression (arg1, nextToken, userData);
709 if (error == NoError)
711 // Final with close ?
712 if (nextToken == Close)
714 switch (reservedWord)
716 case Atan2:
717 value = atan2 (arg0, arg1);
718 break;
719 case Max:
720 value = (arg0>arg1) ? arg0 : arg1;
721 break;
722 case Min:
723 value = (arg0<arg1) ? arg0 : arg1;
724 break;
725 case Pow:
726 value = pow (arg0, arg1);
727 break;
728 case Rand:
729 value = arg0 + (arg1-arg0) * (double)rand () / ((double)RAND_MAX+1.0);
730 break;
731 default:
732 // Can't be here after getToken
733 nlstop;
736 else
737 return MustBeClose;
739 else
740 return error;
742 else
743 return MustBeComa;
745 else
747 if (nextToken == Close)
749 // Eval the function
750 switch (reservedWord)
752 case Abs:
753 value = fabs (arg0);
754 break;
755 case Acos:
756 value = acos (arg0);
757 break;
758 case Asin:
759 value = asin (arg0);
760 break;
761 case Atan:
762 value = atan (arg0);
763 break;
764 case Ceil:
765 value = ceil (arg0);
766 break;
767 case Cosh:
768 value = cosh (arg0);
769 break;
770 case Cos:
771 value = cos (arg0);
772 break;
773 case Exponent:
775 int exponent;
776 (void)frexp( arg0, &exponent);
777 value = (double)exponent;
779 break;
780 case Exp:
781 value = exp (arg0);
782 break;
783 case Floor:
784 value = floor (arg0);
785 break;
786 case Int:
787 value = (double)(int)(arg0);
788 break;
789 case Log10:
790 value = log10 (arg0);
791 break;
792 case Log:
793 value = log (arg0);
794 break;
795 case Mantissa:
797 int exponent;
798 value = frexp( arg0, &exponent);
800 break;
801 case Round:
802 value = floor (arg0 + 0.5);
803 break;
804 case Sinh:
805 value = sinh (arg0);
806 break;
807 case Sin:
808 value = sin (arg0);
809 break;
810 case Sqrt:
811 value = sqrt (arg0);
812 break;
813 case Sq:
814 value = arg0 * arg0;
815 break;
816 case Tanh:
817 value = tanh (arg0);
818 break;
819 case Tan:
820 value = tan (arg0);
821 break;
822 default:
823 // Can't be hear after getToken
824 nlstop;
827 else
828 return MustBeClose;
831 else
832 return error;
834 else
835 return error;
837 // Get next token
838 error = getNextToken (nextToken);
839 if (error != NoError)
840 return error;
842 else if (nextToken == Number)
844 // Save the internal value
845 value = _Value;
847 // Get next token
848 error = getNextToken (nextToken);
849 if (error != NoError)
850 return error;
852 else if (nextToken == String)
854 // Copy the string
855 char internalString[InternalStringLen];
856 std::string internalStlString;
857 const char *internalStringPtr;
858 if (strlen (_InternalStringPtr) >= InternalStringLen-1)
860 internalStlString = _InternalStringPtr;
861 internalStringPtr = internalStlString.c_str ();
863 else
865 strcpy (internalString ,_InternalStringPtr);
866 internalStringPtr = internalString;
869 // Read a token
870 error = getNextToken (nextToken);
871 if (error == NoError)
873 // Open ?
874 if (nextToken == Open)
876 // Eval an expression
877 double arg0;
878 error = evalExpression (arg0, nextToken, userData);
879 if (error == NoError)
881 if (nextToken == Coma)
883 // Second argument
884 double arg1;
885 error = evalExpression (arg1, nextToken, userData);
886 if (error == NoError)
888 // Final with close ?
889 if (nextToken == Close)
891 // Eval the function
892 error = evalFunction (internalStringPtr, arg0, arg1, value);
893 if (error != NoError)
894 return error;
896 // Get next token
897 error = getNextToken (nextToken);
898 if (error != NoError)
899 return error;
901 else
902 return MustBeClose;
904 else
905 return error;
907 else
909 if (nextToken == Close)
911 // Eval the function
912 error = evalFunction (internalStringPtr, arg0, value);
913 if (error != NoError)
914 return error;
916 // Get next token
917 error = getNextToken (nextToken);
918 if (error != NoError)
919 return error;
921 else
922 return MustBeClose;
925 else
926 return error;
928 else
930 // This is a user value
931 error = evalValue (internalStringPtr, value, userData);
932 if (error != NoError)
933 return error;
936 else
937 return error;
939 else
941 return MustBeExpression;
944 // Eval unary operator
945 sint i;
946 for (i=unaryOpCount-1; i>=0; i--)
948 switch ((i<InternalOperator)?resultUnaryOp[i]:resultUnaryOpSup[i-InternalOperator])
950 case Not:
951 value = (double)(uint)((floor (value+0.5)==0.0));
952 break;
953 case Tilde:
954 value = (double)(~((uint)floor (value+0.5)) & std::numeric_limits<uint>::max());
955 break;
956 case Minus:
957 value = -value;
958 break;
959 default:
960 // Can't be hear after getToken
961 nlstop;
965 // Push the value
966 if (exprCount < InternalOperator)
967 result[exprCount] = value;
968 else
969 resultSup.push_back (value);
970 exprCount++;
972 // Look for an operator
973 // Operator ?
974 if (nextToken == Operator)
976 // Yes, push it
977 if (opCount < InternalOperator)
978 resultOp[opCount] = _Op;
979 else
980 resultOpSup.push_back (_Op);
981 opCount++;
983 else
985 // Exit the evaluate loop
986 break;
989 // Next token
990 error = getNextToken (nextToken);
993 // Reduce the expression
994 uint index = 1;
995 while (exprCount != 1)
997 // Reduct ?
998 TOperator before = (((index-1)<InternalOperator)?resultOp[index-1]:resultOpSup[index-1-InternalOperator]);
999 TOperator after = (index < opCount)?(((index)<InternalOperator)?resultOp[index]:resultOpSup[index-InternalOperator]):NotOperator;
1000 if ((index == opCount) || (_OperatorPrecedence[before] <= _OperatorPrecedence[after]))
1002 // Eval the value
1003 double &v0 = ((index-1)<InternalOperator)?result[index-1]:resultSup[index-1-InternalOperator];
1004 double &v1 = ((index)<InternalOperator)?result[index]:resultSup[index-InternalOperator];
1006 // Choose the operator
1007 switch (before)
1009 case Not:
1010 case Tilde:
1011 return NotUnaryOperator;
1012 case Mul:
1013 v0 *= v1;
1014 break;
1015 case Div:
1016 if (v1 == 0)
1018 return DividByZero;
1020 else
1022 v0 /= v1;
1024 break;
1025 case Remainder:
1026 v0 = fmod (v0, v1);
1027 break;
1028 case Plus:
1029 v0 += v1;
1030 break;
1031 case Minus:
1032 v0 -= v1;
1033 break;
1034 case ULeftShift:
1035 v0 = (double)(uint)(((uint)floor (v0 + 0.5))<<((uint)floor (v1 + 0.5)));
1036 break;
1037 case URightShift:
1038 v0 = (double)(((uint)floor (v0 + 0.5))>>((uint)floor (v1 + 0.5)));
1039 break;
1040 case SLeftShift:
1041 v0 = (double)(sint)(((sint)floor (v0 + 0.5))<<((sint)floor (v1 + 0.5)));
1042 break;
1043 case SRightShift:
1044 v0 = (double)(((sint)floor (v0 + 0.5))>>((sint)floor (v1 + 0.5)));
1045 break;
1046 case Inferior:
1047 v0 = (v0<v1)?1.0:0.0;
1048 break;
1049 case InferiorEqual:
1050 v0 = (v0<=v1)?1.0:0.0;
1051 break;
1052 case Superior:
1053 v0 = (v0>v1)?1.0:0.0;
1054 break;
1055 case SuperiorEqual:
1056 v0 = (v0>=v1)?1.0:0.0;
1057 break;
1058 case Equal:
1059 v0 = (v0==v1)?1.0:0.0;
1060 break;
1061 case NotEqual:
1062 v0 = (v0!=v1)?1.0:0.0;
1063 break;
1064 case And:
1065 v0 = (double)(((uint)floor (v0 + 0.5)) & ((uint)floor (v1 + 0.5)));
1066 break;
1067 case Or:
1068 v0 = (double)(((uint)floor (v0 + 0.5)) | ((uint)floor (v1 + 0.5)));
1069 break;
1070 case Xor:
1071 v0 = (double)(((uint)floor (v0 + 0.5)) ^ ((uint)floor (v1 + 0.5)));
1072 break;
1073 case LogicalAnd:
1074 v0 = (double)(uint)((floor (v0 + 0.5) != 0.0) && (floor (v1 + 0.5) != 0.0));
1075 break;
1076 case LogicalOr:
1077 v0 = (double)(uint)((floor (v0 + 0.5) != 0.0) || (floor (v1 + 0.5) != 0.0));
1078 break;
1079 case LogicalXor:
1081 bool b0 = floor (v0 + 0.5) != 0.0;
1082 bool b1 = floor (v1 + 0.5) != 0.0;
1083 v0 = (double)(uint)((b0&&!b1) || ((!b0)&&b1));
1085 break;
1086 default:
1087 nlstop;
1090 // Decal others values
1091 uint i = index;
1092 for (; i<exprCount-1; i++)
1094 // Copy
1095 if (i<InternalOperator)
1096 result[i] = (i+1<InternalOperator)?result[i+1]:resultSup[i+1-InternalOperator];
1097 else
1098 resultSup[i-InternalOperator] = (i+1<InternalOperator)?result[i+1]:resultSup[i+1-InternalOperator];
1100 exprCount--;
1102 // Decal operators
1103 i = index-1;
1104 for (; i<opCount-1; i++)
1106 // Copy
1107 if (i<InternalOperator)
1108 resultOp[i] = (i+1<InternalOperator)?resultOp[i+1]:resultOpSup[i+1-InternalOperator];
1109 else
1110 resultOpSup[i-InternalOperator] = (i+1<InternalOperator)?resultOp[i+1]:resultOpSup[i+1-InternalOperator];
1113 opCount--;
1115 // Last one ?
1116 if (index > 1)
1117 index--;
1119 else
1120 index++;
1123 finalResult = result[0];
1124 return NoError;
1127 // ***************************************************************************
1129 bool CEvalNumExpr::internalCheck ()
1131 for (uint i=0; i<ReservedWordCount-1; i++)
1132 if (strcmp (_ReservedWord[i], _ReservedWord[i+1]) >= 0)
1134 nlstop;
1135 return false;
1137 return true;
1140 // ***************************************************************************
1142 // ASCII TABLE
1145 0 NUL SOH STX ETX EOT ENQ ACK BEL BS TAB LF VT FF CR SO SI
1146 1 DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US
1147 2 ! " # $ % & ' ( ) * + , - . /
1148 3 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
1149 4 @ A B C D E F G H I J K L M N O
1150 5 P Q R S T U V W X Y Z [ \ ] ^ _
1151 6 ` a b c d e f g h i j k l m n o
1152 7 p q r s t u v w x y z { | } ~
1155 // ***************************************************************************
1157 const CEvalNumExpr::TOperator CEvalNumExpr::_OperatorArray[128] =
1159 NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator,
1160 NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator,
1161 NotOperator, ExtOperator, NotOperator, NotOperator, NotOperator, Remainder, ExtOperator, NotOperator, NotOperator, NotOperator, Mul, Plus, NotOperator, ExtOperator, NotOperator, Div,
1162 NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, ExtOperator, ExtOperator, ExtOperator, NotOperator,
1163 NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator,
1164 NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, ExtOperator, NotOperator,
1165 NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator,
1166 NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, ExtOperator, NotOperator, Tilde, NotOperator,
1169 // ***************************************************************************
1171 const bool CEvalNumExpr::_StringChar[128] =
1173 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
1174 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
1175 false, false, true, true, true, false, false, true, false, false, false, false, false, false, false, false,
1176 true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, true,
1177 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
1178 true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, true,
1179 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
1180 true, true, true, true, true, true, true, true, true, true, true, true, false, true, false, true,
1183 // ***************************************************************************
1185 CEvalNumExpr::TReturnState CEvalNumExpr::evalValue (const char *value, double &result, uint32 userData)
1187 return UnknownValue;
1190 // ***************************************************************************
1192 CEvalNumExpr::TReturnState CEvalNumExpr::evalFunction (const char *funcName, double arg0, double &result)
1194 return UnknownFunction;
1197 // ***************************************************************************
1199 CEvalNumExpr::TReturnState CEvalNumExpr::evalFunction (const char *funcName, double arg0, double arg1, double &result)
1201 return UnknownFunction;
1204 // ***************************************************************************
1206 const char *CEvalNumExpr::_ReservedWord[ReservedWordCount] =
1208 "abs", // Abs
1209 "acos", // Acos
1210 "asin", // Asin
1211 "atan", // Atan
1212 "atan2", // Atan2
1213 "ceil", // Ceil
1214 "cos", // Cos
1215 "cosh", // Cosh
1216 "exp", // Exp
1217 "exponent", // Exponent
1218 "floor", // Floor
1219 "int", // Int
1220 "log", // Log
1221 "log10", // Log10
1222 "mantissa", // Mantissa
1223 "max", // Max
1224 "min", // Min
1225 "pow", // Pow
1226 "rand", // Rand
1227 "round", // Round
1228 "sin", // Sin
1229 "sinh", // Sinh
1230 "sq", // Sq
1231 "sqrt", // Sqrt
1232 "tan", // Tan
1233 "tanh", // Tanh
1236 // ***************************************************************************
1238 const CEvalNumExpr::TToken CEvalNumExpr::_ReservedWordToken[ReservedWordCount] =
1240 Function1, // Abs
1241 Function1, // Acos
1242 Function1, // Asin
1243 Function1, // Atan
1244 Function2, // Atan2
1245 Function1, // Ceil
1246 Function1, // Cos
1247 Function1, // Cosh
1248 Function1, // Exp
1249 Function1, // Exponent
1250 Function1, // Floor
1251 Function1, // Int
1252 Function1, // Log
1253 Function1, // Log10
1254 Function1, // Mantissa
1255 Function2, // Max
1256 Function2, // Min
1257 Function2, // Pow
1258 Function2, // Rand
1259 Function1, // Round
1260 Function1, // Sin
1261 Function1, // Sinh
1262 Function1, // Sq
1263 Function1, // Sqrt
1264 Function1, // Tan
1265 Function1, // Tanh
1268 // ***************************************************************************
1270 const char *CEvalNumExpr::_ErrorString[ReturnValueCount]=
1272 "No error",
1273 "Unknown value",
1274 "Error during user defined value evaluation",
1275 "Unknown function",
1276 "Error during user defined function evaluation",
1277 "Syntax error in a number expression",
1278 "Unknown operator",
1279 "Should be a open parentesis",
1280 "Should be a close parentesis",
1281 "Should be a coma character",
1282 "Should be an expression",
1283 "Should not be an unary operator",
1284 "Should be the end of the expression",
1285 "Should be a double quote",
1286 "Divid by zero",
1289 // ***************************************************************************
1291 const char* CEvalNumExpr::getErrorString (TReturnState state) const
1293 return _ErrorString[state];
1296 // ***************************************************************************
1298 const int CEvalNumExpr::_OperatorPrecedence[]=
1300 0, // Not
1301 0, // Tilde
1302 1, // Mul
1303 1, // Div
1304 1, // Remainder
1305 2, // Plus
1306 2, // Minus
1307 3, // ULeftShift
1308 3, // URightShift
1309 3, // SLeftShift
1310 3, // SRightShift
1311 4, // Inferior
1312 4, // InferiorEqual
1313 4, // Superior
1314 4, // SuperiorEqual
1315 5, // Equal
1316 5, // NotEqual
1317 6, // And
1318 7, // Or
1319 8, // Xor
1320 9, // LogicalAnd
1321 10, // LogicalOr
1322 11, // LogicalXor
1323 -1, // OperatorCount
1324 20, // NotOperator
1327 // ***************************************************************************