diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 3efe902e..cda76711 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -32,22 +32,24 @@ namespace chaiscript /// Types of AST nodes available to the parser and eval - enum class AST_Node_Type { Error, Id, Eol, Fun_Call, Arg_List, Variable, Equation, Var_Decl, - Comparison, Addition, Subtraction, Multiplication, Division, Modulus, Array_Call, Dot_Access, + enum class AST_Node_Type { Id, Fun_Call, Arg_List, Equation, Var_Decl, + Array_Call, Dot_Access, Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range, - Inline_Range, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or, + Inline_Range, Try, Catch, Finally, Method, Attr_Decl, Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond, Noop, Class, Binary, Arg, Global_Decl, Constant }; + enum class Operator_Precidence { Ternary_Cond, Logical_Or, Logical_And, Bitwise_Or, Bitwise_Xor, Bitwise_And, Equality, Comparison, Shift, Addition, Multiplication }; + namespace { /// Helper lookup to get the name of each node type const char *ast_node_type_to_string(AST_Node_Type ast_node_type) { - static const char * const ast_node_types[] = { "Internal Parser Error", "Id", "Eol", "Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl", - "Comparison", "Addition", "Subtraction", "Multiplication", "Division", "Modulus", "Array_Call", "Dot_Access", + static const char * const ast_node_types[] = { "Id", "Fun_Call", "Arg_List", "Equation", "Var_Decl", + "Array_Call", "Dot_Access", "Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range", - "Inline_Range", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or", + "Inline_Range", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Ternary Condition", "Noop", "Class", "Binary", "Arg", "Constant"}; return ast_node_types[static_cast(ast_node_type)]; diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 2377d1e1..fec5458a 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -146,19 +146,19 @@ namespace chaiscript } - static const std::array &create_operators() { - static const std::array operators = { { - AST_Node_Type::Ternary_Cond, - AST_Node_Type::Logical_Or, - AST_Node_Type::Logical_And, - AST_Node_Type::Bitwise_Or, - AST_Node_Type::Bitwise_Xor, - AST_Node_Type::Bitwise_And, - AST_Node_Type::Equality, - AST_Node_Type::Comparison, - AST_Node_Type::Shift, - AST_Node_Type::Addition, - AST_Node_Type::Multiplication + static const std::array &create_operators() { + static const std::array operators = { { + Operator_Precidence::Ternary_Cond, + Operator_Precidence::Logical_Or, + Operator_Precidence::Logical_And, + Operator_Precidence::Bitwise_Or, + Operator_Precidence::Bitwise_Xor, + Operator_Precidence::Bitwise_And, + Operator_Precidence::Equality, + Operator_Precidence::Comparison, + Operator_Precidence::Shift, + Operator_Precidence::Addition, + Operator_Precidence::Multiplication } }; return operators; } @@ -170,7 +170,7 @@ namespace chaiscript const std::array, detail::max_alphabet> &m_alphabet = create_alphabet(); const std::vector> &m_operator_matches = create_operator_matches(); - const std::array &m_operators = create_operators(); + const std::array &m_operators = create_operators(); std::shared_ptr m_filename; std::vector m_match_stack; @@ -881,11 +881,11 @@ namespace chaiscript { string_type &match; typedef typename string_type::value_type char_type; - bool is_escaped; - bool is_interpolated; - bool saw_interpolation_marker; - bool is_octal; - bool is_hex; + bool is_escaped = false; + bool is_interpolated = false; + bool saw_interpolation_marker = false; + bool is_octal = false; + bool is_hex = false; const bool interpolation_allowed; string_type octal_matches; @@ -893,11 +893,6 @@ namespace chaiscript Char_Parser(string_type &t_match, const bool t_interpolation_allowed) : match(t_match), - is_escaped(false), - is_interpolated(false), - saw_interpolation_marker(false), - is_octal(false), - is_hex(false), interpolation_allowed(t_interpolation_allowed) { } @@ -1034,13 +1029,11 @@ namespace chaiscript if (*s == '{') { //We've found an interpolation point + m_match_stack.push_back(make_node(match, start.line, start.col, const_var(match))); + if (cparser.is_interpolated) { //If we've seen previous interpolation, add on instead of making a new one - m_match_stack.push_back(make_node(match, start.line, start.col, const_var(match))); - build_match(prev_stack_top, "+"); - } else { - m_match_stack.push_back(make_node(match, start.line, start.col, const_var(match))); } //We've finished with the part of the string up to this point, so clear it @@ -1091,13 +1084,12 @@ namespace chaiscript return cparser.is_interpolated; }(); - if (is_interpolated) { - m_match_stack.push_back(make_node(match, start.line, start.col, const_var(match))); + m_match_stack.push_back(make_node(match, start.line, start.col, const_var(match))); + if (is_interpolated) { build_match(prev_stack_top, "+"); - } else { - m_match_stack.push_back(make_node(match, start.line, start.col, const_var(match))); } + return true; } else { return false; @@ -1302,14 +1294,13 @@ namespace chaiscript if (Arg(false)) { retval = true; while (Eol()) {} - if (Char(',')) { - do { - while (Eol()) {} - if (!Arg(false)) { - throw exception::eval_error("Unexpected value in parameter list", File_Position(m_position.line, m_position.col), *m_filename); - } - } while (Char(',')); - } + + while (Char(',')) { + while (Eol()) {} + if (!Arg(false)) { + throw exception::eval_error("Unexpected value in parameter list", File_Position(m_position.line, m_position.col), *m_filename); + } + } } build_match(prev_stack_top); @@ -1328,13 +1319,12 @@ namespace chaiscript if (Arg()) { retval = true; while (Eol()) {} - if (Char(',')) { - do { - while (Eol()) {} - if (!Arg()) { - throw exception::eval_error("Unexpected value in parameter list", File_Position(m_position.line, m_position.col), *m_filename); - } - } while (Char(',')); + + while (Char(',')) { + while (Eol()) {} + if (!Arg()) { + throw exception::eval_error("Unexpected value in parameter list", File_Position(m_position.line, m_position.col), *m_filename); + } } } build_match(prev_stack_top); @@ -1355,13 +1345,11 @@ namespace chaiscript if (Equation()) { retval = true; while (Eol()) {} - if (Char(',')) { - do { - while (Eol()) {} - if (!Equation()) { - throw exception::eval_error("Unexpected value in parameter list", File_Position(m_position.line, m_position.col), *m_filename); - } - } while (Char(',')); + while (Char(',')) { + while (Eol()) {} + if (!Equation()) { + throw exception::eval_error("Unexpected value in parameter list", File_Position(m_position.line, m_position.col), *m_filename); + } } } @@ -1385,25 +1373,21 @@ namespace chaiscript } else if (Map_Pair()) { retval = true; while (Eol()) {} - if (Char(',')) { - do { - while (Eol()) {} - if (!Map_Pair()) { - throw exception::eval_error("Unexpected value in container", File_Position(m_position.line, m_position.col), *m_filename); - } - } while (Char(',')); + while (Char(',')) { + while (Eol()) {} + if (!Map_Pair()) { + throw exception::eval_error("Unexpected value in container", File_Position(m_position.line, m_position.col), *m_filename); + } } build_match(prev_stack_top); } else if (Operator()) { retval = true; while (Eol()) {} - if (Char(',')) { - do { - while (Eol()) {} - if (!Operator()) { - throw exception::eval_error("Unexpected value in container", File_Position(m_position.line, m_position.col), *m_filename); - } - } while (Char(',')); + while (Char(',')) { + while (Eol()) {} + if (!Operator()) { + throw exception::eval_error("Unexpected value in container", File_Position(m_position.line, m_position.col), *m_filename); + } } build_match(prev_stack_top); } @@ -2142,36 +2126,33 @@ namespace chaiscript while (Operator_Helper(t_precedence, oper)) { while (Eol()) {} if (!Operator(t_precedence+1)) { - throw exception::eval_error("Incomplete " - + std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression", + throw exception::eval_error("Incomplete '" + oper + "' expression", File_Position(m_position.line, m_position.col), *m_filename); } switch (m_operators[t_precedence]) { - case(AST_Node_Type::Ternary_Cond) : + case(Operator_Precidence::Ternary_Cond) : if (Symbol(":")) { if (!Operator(t_precedence+1)) { - throw exception::eval_error("Incomplete " - + std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression", + throw exception::eval_error("Incomplete '" + oper + "' expression", File_Position(m_position.line, m_position.col), *m_filename); } build_match(prev_stack_top); } else { - throw exception::eval_error("Incomplete " - + std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression", + throw exception::eval_error("Incomplete '" + oper + "' expression", File_Position(m_position.line, m_position.col), *m_filename); } break; - case(AST_Node_Type::Addition) : - case(AST_Node_Type::Multiplication) : - case(AST_Node_Type::Shift) : - case(AST_Node_Type::Equality) : - case(AST_Node_Type::Bitwise_And) : - case(AST_Node_Type::Bitwise_Xor) : - case(AST_Node_Type::Bitwise_Or) : - case(AST_Node_Type::Comparison) : + case(Operator_Precidence::Addition) : + case(Operator_Precidence::Multiplication) : + case(Operator_Precidence::Shift) : + case(Operator_Precidence::Equality) : + case(Operator_Precidence::Bitwise_And) : + case(Operator_Precidence::Bitwise_Xor) : + case(Operator_Precidence::Bitwise_Or) : + case(Operator_Precidence::Comparison) : { bool folded = false; const auto size = m_match_stack.size(); @@ -2205,10 +2186,10 @@ namespace chaiscript break; - case(AST_Node_Type::Logical_And) : + case(Operator_Precidence::Logical_And) : build_match(prev_stack_top, oper); break; - case(AST_Node_Type::Logical_Or) : + case(Operator_Precidence::Logical_Or) : build_match(prev_stack_top, oper); break; diff --git a/unittests/dispatch_functions.chai b/unittests/dispatch_functions.chai index 1887844e..67805164 100644 --- a/unittests/dispatch_functions.chai +++ b/unittests/dispatch_functions.chai @@ -1,7 +1,6 @@ assert_equal(`==`, `==`); assert_not_equal(`==`, `<`); assert_equal(`<`.get_arity(), 2); -assert_equal(`+`.get_annotation(), "Multiple method dispatch function wrapper."); assert_equal(get_arity.get_contained_functions().size(), 0); assert_equal(get_arity.get_arity(), 1); assert_equal(get_arity.get_param_types().size(), 2);