diff --git a/src/language/PEGGrammar.hpp b/src/language/PEGGrammar.hpp index d173f50745e781d2be5cade0372a0b15524f4850..82bd0969e9e0ca6933267474bd4da2bbe1db044c 100644 --- a/src/language/PEGGrammar.hpp +++ b/src/language/PEGGrammar.hpp @@ -179,10 +179,11 @@ struct close_bracket : seq< one< ']' >, ignored > {}; struct subscript_expression : if_must< open_bracket, list_must<expression, COMMA>, close_bracket >{}; -struct postfix_expression : seq< primary_expression, star< sor< subscript_expression , postfix_operator> > >{}; +struct postfix_expression : seq< primary_expression, star< sor< subscript_expression, postfix_operator > > >{}; -struct unary_expression : sor< seq< unary_operator, unary_expression >, - postfix_expression > {}; +struct prefix_expression : sor< postfix_expression, seq< unary_operator, prefix_expression > >{}; + +struct unary_expression : seq< prefix_expression, ignored >{}; struct and_op : seq< and_kw, ignored > {}; struct or_op : seq< or_kw, ignored > {}; diff --git a/src/language/ast/ASTBuilder.cpp b/src/language/ast/ASTBuilder.cpp index db7f77b29695bf82fc650ade4176592eefe5b651..42350ad359cd312f744367221f6875cc0f59b601 100644 --- a/src/language/ast/ASTBuilder.cpp +++ b/src/language/ast/ASTBuilder.cpp @@ -7,7 +7,7 @@ #include <pegtl/contrib/parse_tree.hpp> -struct ASTBuilder::rearrange : TAO_PEGTL_NAMESPACE::parse_tree::apply<ASTBuilder::rearrange> +struct ASTBuilder::rearrange_binary_op : TAO_PEGTL_NAMESPACE::parse_tree::apply<ASTBuilder::rearrange_binary_op> { template <typename... States> static void @@ -50,82 +50,80 @@ struct ASTBuilder::rearrange : TAO_PEGTL_NAMESPACE::parse_tree::apply<ASTBuilder } }; -struct ASTBuilder::simplify_unary : TAO_PEGTL_NAMESPACE::parse_tree::apply<ASTBuilder::simplify_unary> +struct ASTBuilder::rearrange_pre_unary_op : TAO_PEGTL_NAMESPACE::parse_tree::apply<ASTBuilder::rearrange_pre_unary_op> { template <typename... States> static void transform(std::unique_ptr<ASTNode>& n, States&&... st) { if (n->children.size() == 1) { - if (n->is_type<language::unary_expression>() or n->is_type<language::type_expression>()) { - n = std::move(n->children.back()); - transform(n, st...); - } else if (n->is_type<language::unary_minus>()) { - auto& child = n->children[0]; - if (child->is_type<language::unary_minus>()) { - n = std::move(child->children[0]); - transform(n, st...); - } - } else if (n->is_type<language::unary_not>()) { - auto& child = n->children[0]; - if (child->is_type<language::unary_not>()) { - n = std::move(child->children[0]); - transform(n, st...); - } - } - } else if ((n->children.size() == 2) and (n->is_type<language::unary_expression>())) { - if (n->children[0]->is_type<language::unary_plus>()) { - n = std::move(n->children[1]); - transform(n, st...); - } else if (n->children[0]->is_type<language::unary_minus>() or n->children[0]->is_type<language::unary_not>() or - n->children[0]->is_type<language::unary_minusminus>() or - n->children[0]->is_type<language::unary_plusplus>()) { - auto expression = std::move(n->children[1]); - auto unary_operator = std::move(n->children[0]); - unary_operator->children.emplace_back(std::move(expression)); - n = std::move(unary_operator); - transform(n, st...); - } + n = std::move(n->children.back()); + } else { + Assert(n->children.size() == 2); + auto op = std::move(n->children[0]); + auto expression = std::move(n->children[1]); + op->children.emplace_back(std::move(expression)); + n = std::move(op); } - if (n->is_type<language::unary_expression>()) { - const size_t child_nb = n->children.size(); - if (child_nb > 1) { - if (n->children[child_nb - 1]->is_type<language::post_minusminus>() or - n->children[child_nb - 1]->is_type<language::post_plusplus>()) { - auto unary_operator = std::move(n->children[child_nb - 1]); - n->children.pop_back(); - - unary_operator->children.emplace_back(std::move(n)); - - n = std::move(unary_operator); - transform(n->children[0], st...); - } + // Eventually simplify expressions + if (n->is_type<language::unary_minus>() or n->is_type<language::unary_not>()) { + if ((n->children[0]->children.size() == 1) and (n->children[0]->type == n->type)) { + n = std::move(n->children[0]->children[0]); } } + } +}; + +struct ASTBuilder::rearrange_post_unary_op : TAO_PEGTL_NAMESPACE::parse_tree::apply<ASTBuilder::rearrange_post_unary_op> +{ + template <typename... States> + static void + transform(std::unique_ptr<ASTNode>& n, States&&... st) + { + if (n->children.size() == 1) { + n = std::move(n->children.back()); + } else { + if (n->children.back()->is_type<language::subscript_expression>()) { + auto op = std::move(n->children.back()); + n->children.pop_back(); + op->children.emplace_back(std::move(n)); - if (n->is_type<language::unary_expression>()) { - if (n->children.size() > 1) { - if (n->children[1]->is_type<language::subscript_expression>()) { - std::swap(n->children[0], n->children[1]); + const size_t child_nb = op->children.size(); + for (size_t i = 1; i < op->children.size(); ++i) { + std::swap(op->children[child_nb - i], op->children[child_nb - i - 1]); + } - n->children[0]->emplace_back(std::move(n->children[1])); - n->children.pop_back(); + n = std::move(op); - auto& array_subscript_expression = n->children[0]; - const size_t child_nb = array_subscript_expression->children.size(); - for (size_t i = 1; i < array_subscript_expression->children.size(); ++i) { - std::swap(array_subscript_expression->children[child_nb - i], - array_subscript_expression->children[child_nb - i - 1]); - } + transform(n->children[0], st...); + } else { + auto op = std::move(n->children.back()); + n->children.pop_back(); - transform(n, st...); - } + auto expression = std::move(n); + op->children.emplace_back(std::move(expression)); + n = std::move(op); + transform(n->children[0], st...); } } } }; +struct ASTBuilder::simplify_type_expression + : TAO_PEGTL_NAMESPACE::parse_tree::apply<ASTBuilder::simplify_type_expression> +{ + template <typename... States> + static void + transform(std::unique_ptr<ASTNode>& n, States&&... st) + { + if ((n->children.size() == 1) and (n->is_type<language::type_expression>())) { + n = std::move(n->children.back()); + transform(n, st...); + } + } +}; + struct ASTBuilder::simplify_node_list : TAO_PEGTL_NAMESPACE::parse_tree::apply<ASTBuilder::simplify_node_list> { template <typename... States> @@ -230,6 +228,7 @@ using selector = TAO_PEGTL_NAMESPACE::parse_tree::selector< language::R_set, language::type_name_id, language::tuple_expression, + language::tuple_type_specifier, language::vector_type, language::matrix_type, language::string_type, @@ -244,24 +243,27 @@ using selector = TAO_PEGTL_NAMESPACE::parse_tree::selector< language::for_statement, language::function_evaluation, language::break_kw, - language::continue_kw>, - ASTBuilder::rearrange::on<language::logical_or, - language::logical_and, - language::bitwise_xor, - language::equality, - language::compare, - language::sum, - language::shift, - language::product, - language::affectation, - language::expression>, - ASTBuilder::simplify_unary::on<language::unary_minus, - language::unary_plus, - language::unary_not, - language::subscript_expression, - language::tuple_type_specifier, - language::type_expression, - language::unary_expression>, + language::continue_kw, + language::unary_minus, + language::unary_not, + language::unary_plusplus, + language::unary_minusminus, + language::post_minusminus, + language::post_plusplus, + language::subscript_expression>, + ASTBuilder::rearrange_binary_op::on<language::logical_or, + language::logical_and, + language::bitwise_xor, + language::equality, + language::compare, + language::sum, + language::shift, + language::product, + language::affectation, + language::expression>, + ASTBuilder::simplify_type_expression::on<language::type_expression>, + ASTBuilder::rearrange_pre_unary_op::on<language::prefix_expression>, + ASTBuilder::rearrange_post_unary_op::on<language::postfix_expression>, TAO_PEGTL_NAMESPACE::parse_tree::remove_content::on<language::plus_op, language::minus_op, language::shift_left_op, @@ -281,11 +283,7 @@ using selector = TAO_PEGTL_NAMESPACE::parse_tree::selector< language::multiplyeq_op, language::divideeq_op, language::pluseq_op, - language::minuseq_op, - language::unary_plusplus, - language::unary_minusminus, - language::post_minusminus, - language::post_plusplus>, + language::minuseq_op>, ASTBuilder::simplify_for_statement_block::on<language::for_statement_block>, TAO_PEGTL_NAMESPACE::parse_tree::discard_empty::on<language::ignored, language::semicol, language::block>, ASTBuilder::simplify_node_list::on<language::name_list, language::lvalue_list, language::function_argument_list>, diff --git a/src/language/ast/ASTBuilder.hpp b/src/language/ast/ASTBuilder.hpp index 8939a09385277dc05255a643bfb46c877a7901bb..2ae20ff77e2320ef1ec136f2e05dde0cc30bcd38 100644 --- a/src/language/ast/ASTBuilder.hpp +++ b/src/language/ast/ASTBuilder.hpp @@ -8,15 +8,17 @@ struct ASTBuilder { private: - struct rearrange; - struct simplify_unary; + struct rearrange_binary_op; + struct rearrange_post_unary_op; + struct rearrange_pre_unary_op; struct simplify_node_list; - struct simplify_statement_block; struct simplify_for_statement_block; struct simplify_for_init; struct simplify_for_test; struct simplify_for_post; + struct simplify_statement_block; struct simplify_stream_statement; + struct simplify_type_expression; public: template <typename InputT> diff --git a/src/language/node_processor/AffectationProcessor.hpp b/src/language/node_processor/AffectationProcessor.hpp index 0d6663e38112897ee3e05b945a298d820b65f608..c172874b8af2bbd5408832e090ecd14492be7745 100644 --- a/src/language/node_processor/AffectationProcessor.hpp +++ b/src/language/node_processor/AffectationProcessor.hpp @@ -236,12 +236,7 @@ class AffectationProcessor final : public INodeProcessor DataVariant execute(ExecutionPolicy& exec_policy) { - // try { m_affectation_executor->affect(exec_policy, m_rhs_node.execute(exec_policy)); - // } - // catch (std::bad_variant_access& e) { - // throw ParseError("trying to uninitialized value", std::vector{m_rhs_node.begin()}); - // } return {}; } diff --git a/tests/test_ASTBuilder.cpp b/tests/test_ASTBuilder.cpp index 262a0cd30b60cee5da070fe6fa8d62d8981e7b1d..bba1d53309d942754e4729d48c0341d0f313ac35 100644 --- a/tests/test_ASTBuilder.cpp +++ b/tests/test_ASTBuilder.cpp @@ -326,6 +326,25 @@ not not not false; CHECK_AST(data, result); } + SECTION("post incr decr parsing") + { + std::string_view data = R"( +(++1)++; +--(2--); +)"; + + std::string_view result = R"( +(root) + +-(language::post_plusplus) + | `-(language::unary_plusplus) + | `-(language::integer:1) + `-(language::unary_minusminus) + `-(language::post_minusminus) + `-(language::integer:2) +)"; + CHECK_AST(data, result); + } + SECTION("statement block simplification (one instruction per block)") { std::string_view data = R"( diff --git a/tests/test_ASTNodeDataTypeBuilder.cpp b/tests/test_ASTNodeDataTypeBuilder.cpp index 5dcd6f57cb77dc3e91b8e2e084f98b9143a75f1c..1adbb89a18c92af774421a54065a8b8d1b3ba734 100644 --- a/tests/test_ASTNodeDataTypeBuilder.cpp +++ b/tests/test_ASTNodeDataTypeBuilder.cpp @@ -339,7 +339,7 @@ let x:R^2, x = 0; let y:R, y = x[2,2]; SECTION("invalid R^dxd subscript index list 1") { std::string_view data = R"( -let x:R^2x2, x = 0; let y:R, y = x[2]; +let x:R^2x2, x = 0; let y:R, y = x[2][1]; )"; TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"}; diff --git a/tests/test_ASTNodeIncDecExpressionBuilder.cpp b/tests/test_ASTNodeIncDecExpressionBuilder.cpp index 78391f1ee8e41f9b0d53cbddc2cea7aefe5e54ec..bc28df8ca7ba0e0acec6841e72bcccfdcece2ae9 100644 --- a/tests/test_ASTNodeIncDecExpressionBuilder.cpp +++ b/tests/test_ASTNodeIncDecExpressionBuilder.cpp @@ -428,10 +428,10 @@ x--; DISALLOWED_CHAINED_AST(data, error_message) } - SECTION("++ a ++") + SECTION("++ (a ++)") { std::string_view data = R"( -++ 1 ++; +++ (1 ++); )"; std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)"; @@ -439,10 +439,10 @@ x--; DISALLOWED_CHAINED_AST(data, error_message) } - SECTION("++ a --") + SECTION("++ (a --)") { std::string_view data = R"( -++ 1 --; +++ (1 --); )"; std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)"; @@ -450,10 +450,10 @@ x--; DISALLOWED_CHAINED_AST(data, error_message) } - SECTION("-- a ++") + SECTION("-- (a ++)") { std::string_view data = R"( --- 1 ++; +-- (1 ++); )"; std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)"; @@ -461,10 +461,54 @@ x--; DISALLOWED_CHAINED_AST(data, error_message) } - SECTION("-- --") + SECTION("-- (a --)") { std::string_view data = R"( --- 1 --; +-- (1 --); +)"; + + std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)"; + + DISALLOWED_CHAINED_AST(data, error_message) + } + + SECTION("(++ a) ++") + { + std::string_view data = R"( +(++ 1) ++; +)"; + + std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)"; + + DISALLOWED_CHAINED_AST(data, error_message) + } + + SECTION("(++ a) --") + { + std::string_view data = R"( +(++ 1) --; +)"; + + std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)"; + + DISALLOWED_CHAINED_AST(data, error_message) + } + + SECTION("(-- a) ++") + { + std::string_view data = R"( +(-- 1) ++; +)"; + + std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)"; + + DISALLOWED_CHAINED_AST(data, error_message) + } + + SECTION("(-- a) --") + { + std::string_view data = R"( +(-- 1) --; )"; std::string error_message = R"(invalid operand type. ++/-- operators only apply to variables)";