diff --git a/src/language/ASTBuilder.cpp b/src/language/ASTBuilder.cpp index 11ad02381774e462befe6e8ed486ac57cfdfc2bb..6a90a29c532775494090846c4e362e37af52ae47 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 e8c75adb3c79e7030e2543043dd7cbe0e61a0153..c5cad33472a1629a9cfbb770555200bb0ae215bc 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 46c9add1f68ea285dd48fd11dace87fb955e5777..a9faafc595b48bba234e0a621804a109855e2092 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")