Fixed operator parsing to return trees instead of flat representations. Fixed evaluator to not loop over equations.

This commit is contained in:
Jonathan Turner 2011-06-04 09:15:19 -07:00
parent f47ec0d522
commit 6c18c197c6
2 changed files with 73 additions and 75 deletions

View File

@ -281,55 +281,53 @@ namespace chaiscript
if (this->children.size() > 1) { if (this->children.size() > 1) {
for (int i = static_cast<int>(this->children.size())-3; i >= 0; i -= 2) { Boxed_Value lhs = this->children[0]->eval(t_ss);
Boxed_Value lhs = this->children[i]->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()) 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); try {
} catch (const std::exception &) { retval = Boxed_Numeric::do_oper(oper, lhs, retval);
throw exception::eval_error("Error with unsupported arithmetic assignment operation"); } 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 { try {
retval = t_ss.call_function(this->children[i+1]->text, lhs, retval); retval = t_ss.call_function(this->children[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.":"."));
}
} }
catch(const exception::dispatch_error &){ 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 == ":=") { catch(const exception::dispatch_error &){
if (lhs.is_undef() || type_match(lhs, retval)) { throw exception::eval_error("Can not clone right hand side of equation");
lhs.assign(retval);
} else {
throw exception::eval_error("Mismatched types in equation");
}
} }
else { }
try { else if (this->children[1]->text == ":=") {
retval = t_ss.call_function(this->children[i+1]->text, lhs, retval); if (lhs.is_undef() || type_match(lhs, retval)) {
} catch(const exception::dispatch_error &){ lhs.assign(retval);
throw exception::eval_error("Can not find appropriate '" + this->children[i+1]->text + "'"); } 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; return retval;
} }
}; };
struct Var_Decl_AST_Node : public AST_Node { struct Var_Decl_AST_Node : public AST_Node {

View File

@ -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 Hex_() {
bool retval = false; 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 Binary_() {
bool retval = false; bool retval = false;
@ -1716,45 +1716,45 @@ namespace chaiscript
+ std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression", + std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression",
File_Position(m_line, m_col), *m_filename); File_Position(m_line, m_col), *m_filename);
} }
} while (Operator_Helper(t_precedence));
switch (m_operators[t_precedence]) { switch (m_operators[t_precedence]) {
case(AST_Node_Type::Comparison) : case(AST_Node_Type::Comparison) :
build_match(AST_NodePtr(new eval::Comparison_AST_Node()), prev_stack_top); build_match(AST_NodePtr(new eval::Comparison_AST_Node()), prev_stack_top);
break; break;
case(AST_Node_Type::Dot_Access) : case(AST_Node_Type::Dot_Access) :
build_match(AST_NodePtr(new eval::Dot_Access_AST_Node()), prev_stack_top); build_match(AST_NodePtr(new eval::Dot_Access_AST_Node()), prev_stack_top);
break; break;
case(AST_Node_Type::Additive) : case(AST_Node_Type::Additive) :
build_match(AST_NodePtr(new eval::Additive_AST_Node()), prev_stack_top); build_match(AST_NodePtr(new eval::Additive_AST_Node()), prev_stack_top);
break; break;
case(AST_Node_Type::Multiplicative) : case(AST_Node_Type::Multiplicative) :
build_match(AST_NodePtr(new eval::Multiplicative_AST_Node()), prev_stack_top); build_match(AST_NodePtr(new eval::Multiplicative_AST_Node()), prev_stack_top);
break; break;
case(AST_Node_Type::Shift) : case(AST_Node_Type::Shift) :
build_match(AST_NodePtr(new eval::Shift_AST_Node()), prev_stack_top); build_match(AST_NodePtr(new eval::Shift_AST_Node()), prev_stack_top);
break; break;
case(AST_Node_Type::Equality) : case(AST_Node_Type::Equality) :
build_match(AST_NodePtr(new eval::Equality_AST_Node()), prev_stack_top); build_match(AST_NodePtr(new eval::Equality_AST_Node()), prev_stack_top);
break; break;
case(AST_Node_Type::Bitwise_And) : case(AST_Node_Type::Bitwise_And) :
build_match(AST_NodePtr(new eval::Bitwise_And_AST_Node()), prev_stack_top); build_match(AST_NodePtr(new eval::Bitwise_And_AST_Node()), prev_stack_top);
break; break;
case(AST_Node_Type::Bitwise_Xor) : case(AST_Node_Type::Bitwise_Xor) :
build_match(AST_NodePtr(new eval::Bitwise_Xor_AST_Node()), prev_stack_top); build_match(AST_NodePtr(new eval::Bitwise_Xor_AST_Node()), prev_stack_top);
break; break;
case(AST_Node_Type::Bitwise_Or) : case(AST_Node_Type::Bitwise_Or) :
build_match(AST_NodePtr(new eval::Bitwise_Or_AST_Node()), prev_stack_top); build_match(AST_NodePtr(new eval::Bitwise_Or_AST_Node()), prev_stack_top);
break; break;
case(AST_Node_Type::Logical_And) : case(AST_Node_Type::Logical_And) :
build_match(AST_NodePtr(new eval::Logical_And_AST_Node()), prev_stack_top); build_match(AST_NodePtr(new eval::Logical_And_AST_Node()), prev_stack_top);
break; break;
case(AST_Node_Type::Logical_Or) : case(AST_Node_Type::Logical_Or) :
build_match(AST_NodePtr(new eval::Logical_Or_AST_Node()), prev_stack_top); build_match(AST_NodePtr(new eval::Logical_Or_AST_Node()), prev_stack_top);
break; break;
default: default:
throw exception::eval_error("Internal error: unhandled ast_node", File_Position(m_line, m_col), *m_filename); throw exception::eval_error("Internal error: unhandled ast_node", File_Position(m_line, m_col), *m_filename);
} }
} while (Operator_Helper(t_precedence));
} }
} }
} }