From 6c18c197c68401f267231aeac94050faf012ed5f Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Sat, 4 Jun 2011 09:15:19 -0700 Subject: [PATCH] Fixed operator parsing to return trees instead of flat representations. Fixed evaluator to not loop over equations. --- .../chaiscript/language/chaiscript_eval.hpp | 68 ++++++++-------- .../chaiscript/language/chaiscript_parser.hpp | 80 +++++++++---------- 2 files changed, 73 insertions(+), 75 deletions(-) diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 0b1a0fb..1951c6c 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -281,55 +281,53 @@ namespace chaiscript if (this->children.size() > 1) { - for (int i = static_cast(this->children.size())-3; i >= 0; i -= 2) { - Boxed_Value lhs = this->children[i]->eval(t_ss); + Boxed_Value lhs = this->children[0]->eval(t_ss); - Operators::Opers oper = Operators::to_operator(this->children[i+1]->text); + Operators::Opers oper = Operators::to_operator(this->children[1]->text); - if (oper != Operators::invalid && lhs.get_type_info().is_arithmetic() && retval.get_type_info().is_arithmetic()) - { - try { - retval = Boxed_Numeric::do_oper(oper, lhs, retval); - } catch (const std::exception &) { - throw exception::eval_error("Error with unsupported arithmetic assignment operation"); + if (oper != Operators::invalid && lhs.get_type_info().is_arithmetic() && + retval.get_type_info().is_arithmetic()) + { + try { + retval = Boxed_Numeric::do_oper(oper, lhs, retval); + } catch (const std::exception &) { + throw exception::eval_error("Error with unsupported arithmetic assignment operation"); + } + } else if (this->children[1]->text == "=") { + try { + if (lhs.is_undef()) { + retval = t_ss.call_function("clone", retval); + retval.clear_dependencies(); } - } else if (this->children[i+1]->text == "=") { - try { - if (lhs.is_undef()) { - retval = t_ss.call_function("clone", retval); - retval.clear_dependencies(); - } - try { - retval = t_ss.call_function(this->children[i+1]->text, lhs, retval); - } - catch(const exception::dispatch_error &){ - throw exception::eval_error(std::string("Mismatched types in equation") + (lhs.is_const()?", lhs is const.":".")); - } + try { + retval = t_ss.call_function(this->children[1]->text, lhs, retval); } catch(const exception::dispatch_error &){ - throw exception::eval_error("Can not clone right hand side of equation"); + throw exception::eval_error(std::string("Mismatched types in equation") + (lhs.is_const()?", lhs is const.":".")); } } - else if (this->children[i+1]->text == ":=") { - if (lhs.is_undef() || type_match(lhs, retval)) { - lhs.assign(retval); - } else { - throw exception::eval_error("Mismatched types in equation"); - } + catch(const exception::dispatch_error &){ + throw exception::eval_error("Can not clone right hand side of equation"); } - else { - try { - retval = t_ss.call_function(this->children[i+1]->text, lhs, retval); - } catch(const exception::dispatch_error &){ - throw exception::eval_error("Can not find appropriate '" + this->children[i+1]->text + "'"); - } + } + else if (this->children[1]->text == ":=") { + if (lhs.is_undef() || type_match(lhs, retval)) { + lhs.assign(retval); + } else { + throw exception::eval_error("Mismatched types in equation"); + } + } + else { + try { + retval = t_ss.call_function(this->children[1]->text, lhs, retval); + } catch(const exception::dispatch_error &){ + throw exception::eval_error("Can not find appropriate '" + this->children[1]->text + "'"); } } } return retval; } - }; struct Var_Decl_AST_Node : public AST_Node { diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index bafd4d8..217db2b 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -352,7 +352,7 @@ namespace chaiscript } /** - * Reads a floating point value from input, without skipping initial whitespace + * Reads a hex value from input, without skipping initial whitespace */ bool Hex_() { bool retval = false; @@ -385,7 +385,7 @@ namespace chaiscript } /** - * Reads a floating point value from input, without skipping initial whitespace + * Reads a binary value from input, without skipping initial whitespace */ bool Binary_() { bool retval = false; @@ -1716,45 +1716,45 @@ namespace chaiscript + std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression", File_Position(m_line, m_col), *m_filename); } - } while (Operator_Helper(t_precedence)); - switch (m_operators[t_precedence]) { - case(AST_Node_Type::Comparison) : - build_match(AST_NodePtr(new eval::Comparison_AST_Node()), prev_stack_top); - break; - case(AST_Node_Type::Dot_Access) : - build_match(AST_NodePtr(new eval::Dot_Access_AST_Node()), prev_stack_top); - break; - case(AST_Node_Type::Additive) : - build_match(AST_NodePtr(new eval::Additive_AST_Node()), prev_stack_top); - break; - case(AST_Node_Type::Multiplicative) : - build_match(AST_NodePtr(new eval::Multiplicative_AST_Node()), prev_stack_top); - break; - case(AST_Node_Type::Shift) : - build_match(AST_NodePtr(new eval::Shift_AST_Node()), prev_stack_top); - break; - case(AST_Node_Type::Equality) : - build_match(AST_NodePtr(new eval::Equality_AST_Node()), prev_stack_top); - break; - case(AST_Node_Type::Bitwise_And) : - build_match(AST_NodePtr(new eval::Bitwise_And_AST_Node()), prev_stack_top); - break; - case(AST_Node_Type::Bitwise_Xor) : - build_match(AST_NodePtr(new eval::Bitwise_Xor_AST_Node()), prev_stack_top); - break; - case(AST_Node_Type::Bitwise_Or) : - build_match(AST_NodePtr(new eval::Bitwise_Or_AST_Node()), prev_stack_top); - break; - case(AST_Node_Type::Logical_And) : - build_match(AST_NodePtr(new eval::Logical_And_AST_Node()), prev_stack_top); - break; - case(AST_Node_Type::Logical_Or) : - build_match(AST_NodePtr(new eval::Logical_Or_AST_Node()), prev_stack_top); - break; - default: - throw exception::eval_error("Internal error: unhandled ast_node", File_Position(m_line, m_col), *m_filename); - } + switch (m_operators[t_precedence]) { + case(AST_Node_Type::Comparison) : + build_match(AST_NodePtr(new eval::Comparison_AST_Node()), prev_stack_top); + break; + case(AST_Node_Type::Dot_Access) : + build_match(AST_NodePtr(new eval::Dot_Access_AST_Node()), prev_stack_top); + break; + case(AST_Node_Type::Additive) : + build_match(AST_NodePtr(new eval::Additive_AST_Node()), prev_stack_top); + break; + case(AST_Node_Type::Multiplicative) : + build_match(AST_NodePtr(new eval::Multiplicative_AST_Node()), prev_stack_top); + break; + case(AST_Node_Type::Shift) : + build_match(AST_NodePtr(new eval::Shift_AST_Node()), prev_stack_top); + break; + case(AST_Node_Type::Equality) : + build_match(AST_NodePtr(new eval::Equality_AST_Node()), prev_stack_top); + break; + case(AST_Node_Type::Bitwise_And) : + build_match(AST_NodePtr(new eval::Bitwise_And_AST_Node()), prev_stack_top); + break; + case(AST_Node_Type::Bitwise_Xor) : + build_match(AST_NodePtr(new eval::Bitwise_Xor_AST_Node()), prev_stack_top); + break; + case(AST_Node_Type::Bitwise_Or) : + build_match(AST_NodePtr(new eval::Bitwise_Or_AST_Node()), prev_stack_top); + break; + case(AST_Node_Type::Logical_And) : + build_match(AST_NodePtr(new eval::Logical_And_AST_Node()), prev_stack_top); + break; + case(AST_Node_Type::Logical_Or) : + build_match(AST_NodePtr(new eval::Logical_Or_AST_Node()), prev_stack_top); + break; + default: + throw exception::eval_error("Internal error: unhandled ast_node", File_Position(m_line, m_col), *m_filename); + } + } while (Operator_Helper(t_precedence)); } } }