Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "AExpression.h"
- #include "AScope.h"
- #include <sstream>
- #include <algorithm>
- template <typename numeraltype> numeraltype ConvertToNumeral( std::string number )
- {
- numeraltype value;
- std::stringstream stream(number);
- stream >> value;
- return value;
- }
- template <typename numeraltype> std::string ConvertToString(numeraltype value)
- {
- std::ostringstream result;
- result << value;
- return result.str();
- }
- template <typename numeraltype> bool ConvertToBool(numeraltype value)
- {
- if (value == numeraltype(0))
- return false;
- return true;
- }
- template <typename numeraltype> void AExpression<numeraltype>::reset()
- {
- _is_conditional = false;
- _is_constant = false;
- _is_function = false;
- _is_variable = false;
- _operator_stack.clear();
- _value_stack.clear();
- }
- template <typename numeraltype> AExpression<numeraltype>::AExpression( std::string expression_string )
- {
- init( expression_string );
- }
- template <typename numeraltype> AExpression<numeraltype>::AExpression( std::string expression_string, AScope<numeraltype> * ascope )
- {
- _ascope = ascope;
- expression_string = processScopeTokens(expression_string);
- init( expression_string );
- }
- template <typename numeraltype> void AExpression<numeraltype>::setScope(AScope<numeraltype> * ascope)
- {
- _ascope = ascope;
- }
- template <typename numeraltype> std::string AExpression<numeraltype>::processScopeTokens(std::string expression_string)
- {
- int token_pos;
- for (int i = 0; i < _ascope->_variable_names.size(); i++)
- {
- std::string token = _ascope->_variable_names[i];
- token_pos = expression_string.find(token);
- while (token_pos != std::string::npos)
- {
- expression_string = expression_string.replace(token_pos, token.length(), "`v"+ConvertToString(i)+"`" );
- token_pos = expression_string.find(token);
- }
- }
- for (int i = 0; i < _ascope->_function0_names.size(); i++)
- {
- std::string token = _ascope->_function0_names[i];
- token_pos = expression_string.find(token);
- while (token_pos != std::string::npos)
- {
- expression_string = expression_string.replace(token_pos, token.length(), "`f0"+ConvertToString(i) );
- token_pos = expression_string.find(token);
- }
- }
- for (int i = 0; i < _ascope->_function1_names.size(); i++)
- {
- std::string token = _ascope->_function1_names[i];
- token_pos = expression_string.find(token);
- while (token_pos != std::string::npos)
- {
- expression_string = expression_string.replace(token_pos, token.length(), "`f1"+ConvertToString(i) );
- token_pos = expression_string.find(token);
- }
- }
- for (int i = 0; i < _ascope->_function2_names.size(); i++)
- {
- std::string token = _ascope->_function2_names[i];
- token_pos = expression_string.find(token);
- while (token_pos != std::string::npos)
- {
- expression_string = expression_string.replace(token_pos, token.length(), "`f2"+ConvertToString(i) );
- token_pos = expression_string.find(token);
- }
- }
- for (int i = 0; i < _ascope->_function3_names.size(); i++)
- {
- std::string token = _ascope->_function3_names[i];
- token_pos = expression_string.find(token);
- while (token_pos != std::string::npos)
- {
- expression_string = expression_string.replace(token_pos, token.length(), "`f3"+ConvertToString(i) );
- token_pos = expression_string.find(token);
- }
- }
- for (int i = 0; i < _ascope->_function4_names.size(); i++)
- {
- std::string token = _ascope->_function4_names[i];
- token_pos = expression_string.find(token);
- while (token_pos != std::string::npos)
- {
- expression_string = expression_string.replace(token_pos, token.length(), "`f4"+ConvertToString(i) );
- token_pos = expression_string.find(token);
- }
- }
- for (int i = 0; i < _ascope->_function5_names.size(); i++)
- {
- std::string token = _ascope->_function5_names[i];
- token_pos = expression_string.find(token);
- while (token_pos != std::string::npos)
- {
- expression_string = expression_string.replace(token_pos, token.length(), "`f5"+ConvertToString(i) );
- token_pos = expression_string.find(token);
- }
- }
- return expression_string;
- }
- template <typename numeraltype> void AExpression<numeraltype>::pushOperator(AOperator oper)
- {
- _operator_stack.push_back(oper);
- }
- template <typename numeraltype> void AExpression<numeraltype>::pushOperand(AExpression<numeraltype> value)
- {
- _value_stack.push_back(value);
- }
- template <typename numeraltype> bool AExpression<numeraltype>::isConstant()
- {
- if (_is_function || _is_variable || _is_conditional)
- {
- return false;
- }
- for (auto & e : _value_stack)
- {
- if (!e.isConstant())
- return false;
- }
- return true;
- }
- template <typename numeraltype> void AExpression<numeraltype>::init( std::string expression_string )
- {
- while (expression_string.find("IF")!=std::string::npos)
- expression_string = expression_string.replace(expression_string.find("IF"), 2, "~");
- while (expression_string.find("THEN")!=std::string::npos)
- expression_string = expression_string.replace(expression_string.find("THEN"), 4, "?");
- while (expression_string.find("ELSE")!=std::string::npos)
- expression_string = expression_string.replace(expression_string.find("ELSE"), 4, ":");
- _expression_string = expression_string;
- _expression_string = expression_string;
- _is_constant = false;
- int parantheses_normalizer = 0;
- int func_bracket_normalizer = 0;
- int if_else_normalizer = 0;
- int if_endif_normalizer = 0;
- int if_then_normalizer = 0;
- bool is_sub_expression = false;
- std::string last_token_value;
- std::string token;
- std::string a_operator;
- std::string sub_expression;
- AOperator last_operator = A_NO_OPERATOR;
- std::string character;
- TokenType last_token = OPERATOR;
- bool var_or_func_coming = false;
- bool is_var = false, is_func = false;
- int func_param_count;
- int func_ptr_index;
- for (int char_position = 0; char_position < expression_string.length() ; char_position++)
- {
- character = expression_string[char_position];
- if (character == " " || character == "\n" || character == "\t") continue;
- if (last_token == OPERATOR)
- {
- if (var_or_func_coming)
- {
- if (character == "v")
- {
- is_var = true;
- }
- if (character == "f")
- {
- is_func = true;
- func_param_count = ConvertToNumeral<int>(expression_string.substr(++char_position, 1));
- while (expression_string.substr(++char_position, 1) != _ascope->_parameter_list_open)
- {
- token.append(expression_string.substr(char_position, 1));
- }
- char_position--;
- func_ptr_index = ConvertToNumeral<int>(token);
- token = "";
- }
- var_or_func_coming = false;
- continue;
- }
- if (character == "`" && !is_sub_expression)
- {
- if (is_var)
- {
- is_var = false;
- AExpression<numeraltype> var_expression;
- var_expression.setScope(_ascope);
- var_expression.setAsVar(ConvertToNumeral<int>(token));
- pushOperand(var_expression);
- last_token_value = "";
- token = "";
- last_token = OPERAND;
- continue;
- }
- var_or_func_coming = true;
- continue;
- }
- if (is_var)
- {
- token.append(character);
- continue;
- }
- if (character == "~" && !is_sub_expression)
- {
- if_endif_normalizer ++;
- if_then_normalizer ++;
- if_else_normalizer ++;
- token = "";
- AExpression<numeraltype> cond_expr;
- cond_expr.setScope(_ascope);
- cond_expr.setAsCond();
- bool got_condition = false, got_then = false, got_else = false;
- while (if_endif_normalizer != 0 && char_position+1 != expression_string.length())
- {
- char_position ++;
- character = expression_string[char_position];
- if (character == "~")
- {
- if_endif_normalizer++;
- if_then_normalizer++;
- if_else_normalizer++;
- }
- if (character == "?")
- if_then_normalizer--;
- if (character == ":")
- if_else_normalizer--;
- if (character == ";")
- if_endif_normalizer--;
- if (if_endif_normalizer == 0 && !got_condition)
- {
- AExpression<numeraltype> then_expr;
- then_expr.setScope(_ascope);
- then_expr.init(token);
- cond_expr.pushOperand(then_expr);
- token = "";
- got_condition = true;
- continue;
- }
- if (if_else_normalizer == 0 && !got_else)
- {
- AExpression<numeraltype> else_expr;
- else_expr.setScope(_ascope);
- else_expr.init(token);
- cond_expr.pushOperand(else_expr);
- token = "";
- got_else = true;
- continue;
- }
- if (if_then_normalizer == 0 && !got_then)
- {
- AExpression<numeraltype> if_expr;
- if_expr.setScope(_ascope);
- if_expr.init(token);
- cond_expr.pushOperand(if_expr);
- token = "";
- got_then = true;
- continue;
- }
- token.append(character);
- }
- pushOperand(cond_expr);
- if_endif_normalizer=0;
- if_then_normalizer=0;
- if_else_normalizer=0;
- last_token_value = "";
- continue;
- }
- if (character == "(" || (is_func && character == _ascope->_parameter_list_open))
- {
- if (is_func)
- func_bracket_normalizer++;
- else
- parantheses_normalizer++;
- if (!is_sub_expression)
- {
- is_sub_expression = true;
- continue;
- }
- }
- if (is_func)
- {
- if (character == _ascope->_parameter_list_close)
- {
- func_bracket_normalizer--;
- if (is_sub_expression && func_bracket_normalizer == 0)
- {
- is_sub_expression = false;
- AExpression func_call, param;
- func_call.setAsFunc(func_ptr_index, func_param_count);
- func_call.setScope(_ascope);
- for (int i = 0; i < func_param_count; i++)
- {
- param.setScope(_ascope);
- param.init(_ascope->getFuncParameter(token, i));
- func_call.pushOperand(param);
- }
- pushOperand(func_call);
- last_token_value = "";
- token = "";
- last_token = OPERAND;
- continue;
- }
- }
- }
- else
- {
- if (character == ")")
- {
- parantheses_normalizer--;
- if (is_sub_expression && parantheses_normalizer == 0)
- {
- is_sub_expression = false;
- AExpression<numeraltype> sub_expression;
- sub_expression.setScope(_ascope);
- sub_expression.init(token);
- _value_stack.push_back(sub_expression);
- last_token_value = token;
- token = "";
- last_token = OPERAND;
- continue;
- }
- }
- }
- if ((is_sub_expression || isValidOperandCharacter(character[0]) || (isMinus(character[0]) && token == "")) )
- {
- token.append(character);
- last_token_value = token;
- }
- else
- {
- AExpression<numeraltype> the_operand(token);
- _value_stack.push_back(the_operand);
- last_token_value = token;
- char_position--;
- last_token = OPERAND;
- token = "";
- }
- }
- else if (last_token == OPERAND)
- {
- if (token == "")
- {
- token.append(character);
- continue;
- }
- else if (token == "+")
- {
- _operator_stack.push_back(A_ADD);
- last_operator = A_ADD;
- char_position--;
- }
- else if (token == "-")
- {
- _operator_stack.push_back(A_SUB);
- last_operator = A_SUB;
- char_position--;
- }
- else if (token == "/")
- {
- _operator_stack.push_back(A_DIV);
- char_position--;
- last_operator = A_DIV;
- }
- else if (token == "*")
- {
- _operator_stack.push_back(A_MUL);
- char_position--;
- last_operator = A_MUL;
- }
- else if (token == "%")
- {
- _operator_stack.push_back(A_MOD);
- char_position--;
- last_operator = A_MOD;
- }
- else if (token == ">")
- {
- if (character == "=")
- {
- _operator_stack.push_back(A_GEQ);
- last_operator = A_GEQ;
- }
- else
- {
- _operator_stack.push_back(A_GRT);
- last_operator = A_GRT;
- char_position--;
- }
- }
- else if (token == "<")
- {
- if (character == "=")
- {
- _operator_stack.push_back(A_SEQ);
- last_operator = A_SEQ;
- }
- else
- {
- _operator_stack.push_back(A_SML);
- last_operator = A_SML;
- char_position--;
- }
- }
- else if (token == "!")
- {
- if (character == "=")
- {
- _operator_stack.push_back(A_NEQ);
- last_operator = A_NEQ;
- }
- else
- {
- _operator_stack.push_back(A_NOT);
- last_operator = A_NOT;
- char_position--;
- }
- }
- else if (token == "=")
- {
- if (character == "=")
- {
- _operator_stack.push_back(A_EQS);
- last_operator = A_EQS;
- }
- }
- token = "";
- last_token = OPERATOR;
- }
- }
- _is_constant = _operator_stack.size() == 0 && isConstant();
- if (_is_constant)
- _constant_value = ConvertToNumeral<numeraltype>(last_token_value);
- if (_operator_stack.size() > 0 && last_token_value != "")
- {
- AExpression<numeraltype> the_operand(last_token_value);
- _value_stack.push_back(the_operand);
- }
- this->handlePrecedenceOfOperators();
- }
- template <typename numeraltype> AExpression<numeraltype>::~AExpression()
- {
- //dtor
- }
- template <typename numeraltype> AExpression<numeraltype>::AExpression()
- {
- //dtor
- }
- template <typename numeraltype> void AExpression<numeraltype>::setAsCond()
- {
- _is_conditional = true;
- }
- template <typename numeraltype> void AExpression<numeraltype>::setAsVar(int var_ptr_index)
- {
- _is_variable = true;
- _scope_ptr_index = var_ptr_index;
- }
- template <typename numeraltype> void AExpression<numeraltype>::setAsFunc(int func_ptr_index, unsigned int param_count)
- {
- _is_function = true;
- _scope_ptr_index = func_ptr_index;
- _func_param_count = param_count;
- }
- template <typename numeraltype> void AExpression<numeraltype>::handlePrecedenceOfOperators()
- {
- int highest_precedence = 0;
- int group_index;
- AExpression<numeraltype> sub;
- int operand_index = 0;
- for (int operator_index = 0; operator_index < _operator_stack.size(); operator_index++)
- {
- group_index = getGroupIndex(_operator_stack[operator_index]);
- if (group_index != -1 && group_index > highest_precedence)
- {
- highest_precedence = group_index;
- operand_index ++;
- }
- else if (group_index != -1 && group_index < highest_precedence)
- {
- sub.pushOperator(_operator_stack[operator_index]);
- switch(group_index)
- {
- case 0:
- _operator_stack.erase(_operator_stack.begin()+operator_index, _operator_stack.begin()+operator_index+1);
- break;
- default:
- _operator_stack.erase(_operator_stack.begin()+operator_index, _operator_stack.begin()+operator_index+1);
- sub.pushOperand(_value_stack[operand_index]);
- sub.pushOperand(_value_stack[operand_index+1]);
- /*int temp_operator_index = operator_index;
- while ( temp_operator_index+1 < _operator_stack.size() )
- {
- a
- }*/
- _value_stack.erase(_value_stack.begin()+operand_index+1, _value_stack.begin()+operand_index+2);
- _value_stack[operand_index] = sub;
- sub.reset();
- operator_index --;
- }
- }
- else if (group_index != -1)
- {
- switch(group_index)
- {
- case 0:
- _operator_stack.erase(_operator_stack.begin()+operator_index, _operator_stack.begin()+operator_index+1);
- break;
- default:
- operand_index += 2;
- }
- // break;
- }
- }
- }
- template <typename numeraltype> int AExpression<numeraltype>::getGroupIndex(AOperator oper)
- {
- std::vector<AOperator> g0 = {A_NOT};
- std::vector<AOperator> g1 = {A_DIV, A_MUL, A_MOD};
- std::vector<AOperator> g2 = {A_ADD, A_SUB};
- std::vector<AOperator> g3 = {A_GRT, A_SML, A_GEQ, A_SEQ};
- std::vector<AOperator> g4 = {A_EQS, A_NEQ};
- std::vector<AOperator> g5 = {A_AND};
- std::vector<AOperator> g6 = {A_OR};
- std::vector<AOperator> g7 = {A_IF, A_THN, A_ELS, A_EDF};
- std::vector< std::vector<AOperator>* > groups = {&g0, &g1, &g2, &g3, &g4, &g5, &g6, &g7};
- for (int i = 0; i < groups.size(); i++)
- {
- std::vector<AOperator> group = *groups[i];
- if ( any_of(group.begin(), group.end(), [oper](int a)
- {
- return oper == a;
- }) )
- return i;
- }
- return -1;
- }
- template <typename numeraltype> bool AExpression<numeraltype>::isValidOperandCharacter( char c )
- {
- return isdigit( (int)c) || c == '.';
- }
- template <typename numeraltype> bool AExpression<numeraltype>::isMinus(char c)
- {
- return c == '-';
- }
- template <typename numeraltype> int wordInStringVector(std::vector<std::string> string_vector, std::string word, bool * fullword)
- {
- if (string_vector.size() == 0)
- {
- *fullword = false;
- return 0;
- }
- *fullword = true;
- int common_chr_count = 0;
- for ( auto & w : string_vector )
- {
- for (int i = 0; i < w.length(); i++)
- {
- if (i >= word.length())
- {
- *fullword = false;
- break;
- }
- if (w[i] == word[i])
- common_chr_count ++;
- else
- {
- *fullword = false;
- break;
- }
- }
- }
- return 0;
- }
- template <typename numeraltype> inline void AExpression<numeraltype>::evalOperations()
- {
- _final_value = _value_stack[0].evaluate();
- int currend_operand = 1;
- for (int operator_index = 0; operator_index < _operator_stack.size(); operator_index ++)
- {
- switch (_operator_stack[operator_index])
- {
- case A_ADD:
- _final_value += _value_stack[currend_operand++].evaluate();
- break;
- case A_SUB:
- _final_value -= _value_stack[currend_operand++].evaluate();
- break;
- case A_DIV:
- _final_value /= _value_stack[currend_operand++].evaluate();
- break;
- case A_MUL:
- _final_value *= _value_stack[currend_operand++].evaluate();
- break;
- case A_MOD:
- numeraltype n;
- n = _value_stack[currend_operand++].evaluate();
- _final_value = _final_value - n * numeraltype(floor(_final_value/n));
- break;
- case A_SML:
- if (_final_value < _value_stack[currend_operand++].evaluate())
- _final_value = numeraltype(1);
- else
- _final_value = numeraltype(0);
- break;
- case A_GRT:
- if (_final_value > _value_stack[currend_operand++].evaluate())
- _final_value = numeraltype(1);
- else
- _final_value = numeraltype(0);
- break;
- case A_SEQ:
- if (_final_value <= _value_stack[currend_operand++].evaluate())
- _final_value = numeraltype(1);
- else
- _final_value = numeraltype(0);
- break;
- case A_GEQ:
- if (_final_value >= _value_stack[currend_operand++].evaluate())
- _final_value = numeraltype(1);
- else
- _final_value = numeraltype(0);
- break;
- case A_EQS:
- if (_final_value == _value_stack[currend_operand++].evaluate())
- _final_value = numeraltype(1);
- else
- _final_value = numeraltype(0);
- break;
- case A_NEQ:
- if (_final_value != _value_stack[currend_operand++].evaluate())
- _final_value = numeraltype(1);
- else
- _final_value = numeraltype(0);
- break;
- }
- }
- }
- template <typename numeraltype> inline void AExpression<numeraltype>::evalVarsFuncsConds(AScope<numeraltype> * scope)
- {
- if (_is_variable)
- {
- _final_value = _ascope->getVariableValue( _scope_ptr_index );
- }
- else if (_is_conditional)
- {
- if (ConvertToBool<numeraltype>(_value_stack[0].evaluate()))
- {
- _final_value = _value_stack[1].evaluate();
- }
- else
- {
- _final_value = _value_stack[2].evaluate();
- }
- }
- else if (_is_function)
- {
- switch (_func_param_count)
- {
- case 0:
- _final_value = _ascope->getFunction0Value(_scope_ptr_index);
- break;
- case 1:
- _final_value = _ascope->getFunction1Value(_scope_ptr_index,
- _value_stack[0].evaluate()
- );
- break;
- case 2:
- _final_value = _ascope->getFunction2Value(_scope_ptr_index,
- _value_stack[0].evaluate(),
- _value_stack[1].evaluate()
- );
- break;
- case 3:
- _final_value = _ascope->getFunction3Value(_scope_ptr_index,
- _value_stack[0].evaluate(),
- _value_stack[1].evaluate(),
- _value_stack[2].evaluate()
- );
- break;
- case 4:
- _final_value = _ascope->getFunction4Value(_scope_ptr_index,
- _value_stack[0].evaluate(),
- _value_stack[1].evaluate(),
- _value_stack[2].evaluate(),
- _value_stack[3].evaluate()
- );
- break;
- case 5:
- _final_value = _ascope->getFunction5Value(_scope_ptr_index,
- _value_stack[0].evaluate(),
- _value_stack[1].evaluate(),
- _value_stack[2].evaluate(),
- _value_stack[3].evaluate(),
- _value_stack[4].evaluate()
- );
- break;
- default:
- ;
- }
- }
- }
- template <typename numeraltype> numeraltype AExpression<numeraltype>::evaluate()
- {
- if (_is_constant)
- {
- _final_value = _constant_value;
- return _constant_value;
- }
- else if (_is_variable || _is_conditional || _is_function)
- {
- evalVarsFuncsConds(_ascope);
- }
- else
- {
- evalOperations();
- }
- return _final_value;
- }
- template <typename numeraltype> numeraltype AExpression<numeraltype>::getFinalValue()
- {
- return _final_value;
- }
- template class AExpression<float>;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement