All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ttmathparser.h
Go to the documentation of this file.
1 /*
2  * This file is a part of TTMath Bignum Library
3  * and is distributed under the (new) BSD licence.
4  * Author: Tomasz Sowa <t.sowa@ttmath.org>
5  */
6 
7 /*
8  * Copyright (c) 2006-2010, Tomasz Sowa
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions are met:
13  *
14  * * Redistributions of source code must retain the above copyright notice,
15  * this list of conditions and the following disclaimer.
16  *
17  * * Redistributions in binary form must reproduce the above copyright
18  * notice, this list of conditions and the following disclaimer in the
19  * documentation and/or other materials provided with the distribution.
20  *
21  * * Neither the name Tomasz Sowa nor the names of contributors to this
22  * project may be used to endorse or promote products derived
23  * from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
35  * THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 
39 
40 #ifndef headerfilettmathparser
41 #define headerfilettmathparser
42 
48 #include <cstdio>
49 #include <vector>
50 #include <map>
51 #include <set>
52 
53 #include "ttmath.h"
54 #include "ttmathobjects.h"
55 #include "ttmathmisc.h"
56 
57 
58 
59 namespace ttmath
60 {
61 
137 template<class ValueType>
138 class Parser
139 {
140 private:
141 
153  class MatOperator
154  {
155  public:
156 
157  enum Type
158  {
159  none,add,sub,mul,div,pow,lt,gt,let,get,eq,neq,lor,land,shortmul
160  };
161 
162  enum Assoc
163  {
164  right, // right-associative
165  non_right // associative or left-associative
166  };
167 
168  Type GetType() const { return type; }
169  int GetPriority() const { return priority; }
170  Assoc GetAssoc() const { return assoc; }
171 
172  void SetType(Type t)
173  {
174  type = t;
175  assoc = non_right;
176 
177  switch( type )
178  {
179  case lor:
180  priority = 4;
181  break;
182 
183  case land:
184  priority = 5;
185  break;
186 
187  case eq:
188  case neq:
189  case lt:
190  case gt:
191  case let:
192  case get:
193  priority = 7;
194  break;
195 
196  case add:
197  case sub:
198  priority = 10;
199  break;
200 
201  case mul:
202  case shortmul:
203  case div:
204  priority = 12;
205  break;
206 
207  case pow:
208  priority = 14;
209  assoc = right;
210  break;
211 
212  default:
213  Error( err_internal_error );
214  break;
215  }
216  }
217 
218  MatOperator(): type(none), priority(0), assoc(non_right)
219  {
220  }
221 
222  private:
223 
224  Type type;
225  int priority;
226  Assoc assoc;
227  }; // end of MatOperator class
228 
229 
230 
231 public:
232 
233 
234 
238  struct Item
239  {
240  enum Type
241  {
244  };
245 
246  // The kind of type which we're keeping
248 
249  // if type == numerical_value
250  ValueType value;
251 
252  // if type == mat_operator
253  MatOperator moperator;
254 
255  /*
256  if type == first_bracket
257 
258  if 'function' is set to true it means that the first recognized bracket
259  was the bracket from function in other words we must call a function when
260  we'll find the 'last' bracket
261  */
262  bool function;
263 
264  // if function is true
265  std::string function_name;
266 
267  /*
268  the sign of value
269 
270  it can be for type==numerical_value or type==first_bracket
271  when it's true it means e.g. that value is equal -value
272  */
273  bool sign;
274 
275  Item(): type(none), function(false), sign(false)
276  {
277  }
278 
279  }; // end of Item struct
280 
281 
296 std::vector<Item> stack;
297 
298 
299 private:
300 
301 
307 const int default_stack_size;
308 
309 
310 
316 unsigned int stack_index;
317 
318 
322 ErrorCode error;
323 
324 
329 const char * pstring;
330 
331 
335 int base;
336 
337 
344 int deg_rad_grad;
345 
346 
347 
351 const volatile StopCalculating * pstop_calculating;
352 
353 
354 
358 const Objects * puser_variables;
359 
363 const Objects * puser_functions;
364 
365 
366 typedef std::map<std::string, ValueType> FunctionLocalVariables;
367 
371 const FunctionLocalVariables * pfunction_local_variables;
372 
373 
377 std::set<std::string> visited_variables;
378 
379 
383 std::set<std::string> visited_functions;
384 
385 
386 
387 
398 typedef void (Parser<ValueType>::*pfunction)(int pstack, int amount_of_arg, ValueType & result);
399 
400 
404 typedef void (ValueType::*pfunction_var)();
405 
406 
414 typedef std::map<std::string, pfunction> FunctionsTable;
415 FunctionsTable functions_table;
416 
417 
425 typedef std::map<std::string, typename MatOperator::Type> OperatorsTable;
426 OperatorsTable operators_table;
427 
428 
436 typedef std::map<std::string, pfunction_var> VariablesTable;
437 VariablesTable variables_table;
438 
439 
443 CGamma<ValueType> cgamma;
444 
445 
449 std::string wide_to_ansi;
450 
451 
456 int group;
457 
458 
464 int comma, comma2;
465 
466 
471 int param_sep;
472 
473 
477 bool calculated;
478 
479 
480 
484 static void Error(ErrorCode code)
485 {
486  throw code;
487 }
488 
489 
495 void SkipWhiteCharacters()
496 {
497  while( (*pstring==' ' ) || (*pstring=='\t') )
498  ++pstring;
499 }
500 
501 
505 void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, const std::string & name)
506 {
507  if( variable )
508  {
509  if( visited_variables.find(name) != visited_variables.end() )
510  Error( err_variable_loop );
511  }
512  else
513  {
514  if( visited_functions.find(name) != visited_functions.end() )
515  Error( err_functions_loop );
516  }
517 }
518 
519 
523 void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const std::string & name)
524 {
525  if( variable )
526  visited_variables.insert( name );
527  else
528  visited_functions.insert( name );
529 }
530 
531 
535 void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const std::string & name)
536 {
537  if( variable )
538  visited_variables.erase( name );
539  else
540  visited_functions.erase( name );
541 }
542 
543 
554 ValueType RecurrenceParsingVariablesOrFunction(bool variable, const std::string & name, const char * new_string,
555  FunctionLocalVariables * local_variables = 0)
556 {
557  RecurrenceParsingVariablesOrFunction_CheckStopCondition(variable, name);
558  RecurrenceParsingVariablesOrFunction_AddName(variable, name);
559 
560  Parser<ValueType> NewParser(*this);
561  ErrorCode err;
562 
563  NewParser.pfunction_local_variables = local_variables;
564 
565  try
566  {
567  err = NewParser.Parse(new_string);
568  }
569  catch(...)
570  {
571  RecurrenceParsingVariablesOrFunction_DeleteName(variable, name);
572 
573  throw;
574  }
575 
576  RecurrenceParsingVariablesOrFunction_DeleteName(variable, name);
577 
578  if( err != err_ok )
579  Error( err );
580 
581  if( NewParser.stack.size() != 1 )
583 
584  if( NewParser.stack[0].type != Item::numerical_value )
585  // I think there shouldn't be this error here
586  Error( err_incorrect_value );
587 
588 return NewParser.stack[0].value;
589 }
590 
591 
592 public:
593 
594 
598 bool GetValueOfUserDefinedVariable(const std::string & variable_name,ValueType & result)
599 {
600  if( !puser_variables )
601  return false;
602 
603  const char * string_value;
604 
605  if( puser_variables->GetValue(variable_name, &string_value) != err_ok )
606  return false;
607 
608  result = RecurrenceParsingVariablesOrFunction(true, variable_name, string_value);
609  calculated = true;
610 
611 return true;
612 }
613 
614 
618 bool GetValueOfFunctionLocalVariable(const std::string & variable_name, ValueType & result)
619 {
620  if( !pfunction_local_variables )
621  return false;
622 
623  typename FunctionLocalVariables::const_iterator i = pfunction_local_variables->find(variable_name);
624 
625  if( i == pfunction_local_variables->end() )
626  return false;
627 
628  result = i->second;
629 
630 return true;
631 }
632 
633 
640 ValueType GetValueOfVariable(const std::string & variable_name)
641 {
642 ValueType result;
643 
644  if( GetValueOfFunctionLocalVariable(variable_name, result) )
645  return result;
646 
647  if( GetValueOfUserDefinedVariable(variable_name, result) )
648  return result;
649 
650 
651  typename std::map<std::string, pfunction_var>::iterator i =
652  variables_table.find(variable_name);
653 
654  if( i == variables_table.end() )
655  Error( err_unknown_variable );
656 
657  (result.*(i->second))();
658  calculated = true;
659 
660 return result;
661 }
662 
663 
664 private:
665 
683 ValueType ConvertAngleToRad(const ValueType & input)
684 {
685  if( deg_rad_grad == 1 ) // rad
686  return input;
687 
688  ValueType result;
689  ErrorCode err;
690 
691  if( deg_rad_grad == 0 ) // deg
692  result = ttmath::DegToRad(input, &err);
693  else // grad
694  result = ttmath::GradToRad(input, &err);
695 
696  if( err != err_ok )
697  Error( err );
698 
699 return result;
700 }
701 
702 
706 ValueType ConvertRadToAngle(const ValueType & input)
707 {
708  if( deg_rad_grad == 1 ) // rad
709  return input;
710 
711  ValueType result;
712  ErrorCode err;
713 
714  if( deg_rad_grad == 0 ) // deg
715  result = ttmath::RadToDeg(input, &err);
716  else // grad
717  result = ttmath::RadToGrad(input, &err);
718 
719  if( err != err_ok )
720  Error( err );
721 
722 return result;
723 }
724 
725 
726 void Gamma(int sindex, int amount_of_args, ValueType & result)
727 {
728  if( amount_of_args != 1 )
730 
731  ErrorCode err;
732 
733  result = ttmath::Gamma(stack[sindex].value, cgamma, &err, pstop_calculating);
734 
735  if(err != err_ok)
736  Error( err );
737 }
738 
739 
744 void Factorial(int sindex, int amount_of_args, ValueType & result)
745 {
746  if( amount_of_args != 1 )
748 
749  ErrorCode err;
750 
751  result = ttmath::Factorial(stack[sindex].value, cgamma, &err, pstop_calculating);
752 
753  if(err != err_ok)
754  Error( err );
755 }
756 
757 
758 void Abs(int sindex, int amount_of_args, ValueType & result)
759 {
760  if( amount_of_args != 1 )
762 
763  result = ttmath::Abs(stack[sindex].value);
764 }
765 
766 void Sin(int sindex, int amount_of_args, ValueType & result)
767 {
768  if( amount_of_args != 1 )
770 
771  ErrorCode err;
772  result = ttmath::Sin( ConvertAngleToRad(stack[sindex].value), &err );
773 
774  if(err != err_ok)
775  Error( err );
776 }
777 
778 void Cos(int sindex, int amount_of_args, ValueType & result)
779 {
780  if( amount_of_args != 1 )
782 
783  ErrorCode err;
784  result = ttmath::Cos( ConvertAngleToRad(stack[sindex].value), &err );
785 
786  if(err != err_ok)
787  Error( err );
788 }
789 
790 void Tan(int sindex, int amount_of_args, ValueType & result)
791 {
792  if( amount_of_args != 1 )
794 
795  ErrorCode err;
796  result = ttmath::Tan(ConvertAngleToRad(stack[sindex].value), &err);
797 
798  if(err != err_ok)
799  Error( err );
800 }
801 
802 void Cot(int sindex, int amount_of_args, ValueType & result)
803 {
804  if( amount_of_args != 1 )
806 
807  ErrorCode err;
808  result = ttmath::Cot(ConvertAngleToRad(stack[sindex].value), &err);
809 
810  if(err != err_ok)
811  Error( err );
812 }
813 
814 void Int(int sindex, int amount_of_args, ValueType & result)
815 {
816  if( amount_of_args != 1 )
818 
819  result = ttmath::SkipFraction(stack[sindex].value);
820 }
821 
822 
823 void Round(int sindex, int amount_of_args, ValueType & result)
824 {
825  if( amount_of_args != 1 )
827 
828  result = stack[sindex].value;
829 
830  if( result.Round() )
831  Error( err_overflow );
832 }
833 
834 
835 void Ln(int sindex, int amount_of_args, ValueType & result)
836 {
837  if( amount_of_args != 1 )
839 
840  ErrorCode err;
841  result = ttmath::Ln(stack[sindex].value, &err);
842 
843  if(err != err_ok)
844  Error( err );
845 }
846 
847 void Log(int sindex, int amount_of_args, ValueType & result)
848 {
849  if( amount_of_args != 2 )
851 
852  ErrorCode err;
853  result = ttmath::Log(stack[sindex].value, stack[sindex+2].value, &err);
854 
855  if(err != err_ok)
856  Error( err );
857 }
858 
859 void Exp(int sindex, int amount_of_args, ValueType & result)
860 {
861  if( amount_of_args != 1 )
863 
864  ErrorCode err;
865  result = ttmath::Exp(stack[sindex].value, &err);
866 
867  if(err != err_ok)
868  Error( err );
869 }
870 
871 
872 void Max(int sindex, int amount_of_args, ValueType & result)
873 {
874  if( amount_of_args == 0 )
875  {
876  result.SetMax();
877 
878  return;
879  }
880 
881  result = stack[sindex].value;
882 
883  for(int i=1 ; i<amount_of_args ; ++i)
884  {
885  if( result < stack[sindex + i*2].value )
886  result = stack[sindex + i*2].value;
887  }
888 }
889 
890 
891 void Min(int sindex, int amount_of_args, ValueType & result)
892 {
893  if( amount_of_args == 0 )
894  {
895  result.SetMin();
896 
897  return;
898  }
899 
900  result = stack[sindex].value;
901 
902  for(int i=1 ; i<amount_of_args ; ++i)
903  {
904  if( result > stack[sindex + i*2].value )
905  result = stack[sindex + i*2].value;
906  }
907 }
908 
909 
910 void ASin(int sindex, int amount_of_args, ValueType & result)
911 {
912  if( amount_of_args != 1 )
914 
915  ErrorCode err;
916  ValueType temp = ttmath::ASin(stack[sindex].value, &err);
917 
918  if(err != err_ok)
919  Error( err );
920 
921  result = ConvertRadToAngle(temp);
922 }
923 
924 
925 void ACos(int sindex, int amount_of_args, ValueType & result)
926 {
927  if( amount_of_args != 1 )
929 
930  ErrorCode err;
931  ValueType temp = ttmath::ACos(stack[sindex].value, &err);
932 
933  if(err != err_ok)
934  Error( err );
935 
936  result = ConvertRadToAngle(temp);
937 }
938 
939 
940 void ATan(int sindex, int amount_of_args, ValueType & result)
941 {
942  if( amount_of_args != 1 )
944 
945  result = ConvertRadToAngle(ttmath::ATan(stack[sindex].value));
946 }
947 
948 
949 void ACot(int sindex, int amount_of_args, ValueType & result)
950 {
951  if( amount_of_args != 1 )
953 
954  result = ConvertRadToAngle(ttmath::ACot(stack[sindex].value));
955 }
956 
957 
958 void Sgn(int sindex, int amount_of_args, ValueType & result)
959 {
960  if( amount_of_args != 1 )
962 
963  result = ttmath::Sgn(stack[sindex].value);
964 }
965 
966 
967 void Mod(int sindex, int amount_of_args, ValueType & result)
968 {
969  if( amount_of_args != 2 )
971 
972  if( stack[sindex+2].value.IsZero() )
973  Error( err_improper_argument );
974 
975  result = stack[sindex].value;
976  uint c = result.Mod(stack[sindex+2].value);
977 
978  if( c )
979  Error( err_overflow );
980 }
981 
982 
983 void If(int sindex, int amount_of_args, ValueType & result)
984 {
985  if( amount_of_args != 3 )
987 
988 
989  if( !stack[sindex].value.IsZero() )
990  result = stack[sindex+2].value;
991  else
992  result = stack[sindex+4].value;
993 }
994 
995 
996 void Or(int sindex, int amount_of_args, ValueType & result)
997 {
998  if( amount_of_args < 2 )
1000 
1001  for(int i=0 ; i<amount_of_args ; ++i)
1002  {
1003  if( !stack[sindex+i*2].value.IsZero() )
1004  {
1005  result.SetOne();
1006  return;
1007  }
1008  }
1009 
1010  result.SetZero();
1011 }
1012 
1013 
1014 void And(int sindex, int amount_of_args, ValueType & result)
1015 {
1016  if( amount_of_args < 2 )
1018 
1019  for(int i=0 ; i<amount_of_args ; ++i)
1020  {
1021  if( stack[sindex+i*2].value.IsZero() )
1022  {
1023  result.SetZero();
1024  return;
1025  }
1026  }
1027 
1028  result.SetOne();
1029 }
1030 
1031 
1032 void Not(int sindex, int amount_of_args, ValueType & result)
1033 {
1034  if( amount_of_args != 1 )
1036 
1037 
1038  if( stack[sindex].value.IsZero() )
1039  result.SetOne();
1040  else
1041  result.SetZero();
1042 }
1043 
1044 
1045 void DegToRad(int sindex, int amount_of_args, ValueType & result)
1046 {
1047  ErrorCode err = err_ok;
1048 
1049  if( amount_of_args == 1 )
1050  {
1051  result = ttmath::DegToRad(stack[sindex].value, &err);
1052  }
1053  else
1054  if( amount_of_args == 3 )
1055  {
1056  result = ttmath::DegToRad( stack[sindex].value, stack[sindex+2].value,
1057  stack[sindex+4].value, &err);
1058  }
1059  else
1061 
1062 
1063  if( err != err_ok )
1064  Error( err );
1065 }
1066 
1067 
1068 void RadToDeg(int sindex, int amount_of_args, ValueType & result)
1069 {
1070  ErrorCode err;
1071 
1072  if( amount_of_args != 1 )
1074 
1075  result = ttmath::RadToDeg(stack[sindex].value, &err);
1076 
1077  if( err != err_ok )
1078  Error( err );
1079 }
1080 
1081 
1082 void DegToDeg(int sindex, int amount_of_args, ValueType & result)
1083 {
1084  if( amount_of_args != 3 )
1086 
1087  ErrorCode err;
1088  result = ttmath::DegToDeg( stack[sindex].value, stack[sindex+2].value,
1089  stack[sindex+4].value, &err);
1090 
1091  if( err != err_ok )
1092  Error( err );
1093 }
1094 
1095 
1096 void GradToRad(int sindex, int amount_of_args, ValueType & result)
1097 {
1098  ErrorCode err;
1099 
1100  if( amount_of_args != 1 )
1102 
1103  result = ttmath::GradToRad(stack[sindex].value, &err);
1104 
1105  if( err != err_ok )
1106  Error( err );
1107 }
1108 
1109 
1110 void RadToGrad(int sindex, int amount_of_args, ValueType & result)
1111 {
1112  ErrorCode err;
1113 
1114  if( amount_of_args != 1 )
1116 
1117  result = ttmath::RadToGrad(stack[sindex].value, &err);
1118 
1119  if( err != err_ok )
1120  Error( err );
1121 }
1122 
1123 
1124 void DegToGrad(int sindex, int amount_of_args, ValueType & result)
1125 {
1126  ErrorCode err = err_ok;
1127 
1128  if( amount_of_args == 1 )
1129  {
1130  result = ttmath::DegToGrad(stack[sindex].value, &err);
1131  }
1132  else
1133  if( amount_of_args == 3 )
1134  {
1135  result = ttmath::DegToGrad( stack[sindex].value, stack[sindex+2].value,
1136  stack[sindex+4].value, &err);
1137  }
1138  else
1140 
1141 
1142  if( err != err_ok )
1143  Error( err );
1144 }
1145 
1146 
1147 void GradToDeg(int sindex, int amount_of_args, ValueType & result)
1148 {
1149  ErrorCode err;
1150 
1151  if( amount_of_args != 1 )
1153 
1154  result = ttmath::GradToDeg(stack[sindex].value, &err);
1155 
1156  if( err != err_ok )
1157  Error( err );
1158 }
1159 
1160 
1161 void Ceil(int sindex, int amount_of_args, ValueType & result)
1162 {
1163  if( amount_of_args != 1 )
1165 
1166  ErrorCode err;
1167  result = ttmath::Ceil(stack[sindex].value, &err);
1168 
1169  if( err != err_ok )
1170  Error( err );
1171 }
1172 
1173 
1174 void Floor(int sindex, int amount_of_args, ValueType & result)
1175 {
1176  if( amount_of_args != 1 )
1178 
1179  ErrorCode err;
1180  result = ttmath::Floor(stack[sindex].value, &err);
1181 
1182  if( err != err_ok )
1183  Error( err );
1184 }
1185 
1186 void Sqrt(int sindex, int amount_of_args, ValueType & result)
1187 {
1188  if( amount_of_args != 1 )
1190 
1191  ErrorCode err;
1192  result = ttmath::Sqrt(stack[sindex].value, &err);
1193 
1194  if( err != err_ok )
1195  Error( err );
1196 }
1197 
1198 
1199 void Sinh(int sindex, int amount_of_args, ValueType & result)
1200 {
1201  if( amount_of_args != 1 )
1203 
1204  ErrorCode err;
1205  result = ttmath::Sinh(stack[sindex].value, &err);
1206 
1207  if( err != err_ok )
1208  Error( err );
1209 }
1210 
1211 
1212 void Cosh(int sindex, int amount_of_args, ValueType & result)
1213 {
1214  if( amount_of_args != 1 )
1216 
1217  ErrorCode err;
1218  result = ttmath::Cosh(stack[sindex].value, &err);
1219 
1220  if( err != err_ok )
1221  Error( err );
1222 }
1223 
1224 
1225 void Tanh(int sindex, int amount_of_args, ValueType & result)
1226 {
1227  if( amount_of_args != 1 )
1229 
1230  ErrorCode err;
1231  result = ttmath::Tanh(stack[sindex].value, &err);
1232 
1233  if( err != err_ok )
1234  Error( err );
1235 }
1236 
1237 
1238 void Coth(int sindex, int amount_of_args, ValueType & result)
1239 {
1240  if( amount_of_args != 1 )
1242 
1243  ErrorCode err;
1244  result = ttmath::Coth(stack[sindex].value, &err);
1245 
1246  if( err != err_ok )
1247  Error( err );
1248 }
1249 
1250 
1251 void Root(int sindex, int amount_of_args, ValueType & result)
1252 {
1253  if( amount_of_args != 2 )
1255 
1256  ErrorCode err;
1257  result = ttmath::Root(stack[sindex].value, stack[sindex+2].value, &err);
1258 
1259  if( err != err_ok )
1260  Error( err );
1261 }
1262 
1263 
1264 
1265 void ASinh(int sindex, int amount_of_args, ValueType & result)
1266 {
1267  if( amount_of_args != 1 )
1269 
1270  ErrorCode err;
1271  result = ttmath::ASinh(stack[sindex].value, &err);
1272 
1273  if( err != err_ok )
1274  Error( err );
1275 }
1276 
1277 
1278 void ACosh(int sindex, int amount_of_args, ValueType & result)
1279 {
1280  if( amount_of_args != 1 )
1282 
1283  ErrorCode err;
1284  result = ttmath::ACosh(stack[sindex].value, &err);
1285 
1286  if( err != err_ok )
1287  Error( err );
1288 }
1289 
1290 
1291 void ATanh(int sindex, int amount_of_args, ValueType & result)
1292 {
1293  if( amount_of_args != 1 )
1295 
1296  ErrorCode err;
1297  result = ttmath::ATanh(stack[sindex].value, &err);
1298 
1299  if( err != err_ok )
1300  Error( err );
1301 }
1302 
1303 
1304 void ACoth(int sindex, int amount_of_args, ValueType & result)
1305 {
1306  if( amount_of_args != 1 )
1308 
1309  ErrorCode err;
1310  result = ttmath::ACoth(stack[sindex].value, &err);
1311 
1312  if( err != err_ok )
1313  Error( err );
1314 }
1315 
1316 
1317 void BitAnd(int sindex, int amount_of_args, ValueType & result)
1318 {
1319  if( amount_of_args != 2 )
1321 
1322  uint err;
1323  result = stack[sindex].value;
1324  err = result.BitAnd(stack[sindex+2].value);
1325 
1326  switch(err)
1327  {
1328  case 1:
1329  Error( err_overflow );
1330  break;
1331  case 2:
1332  Error( err_improper_argument );
1333  break;
1334  }
1335 }
1336 
1337 void BitOr(int sindex, int amount_of_args, ValueType & result)
1338 {
1339  if( amount_of_args != 2 )
1341 
1342  uint err;
1343  result = stack[sindex].value;
1344  err = result.BitOr(stack[sindex+2].value);
1345 
1346  switch(err)
1347  {
1348  case 1:
1349  Error( err_overflow );
1350  break;
1351  case 2:
1352  Error( err_improper_argument );
1353  break;
1354  }
1355 }
1356 
1357 
1358 void BitXor(int sindex, int amount_of_args, ValueType & result)
1359 {
1360  if( amount_of_args != 2 )
1362 
1363  uint err;
1364  result = stack[sindex].value;
1365  err = result.BitXor(stack[sindex+2].value);
1366 
1367  switch(err)
1368  {
1369  case 1:
1370  Error( err_overflow );
1371  break;
1372  case 2:
1373  Error( err_improper_argument );
1374  break;
1375  }
1376 }
1377 
1378 
1379 void Sum(int sindex, int amount_of_args, ValueType & result)
1380 {
1381  if( amount_of_args == 0 )
1383 
1384  result = stack[sindex].value;
1385 
1386  for(int i=1 ; i<amount_of_args ; ++i )
1387  if( result.Add( stack[ sindex + i*2 ].value ) )
1388  Error( err_overflow );
1389 }
1390 
1391 void Avg(int sindex, int amount_of_args, ValueType & result)
1392 {
1393  if( amount_of_args == 0 )
1395 
1396  result = stack[sindex].value;
1397 
1398  for(int i=1 ; i<amount_of_args ; ++i )
1399  if( result.Add( stack[ sindex + i*2 ].value ) )
1400  Error( err_overflow );
1401 
1402  if( result.Div( amount_of_args ) )
1403  Error( err_overflow );
1404 }
1405 
1406 
1407 void Frac(int sindex, int amount_of_args, ValueType & result)
1408 {
1409  if( amount_of_args != 1 )
1411 
1412  result = stack[sindex].value;
1413  result.RemainFraction();
1414 }
1415 
1416 
1417 
1418 
1422 void Sprintf(char * buffer, int par)
1423 {
1424 char buf[30]; // char, not wchar_t
1425 int i;
1426 
1427  #ifdef _MSC_VER
1428  #pragma warning( disable: 4996 )
1429  //warning C4996: 'sprintf': This function or variable may be unsafe.
1430  #endif
1431 
1432  sprintf(buf, "%d", par);
1433  for(i=0 ; buf[i] != 0 ; ++i)
1434  buffer[i] = buf[i];
1435 
1436  buffer[i] = 0;
1437 
1438  #ifdef _MSC_VER
1439  #pragma warning( default: 4996 )
1440  #endif
1441 }
1442 
1443 
1444 
1445 
1451 bool GetValueOfUserDefinedFunction(const std::string & function_name, int amount_of_args, int sindex)
1452 {
1453  if( !puser_functions )
1454  return false;
1455 
1456  const char * string_value;
1457  int param;
1458 
1459  if( puser_functions->GetValueAndParam(function_name, &string_value, &param) != err_ok )
1460  return false;
1461 
1462  if( param != amount_of_args )
1464 
1465 
1466  FunctionLocalVariables local_variables;
1467 
1468  if( amount_of_args > 0 )
1469  {
1470  char buffer[30];
1471 
1472  // x = x1
1473  buffer[0] = 'x';
1474  buffer[1] = 0;
1475  local_variables.insert( std::make_pair(buffer, stack[sindex].value) );
1476 
1477  for(int i=0 ; i<amount_of_args ; ++i)
1478  {
1479  buffer[0] = 'x';
1480  Sprintf(buffer+1, i+1);
1481  local_variables.insert( std::make_pair(buffer, stack[sindex + i*2].value) );
1482  }
1483  }
1484 
1485  stack[sindex-1].value = RecurrenceParsingVariablesOrFunction(false, function_name, string_value, &local_variables);
1486  calculated = true;
1487 
1488 return true;
1489 }
1490 
1491 
1492 /*
1493  we're calling a specific function
1494 
1495  function_name - name of the function
1496  amount_of_args - how many arguments there are on our stack
1497  (function must check whether this is a correct value or not)
1498  sindex - index of the first argument on the stack (sindex is greater than zero)
1499  if there aren't any arguments on the stack 'sindex' pointing on
1500  a non existend element (after the first bracket)
1501 
1502  result will be stored in 'stack[sindex-1].value'
1503  (we don't have to set the correct type of this element, it'll be set later)
1504 */
1505 void CallFunction(const std::string & function_name, int amount_of_args, int sindex)
1506 {
1507  if( GetValueOfUserDefinedFunction(function_name, amount_of_args, sindex) )
1508  return;
1509 
1510  typename FunctionsTable::iterator i = functions_table.find( function_name );
1511 
1512  if( i == functions_table.end() )
1513  Error( err_unknown_function );
1514 
1515  /*
1516  calling the specify function
1517  */
1518  (this->*(i->second))(sindex, amount_of_args, stack[sindex-1].value);
1519  calculated = true;
1520 }
1521 
1522 
1523 
1524 
1525 
1532 void InsertFunctionToTable(const char * function_name, pfunction pf)
1533 {
1534  std::string str;
1535  Misc::AssignString(str, function_name);
1536 
1537  functions_table.insert( std::make_pair(str, pf) );
1538 }
1539 
1540 
1541 
1549 void InsertVariableToTable(const char * variable_name, pfunction_var pf)
1550 {
1551  std::string str;
1552  Misc::AssignString(str, variable_name);
1553 
1554  variables_table.insert( std::make_pair(str, pf) );
1555 }
1556 
1557 
1561 void CreateFunctionsTable()
1562 {
1563  InsertFunctionToTable("gamma", &Parser<ValueType>::Gamma);
1564  InsertFunctionToTable("factorial", &Parser<ValueType>::Factorial);
1565  InsertFunctionToTable("abs", &Parser<ValueType>::Abs);
1566  InsertFunctionToTable("sin", &Parser<ValueType>::Sin);
1567  InsertFunctionToTable("cos", &Parser<ValueType>::Cos);
1568  InsertFunctionToTable("tan", &Parser<ValueType>::Tan);
1569  InsertFunctionToTable("tg", &Parser<ValueType>::Tan);
1570  InsertFunctionToTable("cot", &Parser<ValueType>::Cot);
1571  InsertFunctionToTable("ctg", &Parser<ValueType>::Cot);
1572  InsertFunctionToTable("int", &Parser<ValueType>::Int);
1573  InsertFunctionToTable("round", &Parser<ValueType>::Round);
1574  InsertFunctionToTable("ln", &Parser<ValueType>::Ln);
1575  InsertFunctionToTable("log", &Parser<ValueType>::Log);
1576  InsertFunctionToTable("exp", &Parser<ValueType>::Exp);
1577  InsertFunctionToTable("max", &Parser<ValueType>::Max);
1578  InsertFunctionToTable("min", &Parser<ValueType>::Min);
1579  InsertFunctionToTable("asin", &Parser<ValueType>::ASin);
1580  InsertFunctionToTable("acos", &Parser<ValueType>::ACos);
1581  InsertFunctionToTable("atan", &Parser<ValueType>::ATan);
1582  InsertFunctionToTable("atg", &Parser<ValueType>::ATan);
1583  InsertFunctionToTable("acot", &Parser<ValueType>::ACot);
1584  InsertFunctionToTable("actg", &Parser<ValueType>::ACot);
1585  InsertFunctionToTable("sgn", &Parser<ValueType>::Sgn);
1586  InsertFunctionToTable("mod", &Parser<ValueType>::Mod);
1587  InsertFunctionToTable("if", &Parser<ValueType>::If);
1588  InsertFunctionToTable("or", &Parser<ValueType>::Or);
1589  InsertFunctionToTable("and", &Parser<ValueType>::And);
1590  InsertFunctionToTable("not", &Parser<ValueType>::Not);
1591  InsertFunctionToTable("degtorad", &Parser<ValueType>::DegToRad);
1592  InsertFunctionToTable("radtodeg", &Parser<ValueType>::RadToDeg);
1593  InsertFunctionToTable("degtodeg", &Parser<ValueType>::DegToDeg);
1594  InsertFunctionToTable("gradtorad", &Parser<ValueType>::GradToRad);
1595  InsertFunctionToTable("radtograd", &Parser<ValueType>::RadToGrad);
1596  InsertFunctionToTable("degtograd", &Parser<ValueType>::DegToGrad);
1597  InsertFunctionToTable("gradtodeg", &Parser<ValueType>::GradToDeg);
1598  InsertFunctionToTable("ceil", &Parser<ValueType>::Ceil);
1599  InsertFunctionToTable("floor", &Parser<ValueType>::Floor);
1600  InsertFunctionToTable("sqrt", &Parser<ValueType>::Sqrt);
1601  InsertFunctionToTable("sinh", &Parser<ValueType>::Sinh);
1602  InsertFunctionToTable("cosh", &Parser<ValueType>::Cosh);
1603  InsertFunctionToTable("tanh", &Parser<ValueType>::Tanh);
1604  InsertFunctionToTable("tgh", &Parser<ValueType>::Tanh);
1605  InsertFunctionToTable("coth", &Parser<ValueType>::Coth);
1606  InsertFunctionToTable("ctgh", &Parser<ValueType>::Coth);
1607  InsertFunctionToTable("root", &Parser<ValueType>::Root);
1608  InsertFunctionToTable("asinh", &Parser<ValueType>::ASinh);
1609  InsertFunctionToTable("acosh", &Parser<ValueType>::ACosh);
1610  InsertFunctionToTable("atanh", &Parser<ValueType>::ATanh);
1611  InsertFunctionToTable("atgh", &Parser<ValueType>::ATanh);
1612  InsertFunctionToTable("acoth", &Parser<ValueType>::ACoth);
1613  InsertFunctionToTable("actgh", &Parser<ValueType>::ACoth);
1614  InsertFunctionToTable("bitand", &Parser<ValueType>::BitAnd);
1615  InsertFunctionToTable("bitor", &Parser<ValueType>::BitOr);
1616  InsertFunctionToTable("bitxor", &Parser<ValueType>::BitXor);
1617  InsertFunctionToTable("band", &Parser<ValueType>::BitAnd);
1618  InsertFunctionToTable("bor", &Parser<ValueType>::BitOr);
1619  InsertFunctionToTable("bxor", &Parser<ValueType>::BitXor);
1620  InsertFunctionToTable("sum", &Parser<ValueType>::Sum);
1621  InsertFunctionToTable("avg", &Parser<ValueType>::Avg);
1622  InsertFunctionToTable("frac", &Parser<ValueType>::Frac);
1623 }
1624 
1625 
1629 void CreateVariablesTable()
1630 {
1631  InsertVariableToTable("pi", &ValueType::SetPi);
1632  InsertVariableToTable("e", &ValueType::SetE);
1633 }
1634 
1635 
1639 int ToLowerCase(int c)
1640 {
1641  if( c>='A' && c<='Z' )
1642  return c - 'A' + 'a';
1643 
1644 return c;
1645 }
1646 
1647 
1658 bool ReadName(std::string & result)
1659 {
1660 int character;
1661 
1662 
1663  result.erase();
1664  character = *pstring;
1665 
1666  /*
1667  the first letter must be from range 'a' - 'z' or 'A' - 'Z'
1668  */
1669  if( ! (( character>='a' && character<='z' ) || ( character>='A' && character<='Z' )) )
1670  Error( err_unknown_character );
1671 
1672 
1673  do
1674  {
1675  result += static_cast<char>( character );
1676  character = * ++pstring;
1677  }
1678  while( (character>='a' && character<='z') ||
1679  (character>='A' && character<='Z') ||
1680  (character>='0' && character<='9') ||
1681  character=='_' );
1682 
1683 
1684  SkipWhiteCharacters();
1685 
1686 
1687  /*
1688  if there's a character '(' that means this name is a name of a function
1689  */
1690  if( *pstring == '(' )
1691  {
1692  ++pstring;
1693  return true;
1694  }
1695 
1696 
1697 return false;
1698 }
1699 
1700 
1705 bool TestSign(Item & result)
1706 {
1707  SkipWhiteCharacters();
1708  result.sign = false;
1709 
1710  if( *pstring == '-' || *pstring == '+' )
1711  {
1712  if( *pstring == '-' )
1713  result.sign = true;
1714 
1715  ++pstring;
1716 
1717  return true;
1718  }
1719 
1720 return false;
1721 }
1722 
1723 
1728 bool ReadVariableOrFunction(Item & result)
1729 {
1730 std::string name;
1731 bool is_it_name_of_function = ReadName(name);
1732 
1733  if( is_it_name_of_function )
1734  {
1735  /*
1736  we've read the name of a function
1737  */
1738  result.function_name = name;
1739  result.type = Item::first_bracket;
1740  result.function = true;
1741  }
1742  else
1743  {
1744  /*
1745  we've read the name of a variable and we're getting its value now
1746  */
1747  result.value = GetValueOfVariable( name );
1748  }
1749 
1750 return is_it_name_of_function;
1751 }
1752 
1753 
1754 
1755 
1759 void ReadValue(Item & result, int reading_base)
1760 {
1761 const char * new_stack_pointer;
1762 bool value_read;
1763 Conv conv;
1764 
1765  conv.base = reading_base;
1766  conv.comma = comma;
1767  conv.comma2 = comma2;
1768  conv.group = group;
1769 
1770  uint carry = result.value.FromString(pstring, conv, &new_stack_pointer, &value_read);
1771  pstring = new_stack_pointer;
1772 
1773  if( carry )
1774  Error( err_overflow );
1775 
1776  if( !value_read )
1777  Error( err_unknown_character );
1778 }
1779 
1780 
1784 bool ValueStarts(int character, int base)
1785 {
1786  if( character == comma )
1787  return true;
1788 
1789  if( comma2!=0 && character==comma2 )
1790  return true;
1791 
1792  if( Misc::CharToDigit(character, base) != -1 )
1793  return true;
1794 
1795 return false;
1796 }
1797 
1798 
1807 int ReadValueVariableOrFunction(Item & result)
1808 {
1809 bool it_was_sign = false;
1810 int character;
1811 
1812 
1813  if( TestSign(result) )
1814  // 'result.sign' was set as well
1815  it_was_sign = true;
1816 
1817  SkipWhiteCharacters();
1818  character = ToLowerCase( *pstring );
1819 
1820 
1821  if( character == 0 )
1822  {
1823  if( it_was_sign )
1824  // at the end of the string a character like '-' or '+' has left
1825  Error( err_unexpected_end );
1826 
1827  // there's the end of the string here
1828  return 1;
1829  }
1830  else
1831  if( character == '(' )
1832  {
1833  // we've got a normal bracket (not a function)
1834  result.type = Item::first_bracket;
1835  result.function = false;
1836  ++pstring;
1837 
1838  return 0;
1839  }
1840  else
1841  if( character == ')' )
1842  {
1843  // we've got a final bracket
1844  // (in this place we can find a final bracket only when there are empty brackets
1845  // without any values inside or with a sign '-' or '+' inside)
1846 
1847  if( it_was_sign )
1849 
1850  result.type = Item::last_bracket;
1851 
1852  // we don't increment 'pstring', this final bracket will be read next by the
1853  // 'ReadOperatorAndCheckFinalBracket(...)' method
1854 
1855  return 2;
1856  }
1857  else
1858  if( character == '#' )
1859  {
1860  ++pstring;
1861  SkipWhiteCharacters();
1862 
1863  // after '#' character we do not allow '-' or '+' (can be white characters)
1864  if( ValueStarts(*pstring, 16) )
1865  ReadValue( result, 16 );
1866  else
1867  Error( err_unknown_character );
1868  }
1869  else
1870  if( character == '&' )
1871  {
1872  ++pstring;
1873  SkipWhiteCharacters();
1874 
1875  // after '&' character we do not allow '-' or '+' (can be white characters)
1876  if( ValueStarts(*pstring, 2) )
1877  ReadValue( result, 2 );
1878  else
1879  Error( err_unknown_character );
1880  }
1881  else
1882  if( ValueStarts(character, base) )
1883  {
1884  ReadValue( result, base );
1885  }
1886  else
1887  if( character>='a' && character<='z' )
1888  {
1889  if( ReadVariableOrFunction(result) )
1890  // we've read the name of a function
1891  return 0;
1892  }
1893  else
1894  Error( err_unknown_character );
1895 
1896 
1897 
1898  /*
1899  we've got a value in the 'result'
1900  this value is from a variable or directly from the string
1901  */
1902  result.type = Item::numerical_value;
1903 
1904  if( result.sign )
1905  {
1906  result.value.ChangeSign();
1907  result.sign = false;
1908  }
1909 
1910 
1911 return 0;
1912 }
1913 
1914 
1915 void InsertOperatorToTable(const char * name, typename MatOperator::Type type)
1916 {
1917  operators_table.insert( std::make_pair(std::string(name), type) );
1918 }
1919 
1920 
1924 void CreateMathematicalOperatorsTable()
1925 {
1926  InsertOperatorToTable("||", MatOperator::lor);
1927  InsertOperatorToTable("&&", MatOperator::land);
1928  InsertOperatorToTable("!=", MatOperator::neq);
1929  InsertOperatorToTable("==", MatOperator::eq);
1930  InsertOperatorToTable(">=", MatOperator::get);
1931  InsertOperatorToTable("<=", MatOperator::let);
1932  InsertOperatorToTable(">", MatOperator::gt);
1933  InsertOperatorToTable("<", MatOperator::lt);
1934  InsertOperatorToTable("-", MatOperator::sub);
1935  InsertOperatorToTable("+", MatOperator::add);
1936  InsertOperatorToTable("/", MatOperator::div);
1937  InsertOperatorToTable("*", MatOperator::mul);
1938  InsertOperatorToTable("^", MatOperator::pow);
1939 }
1940 
1941 
1948 bool IsSubstring(const std::string & str1, const std::string & str2)
1949 {
1950  if( str2.length() > str1.length() )
1951  return false;
1952 
1953  for(typename std::string::size_type i=0 ; i<str2.length() ; ++i)
1954  if( str1[i] != str2[i] )
1955  return false;
1956 
1957 return true;
1958 }
1959 
1960 
1964 void ReadMathematicalOperator(Item & result)
1965 {
1966 std::string oper;
1967 typename OperatorsTable::iterator iter_old, iter_new;
1968 
1969  iter_old = operators_table.end();
1970 
1971  for( ; true ; ++pstring )
1972  {
1973  oper += *pstring;
1974  iter_new = operators_table.lower_bound(oper);
1975 
1976  if( iter_new == operators_table.end() || !IsSubstring(iter_new->first, oper) )
1977  {
1978  oper.erase( --oper.end() ); // we've got mininum one element
1979 
1980  if( iter_old != operators_table.end() && iter_old->first == oper )
1981  {
1982  result.type = Item::mat_operator;
1983  result.moperator.SetType( iter_old->second );
1984  break;
1985  }
1986 
1987  Error( err_unknown_operator );
1988  }
1989 
1990  iter_old = iter_new;
1991  }
1992 }
1993 
1994 
2000 void OperatorPercentage()
2001 {
2002  if( stack_index < 3 ||
2003  stack[stack_index-1].type != Item::numerical_value ||
2004  stack[stack_index-2].type != Item::mat_operator ||
2005  stack[stack_index-3].type != Item::numerical_value )
2006  Error(err_percent_from);
2007 
2008  ++pstring;
2009  SkipWhiteCharacters();
2010 
2011  uint c = 0;
2012  c += stack[stack_index-1].value.Div(100);
2013  c += stack[stack_index-1].value.Mul(stack[stack_index-3].value);
2014 
2015  if( c )
2016  Error(err_overflow);
2017 }
2018 
2019 
2028 int ReadOperator(Item & result)
2029 {
2030  SkipWhiteCharacters();
2031 
2032  if( *pstring == '%' )
2033  OperatorPercentage();
2034 
2035 
2036  if( *pstring == 0 )
2037  return 1;
2038  else
2039  if( *pstring == ')' )
2040  {
2041  result.type = Item::last_bracket;
2042  ++pstring;
2043  }
2044  else
2045  if( *pstring == ';' || (param_sep!=0 && *pstring==param_sep) )
2046  {
2047  result.type = Item::semicolon;
2048  ++pstring;
2049  }
2050  else
2051  if( (*pstring>='a' && *pstring<='z') || (*pstring>='A' && *pstring<='Z') )
2052  {
2053  // short mul (without any operators)
2054 
2055  result.type = Item::mat_operator;
2056  result.moperator.SetType( MatOperator::shortmul );
2057  }
2058  else
2059  ReadMathematicalOperator(result);
2060 
2061 return 0;
2062 }
2063 
2064 
2065 
2072 void MakeStandardMathematicOperation(ValueType & value1, typename MatOperator::Type mat_operator,
2073  const ValueType & value2)
2074 {
2075 uint res;
2076 
2077  calculated = true;
2078 
2079  switch( mat_operator )
2080  {
2081  case MatOperator::land:
2082  (!value1.IsZero() && !value2.IsZero()) ? value1.SetOne() : value1.SetZero();
2083  break;
2084 
2085  case MatOperator::lor:
2086  (!value1.IsZero() || !value2.IsZero()) ? value1.SetOne() : value1.SetZero();
2087  break;
2088 
2089  case MatOperator::eq:
2090  (value1 == value2) ? value1.SetOne() : value1.SetZero();
2091  break;
2092 
2093  case MatOperator::neq:
2094  (value1 != value2) ? value1.SetOne() : value1.SetZero();
2095  break;
2096 
2097  case MatOperator::lt:
2098  (value1 < value2) ? value1.SetOne() : value1.SetZero();
2099  break;
2100 
2101  case MatOperator::gt:
2102  (value1 > value2) ? value1.SetOne() : value1.SetZero();
2103  break;
2104 
2105  case MatOperator::let:
2106  (value1 <= value2) ? value1.SetOne() : value1.SetZero();
2107  break;
2108 
2109  case MatOperator::get:
2110  (value1 >= value2) ? value1.SetOne() : value1.SetZero();
2111  break;
2112 
2113  case MatOperator::sub:
2114  if( value1.Sub(value2) ) Error( err_overflow );
2115  break;
2116 
2117  case MatOperator::add:
2118  if( value1.Add(value2) ) Error( err_overflow );
2119  break;
2120 
2121  case MatOperator::mul:
2122  case MatOperator::shortmul:
2123  if( value1.Mul(value2) ) Error( err_overflow );
2124  break;
2125 
2126  case MatOperator::div:
2127  if( value2.IsZero() ) Error( err_division_by_zero );
2128  if( value1.Div(value2) ) Error( err_overflow );
2129  break;
2130 
2131  case MatOperator::pow:
2132  res = value1.Pow( value2 );
2133 
2134  if( res == 1 ) Error( err_overflow );
2135  else
2136  if( res == 2 ) Error( err_improper_argument );
2137 
2138  break;
2139 
2140  default:
2141  /*
2142  on the stack left an unknown operator but we had to recognize its before
2143  that means there's an error in our algorithm
2144  */
2145  Error( err_internal_error );
2146  }
2147 }
2148 
2149 
2150 
2151 
2164 void TryRollingUpStackWithOperatorPriority()
2165 {
2166  while( stack_index>=4 &&
2167  stack[stack_index-4].type == Item::numerical_value &&
2168  stack[stack_index-3].type == Item::mat_operator &&
2169  stack[stack_index-2].type == Item::numerical_value &&
2170  stack[stack_index-1].type == Item::mat_operator &&
2171  (
2172  (
2173  // the first operator has greater priority
2174  stack[stack_index-3].moperator.GetPriority() > stack[stack_index-1].moperator.GetPriority()
2175  ) ||
2176  (
2177  // or both operators have the same priority and the first operator is not right associative
2178  stack[stack_index-3].moperator.GetPriority() == stack[stack_index-1].moperator.GetPriority() &&
2179  stack[stack_index-3].moperator.GetAssoc() == MatOperator::non_right
2180  )
2181  )
2182  )
2183  {
2184  MakeStandardMathematicOperation(stack[stack_index-4].value,
2185  stack[stack_index-3].moperator.GetType(),
2186  stack[stack_index-2].value);
2187 
2188 
2189  /*
2190  copying the last operator and setting the stack pointer to the correct value
2191  */
2192  stack[stack_index-3] = stack[stack_index-1];
2193  stack_index -= 2;
2194  }
2195 }
2196 
2197 
2205 void TryRollingUpStack()
2206 {
2207  while( stack_index >= 3 &&
2208  stack[stack_index-3].type == Item::numerical_value &&
2209  stack[stack_index-2].type == Item::mat_operator &&
2210  stack[stack_index-1].type == Item::numerical_value )
2211  {
2212  MakeStandardMathematicOperation( stack[stack_index-3].value,
2213  stack[stack_index-2].moperator.GetType(),
2214  stack[stack_index-1].value );
2215 
2216  stack_index -= 2;
2217  }
2218 }
2219 
2220 
2225 int ReadValueVariableOrFunctionAndPushItIntoStack(Item & temp)
2226 {
2227 int code = ReadValueVariableOrFunction( temp );
2228 
2229  if( code == 0 )
2230  {
2231  if( stack_index < stack.size() )
2232  stack[stack_index] = temp;
2233  else
2234  stack.push_back( temp );
2235 
2236  ++stack_index;
2237  }
2238 
2239  if( code == 2 )
2240  // there was a final bracket, we didn't push it into the stack
2241  // (it'll be read by the 'ReadOperatorAndCheckFinalBracket' method next)
2242  code = 0;
2243 
2244 
2245 return code;
2246 }
2247 
2248 
2249 
2258 void HowManyParameters(int & size, int & index)
2259 {
2260  size = 0;
2261  index = stack_index;
2262 
2263  if( index == 0 )
2264  // we haven't put a first bracket on the stack
2266 
2267 
2268  if( stack[index-1].type == Item::first_bracket )
2269  // empty brackets
2270  return;
2271 
2272  for( --index ; index>=1 ; index-=2 )
2273  {
2274  if( stack[index].type != Item::numerical_value )
2275  {
2276  /*
2277  this element must be 'numerical_value', if not that means
2278  there's an error in our algorithm
2279  */
2280  Error( err_internal_error );
2281  }
2282 
2283  ++size;
2284 
2285  if( stack[index-1].type != Item::semicolon )
2286  break;
2287  }
2288 
2289  if( index<1 || stack[index-1].type != Item::first_bracket )
2290  {
2291  /*
2292  we haven't put a first bracket on the stack
2293  */
2295  }
2296 }
2297 
2298 
2305 void RollingUpFinalBracket()
2306 {
2307 int amount_of_parameters;
2308 int index;
2309 
2310 
2311  if( stack_index<1 ||
2312  (stack[stack_index-1].type != Item::numerical_value &&
2313  stack[stack_index-1].type != Item::first_bracket)
2314  )
2316 
2317 
2318  TryRollingUpStack();
2319  HowManyParameters(amount_of_parameters, index);
2320 
2321  // 'index' will be greater than zero
2322  // 'amount_of_parameters' can be zero
2323 
2324 
2325  if( amount_of_parameters==0 && !stack[index-1].function )
2327 
2328 
2329  bool was_sign = stack[index-1].sign;
2330 
2331 
2332  if( stack[index-1].function )
2333  {
2334  // the result of a function will be on 'stack[index-1]'
2335  // and then at the end we'll set the correct type (numerical value) of this element
2336  CallFunction(stack[index-1].function_name, amount_of_parameters, index);
2337  }
2338  else
2339  {
2340  /*
2341  there was a normal bracket (not a funcion)
2342  */
2343  if( amount_of_parameters != 1 )
2345 
2346 
2347  /*
2348  in the place where is the bracket we put the result
2349  */
2350  stack[index-1] = stack[index];
2351  }
2352 
2353 
2354  /*
2355  if there was a '-' character before the first bracket
2356  we change the sign of the expression
2357  */
2358  stack[index-1].sign = false;
2359 
2360  if( was_sign )
2361  stack[index-1].value.ChangeSign();
2362 
2363  stack[index-1].type = Item::numerical_value;
2364 
2365 
2366  /*
2367  the pointer of the stack will be pointing on the next (non-existing now) element
2368  */
2369  stack_index = index;
2370 }
2371 
2372 
2377 void PushOperatorIntoStack(Item & temp)
2378 {
2379  if( stack_index < stack.size() )
2380  stack[stack_index] = temp;
2381  else
2382  stack.push_back( temp );
2383 
2384  ++stack_index;
2385 }
2386 
2387 
2388 
2393 int ReadOperatorAndCheckFinalBracket(Item & temp)
2394 {
2395  do
2396  {
2397  if( ReadOperator(temp) == 1 )
2398  {
2399  /*
2400  the string is finished
2401  */
2402  return 1;
2403  }
2404 
2405  if( temp.type == Item::last_bracket )
2406  RollingUpFinalBracket();
2407 
2408  }
2409  while( temp.type == Item::last_bracket );
2410 
2411 return 0;
2412 }
2413 
2414 
2418 void CheckIntegrityOfStack()
2419 {
2420  for(unsigned int i=0 ; i<stack_index; ++i)
2421  {
2422  if( stack[i].type != Item::numerical_value &&
2423  stack[i].type != Item::semicolon)
2424  {
2425  /*
2426  on the stack we must only have 'numerical_value' or 'semicolon' operator
2427  if there is something another that means
2428  we probably didn't close any of the 'first' bracket
2429  */
2430  Error( err_stack_not_clear );
2431  }
2432  }
2433 }
2434 
2435 
2436 
2440 void Parse()
2441 {
2442 Item item;
2443 int result_code;
2444 
2445 
2446  while( true )
2447  {
2448  if( pstop_calculating && pstop_calculating->WasStopSignal() )
2449  Error( err_interrupt );
2450 
2451  result_code = ReadValueVariableOrFunctionAndPushItIntoStack( item );
2452 
2453  if( result_code == 0 )
2454  {
2455  if( item.type == Item::first_bracket )
2456  continue;
2457 
2458  result_code = ReadOperatorAndCheckFinalBracket( item );
2459  }
2460 
2461 
2462  if( result_code==1 || item.type==Item::semicolon )
2463  {
2464  /*
2465  the string is finished or the 'semicolon' operator has appeared
2466  */
2467 
2468  if( stack_index == 0 )
2469  Error( err_nothing_has_read );
2470 
2471  TryRollingUpStack();
2472 
2473  if( result_code == 1 )
2474  {
2475  CheckIntegrityOfStack();
2476 
2477  return;
2478  }
2479  }
2480 
2481 
2482  PushOperatorIntoStack( item );
2483  TryRollingUpStackWithOperatorPriority();
2484  }
2485 }
2486 
2497 void NormalizeStack()
2498 {
2499  if( error!=err_ok || stack_index==0 )
2500  {
2501  stack.clear();
2502  return;
2503  }
2504 
2505 
2506  /*
2507  'stack_index' tell us how many elements there are on the stack,
2508  we must resize the stack now because 'stack_index' is using only for parsing
2509  and stack has more (or equal) elements than value of 'stack_index'
2510  */
2511  stack.resize( stack_index );
2512 
2513  for(uint i=stack_index-1 ; i!=uint(-1) ; --i)
2514  {
2515  if( stack[i].type != Item::numerical_value )
2516  stack.erase( stack.begin() + i );
2517  }
2518 }
2519 
2520 
2521 public:
2522 
2523 
2527 Parser(): default_stack_size(100)
2528 {
2529  pstop_calculating = 0;
2530  puser_variables = 0;
2531  puser_functions = 0;
2532  pfunction_local_variables = 0;
2533  base = 10;
2534  deg_rad_grad = 1;
2535  error = err_ok;
2536  group = 0;
2537  comma = '.';
2538  comma2 = ',';
2539  param_sep = 0;
2540 
2541  CreateFunctionsTable();
2542  CreateVariablesTable();
2543  CreateMathematicalOperatorsTable();
2544 }
2545 
2546 
2551 {
2552  pstop_calculating = p.pstop_calculating;
2553  puser_variables = p.puser_variables;
2554  puser_functions = p.puser_functions;
2555  pfunction_local_variables = 0;
2556  base = p.base;
2557  deg_rad_grad = p.deg_rad_grad;
2558  error = p.error;
2559  group = p.group;
2560  comma = p.comma;
2561  comma2 = p.comma2;
2562  param_sep = p.param_sep;
2563 
2564  /*
2565  we don't have to call 'CreateFunctionsTable()' etc.
2566  we can only copy these tables
2567  */
2568  functions_table = p.functions_table;
2569  variables_table = p.variables_table;
2570  operators_table = p.operators_table;
2571 
2572  visited_variables = p.visited_variables;
2573  visited_functions = p.visited_functions;
2574 
2575 return *this;
2576 }
2577 
2578 
2582 Parser(const Parser<ValueType> & p): default_stack_size(p.default_stack_size)
2583 {
2584  operator=(p);
2585 }
2586 
2587 
2592 void SetBase(int b)
2593 {
2594  if( b>=2 && b<=16 )
2595  base = b;
2596 }
2597 
2598 
2605 void SetDegRadGrad(int angle)
2606 {
2607  if( angle >= 0 || angle <= 2 )
2608  deg_rad_grad = angle;
2609 }
2610 
2615 void SetStopObject(const volatile StopCalculating * ps)
2616 {
2617  pstop_calculating = ps;
2618 }
2619 
2620 
2627 void SetVariables(const Objects * pv)
2628 {
2629  puser_variables = pv;
2630 }
2631 
2632 
2639 void SetFunctions(const Objects * pf)
2640 {
2641  puser_functions = pf;
2642 }
2643 
2644 
2649 void SetGroup(int g)
2650 {
2651  group = g;
2652 }
2653 
2654 
2660 void SetComma(int c, int c2 = 0)
2661 {
2662  comma = c;
2663  comma2 = c2;
2664 }
2665 
2666 
2673 void SetParamSep(int s)
2674 {
2675  param_sep = s;
2676 }
2677 
2678 
2682 ErrorCode Parse(const char * str)
2683 {
2684  stack_index = 0;
2685  pstring = str;
2686  error = err_ok;
2687  calculated = false;
2688 
2689  stack.resize( default_stack_size );
2690 
2691  try
2692  {
2693  Parse();
2694  }
2695  catch(ErrorCode c)
2696  {
2697  error = c;
2698  calculated = false;
2699  }
2700 
2701  NormalizeStack();
2702 
2703 return error;
2704 }
2705 
2706 
2710 ErrorCode Parse(const std::string & str)
2711 {
2712  return Parse(str.c_str());
2713 }
2714 
2715 
2716 #ifndef TTMATH_DONT_USE_WCHAR
2717 
2721 ErrorCode Parse(const wchar_t * str)
2722 {
2723  Misc::AssignString(wide_to_ansi, str);
2724 
2725 return Parse(wide_to_ansi.c_str());
2726 
2727  // !! wide_to_ansi clearing can be added here
2728 }
2729 
2730 
2734 ErrorCode Parse(const std::wstring & str)
2735 {
2736  return Parse(str.c_str());
2737 }
2738 
2739 #endif
2740 
2741 
2753 {
2754  return calculated;
2755 }
2756 
2757 
2765 {
2766  cgamma.InitAll();
2767 }
2768 
2769 
2770 };
2771 
2772 
2773 
2774 } // namespace
2775 
2776 
2777 #endif
ValueType Sgn(ValueType x)
Definition: ttmath.h:2142
ValueType ACot(const ValueType &x)
Definition: ttmath.h:1129
Definition: ttmathtypes.h:366
constexpr int64_t none
Definition: BucketPQ.h:22
ValueType ACoth(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:1482
Definition: ttmathtypes.h:357
ValueType Tan(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:612
bool sign
Definition: ttmathparser.h:273
Definition: ttmathtypes.h:362
ValueType Log(const ValueType &x, const ValueType &base, ErrorCode *err=0)
Definition: ttmath.h:274
Definition: ttmathtypes.h:365
ValueType Sin(ValueType x, ErrorCode *err=0)
Definition: ttmath.h:518
Definition: ttmathtypes.h:360
void SetParamSep(int s)
Definition: ttmathparser.h:2673
static uint CharToDigit(uint c)
Definition: ttmathmisc.h:181
Definition: ttmathtypes.h:364
Definition: ttmathtypes.h:363
Definition: ttmathtypes.h:353
ErrorCode Parse(const std::wstring &str)
Definition: ttmathparser.h:2734
void SetComma(int c, int c2=0)
Definition: ttmathparser.h:2660
NetworKit::index index
Definition: BloomFilter.h:16
Definition: ttmathparser.h:243
some helpful functions
Definition: ttmathparser.h:242
std::vector< Item > stack
Definition: ttmathparser.h:296
ValueType Exp(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:319
ErrorCode Parse(const char *str)
Definition: ttmathparser.h:2682
Mathematical parser.
Definition: ttmathparser.h:138
ValueType ACosh(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:1380
ValueType RadToDeg(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:1581
ValueType ASin(ValueType x, ErrorCode *err=0)
Definition: ttmath.h:848
virtual bool WasStopSignal() const volatile
Definition: ttmathtypes.h:523
ValueType ASinh(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:1344
Item()
Definition: ttmathparser.h:275
Definition: ttmathtypes.h:352
Definition: ttmathtypes.h:370
Definition: ttmathtypes.h:372
ValueType SkipFraction(const ValueType &x)
Definition: ttmath.h:88
ValueType Cos(ValueType x, ErrorCode *err=0)
Definition: ttmath.h:574
void SetVariables(const Objects *pv)
Definition: ttmathparser.h:2627
ValueType ATanh(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:1429
ErrorCode GetValue(const std::string &name, std::string &value) const
Definition: ttmathobjects.h:389
ErrorCode Parse(const wchar_t *str)
Definition: ttmathparser.h:2721
Definition: ttmathtypes.h:356
Definition: ttmathtypes.h:371
ValueType Ln(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:233
void InitCGamma()
Definition: ttmathparser.h:2764
Parser< ValueType > & operator=(const Parser< ValueType > &p)
Definition: ttmathparser.h:2550
ValueType RadToGrad(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:1718
ValueType Abs(const ValueType &x)
Definition: ttmath.h:2126
Definition: ttmathtypes.h:359
bool Calculated()
Definition: ttmathparser.h:2752
void SetDegRadGrad(int angle)
Definition: ttmathparser.h:2605
ValueType GradToDeg(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:1800
ErrorCode
Definition: ttmathtypes.h:349
static void AssignString(std::string &result, const char *str)
Definition: ttmathmisc.h:72
void SetBase(int b)
Definition: ttmathparser.h:2592
Parser()
Definition: ttmathparser.h:2527
Definition: ttmathparser.h:242
Definition: ttmathparser.h:238
ErrorCode Parse(const std::string &str)
Definition: ttmathparser.h:2710
ValueType Root(ValueType x, const ValueType &index, ErrorCode *err=0)
Definition: ttmath.h:2067
ValueType DegToRad(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:1545
ValueType GradToRad(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:1682
Definition: ttmathtypes.h:368
void SetFunctions(const Objects *pf)
Definition: ttmathparser.h:2639
ValueType Mod(ValueType a, const ValueType &b, ErrorCode *err=0)
Definition: ttmath.h:2160
Definition: ttmathtypes.h:377
void SetStopObject(const volatile StopCalculating *ps)
Definition: ttmathparser.h:2615
ValueType ATan(ValueType x)
Definition: ttmath.h:1078
Parser(const Parser< ValueType > &p)
Definition: ttmathparser.h:2582
Definition: ttmathtypes.h:358
ValueType Coth(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:1279
ValueType Factorial(const ValueType &x, CGamma< ValueType > &cgamma, ErrorCode *err=0, const volatile StopCalculating *stop=0)
Definition: ttmath.h:2782
Definition: ttmathparser.h:243
ValueType Floor(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:185
ValueType Tanh(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:1231
ValueType Sinh(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:1167
ErrorCode GetValueAndParam(const std::string &name, std::string &value, int *param) const
Definition: ttmathobjects.h:478
MatOperator moperator
Definition: ttmathparser.h:253
Definition: ttmathobjects.h:739
ValueType Cot(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:654
bool function
Definition: ttmathparser.h:262
ValueType value
Definition: ttmathparser.h:250
ValueType DegToGrad(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:1750
ValueType Gamma(const ValueType &n, CGamma< ValueType > &cgamma, ErrorCode *err=0, const volatile StopCalculating *stop=0)
Definition: ttmath.h:2654
Mathematic functions.
ValueType Cosh(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:1199
Type type
Definition: ttmathparser.h:247
Mathematics functions.
Definition: ttmathparser.h:243
Definition: ttmathparser.h:242
ValueType Round(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:105
ValueType DegToDeg(const ValueType &d, const ValueType &m, const ValueType &s, ErrorCode *err=0)
Definition: ttmath.h:1625
Definition: ttmathparser.h:242
Definition: ttmathtypes.h:520
ValueType GetValueOfVariable(const std::string &variable_name)
Definition: ttmathparser.h:640
bool GetValueOfFunctionLocalVariable(const std::string &variable_name, ValueType &result)
Definition: ttmathparser.h:618
void SetGroup(int g)
Definition: ttmathparser.h:2649
unsigned int uint
Definition: ttmathtypes.h:163
ValueType Ceil(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:138
Type
Definition: ttmathparser.h:240
ValueType Sqrt(ValueType x, ErrorCode *err=0)
Definition: ttmath.h:1844
Definition: ttmathtypes.h:354
Definition: ttmathtypes.h:351
Definition: ttmathobjects.h:65
ValueType ACos(const ValueType &x, ErrorCode *err=0)
Definition: ttmath.h:903
std::string function_name
Definition: ttmathparser.h:265
Definition: ttmathtypes.h:355
bool GetValueOfUserDefinedVariable(const std::string &variable_name, ValueType &result)
Definition: ttmathparser.h:598
Definition: ttmathtypes.h:361