From d080ce5f52421e4a756d2bebb4ac614f3ab3592c Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Mon, 10 Feb 2020 18:41:25 +0100 Subject: [PATCH] Fix initialization checker for subscript expressions and add tests The subscript initialization checker is definitely not satisfactory, but it is an on going fact: many treatment (none trivial ones should be performed). By now it is just a simple helper, and should require much improvements. Not sure that it is the right strategy. One should maybe force initialization... However, this is a second-order question that should be addressed in a far(?) future. --- src/language/ASTBuilder.cpp | 2 + .../ASTSymbolInitializationChecker.cpp | 6 ++ tests/test_ASTSymbolInitializationChecker.cpp | 87 +++++++++++++++++++ 3 files changed, 95 insertions(+) diff --git a/src/language/ASTBuilder.cpp b/src/language/ASTBuilder.cpp index 11ad02381..6a90a29c5 100644 --- a/src/language/ASTBuilder.cpp +++ b/src/language/ASTBuilder.cpp @@ -122,6 +122,8 @@ struct ASTBuilder::simplify_unary : parse_tree::apply<ASTBuilder::simplify_unary std::swap(array_subscript_expression->children[0], array_subscript_expression->children[1]); + array_subscript_expression->m_begin = array_subscript_expression->children[0]->m_begin; + transform(n, st...); } } diff --git a/src/language/ASTSymbolInitializationChecker.cpp b/src/language/ASTSymbolInitializationChecker.cpp index e8c75adb3..c5cad3347 100644 --- a/src/language/ASTSymbolInitializationChecker.cpp +++ b/src/language/ASTSymbolInitializationChecker.cpp @@ -54,6 +54,12 @@ ASTSymbolInitializationChecker::_checkSymbolInitialization(ASTNode& node) if (node.children[0]->is_type<language::name>()) { set_is_initialized(*node.children[0]); + } else if (node.children[0]->is_type<language::subscript_expression>()) { + ASTNode& subscript_node = *node.children[0]; + ASTNode& name_node = *subscript_node.children[0]; + + Assert(name_node.is_type<language::name>()); + set_is_initialized(name_node); } else if (node.children[0]->is_type<language::name_list>() or node.children[0]->is_type<language::lvalue_list>()) { ASTNode& list_node = *node.children[0]; for (auto& child_node : list_node.children) { diff --git a/tests/test_ASTSymbolInitializationChecker.cpp b/tests/test_ASTSymbolInitializationChecker.cpp index 46c9add1f..a9faafc59 100644 --- a/tests/test_ASTSymbolInitializationChecker.cpp +++ b/tests/test_ASTSymbolInitializationChecker.cpp @@ -37,6 +37,27 @@ N p; REQUIRE(not symbol_p->attributes().isInitialized()); } + SECTION("Array subscript initialization") + { + std::string_view data = R"( +R^3 x; +x[0] = 1; +)"; + + string_input input{data, "test.pgs"}; + auto ast = ASTBuilder::build(input); + + ASTSymbolTableBuilder{*ast}; + ASTSymbolInitializationChecker{*ast}; + + position position{internal::iterator{"fixture"}, "fixture"}; + position.byte = data.size(); // ensure that variables are declared at this point + + auto [symbol_m, found_m] = ast->m_symbol_table->find("x", position); + REQUIRE(found_m); + REQUIRE(symbol_m->attributes().isInitialized()); + } + SECTION("Declaration plus affectation") { std::string_view data = R"( @@ -115,6 +136,26 @@ R*R (x,y) = (2.3, 4.1); REQUIRE(symbol_y->attributes().isInitialized()); } + SECTION("Declarative initialization") + { + std::string_view data = R"( +R^2 x = (2.3, 4.1); +)"; + + string_input input{data, "test.pgs"}; + auto ast = ASTBuilder::build(input); + + ASTSymbolTableBuilder{*ast}; + ASTSymbolInitializationChecker{*ast}; + + position position{internal::iterator{"fixture"}, "fixture"}; + position.byte = data.size(); // ensure that variables are declared at this point + + auto [symbol_x, found_x] = ast->m_symbol_table->find("x", position); + REQUIRE(found_x); + REQUIRE(symbol_x->attributes().isInitialized()); + } + SECTION("Not initialized") { std::string_view data = R"( @@ -164,6 +205,52 @@ R*R (x,y); REQUIRE(found_y); REQUIRE(symbol_y->attributes().isInitialized()); } + + SECTION("Affectation") + { + std::string_view data = R"( +R^3*R (x,y); +(x,y) = ((2.3, 2, 5), 4.1); +)"; + + string_input input{data, "test.pgs"}; + auto ast = ASTBuilder::build(input); + + ASTSymbolTableBuilder{*ast}; + ASTSymbolInitializationChecker{*ast}; + + position position{internal::iterator{"fixture"}, "fixture"}; + position.byte = data.size(); // ensure that variables are declared at this point + + auto [symbol_x, found_x] = ast->m_symbol_table->find("x", position); + REQUIRE(found_x); + REQUIRE(symbol_x->attributes().isInitialized()); + + auto [symbol_y, found_y] = ast->m_symbol_table->find("y", position); + REQUIRE(found_y); + REQUIRE(symbol_y->attributes().isInitialized()); + } + } + + SECTION("Affectation") + { + std::string_view data = R"( +R^3 x; +(x[2], x[1], x[0]) = (1, 2, 3); +)"; + + string_input input{data, "test.pgs"}; + auto ast = ASTBuilder::build(input); + + ASTSymbolTableBuilder{*ast}; + ASTSymbolInitializationChecker{*ast}; + + position position{internal::iterator{"fixture"}, "fixture"}; + position.byte = data.size(); // ensure that variables are declared at this point + + auto [symbol_x, found_x] = ast->m_symbol_table->find("x", position); + REQUIRE(found_x); + REQUIRE(symbol_x->attributes().isInitialized()); } SECTION("errors") -- GitLab