From 30c256fc1848e5c7045a5a6c0af29a4ebd518020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Del=20Pino?= <stephane.delpino44@gmail.com> Date: Mon, 30 May 2022 16:44:35 +0200 Subject: [PATCH] Fix symbol table management for do...while and while loops In case of empty blocks or single instruction statement, the symbol table could be cleared unexpectedly. --- src/language/ast/ASTSymbolTableBuilder.cpp | 3 +- tests/test_DoWhileProcessor.cpp | 35 ++++++++++++++++++++++ tests/test_WhileProcessor.cpp | 34 +++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/src/language/ast/ASTSymbolTableBuilder.cpp b/src/language/ast/ASTSymbolTableBuilder.cpp index d2eb7d77c..ac7d03155 100644 --- a/src/language/ast/ASTSymbolTableBuilder.cpp +++ b/src/language/ast/ASTSymbolTableBuilder.cpp @@ -8,7 +8,8 @@ void ASTSymbolTableBuilder::buildSymbolTable(ASTNode& n, std::shared_ptr<SymbolTable>& symbol_table) { - if (n.is_type<language::block>() or (n.is_type<language::for_statement>())) { + if (n.is_type<language::block>() or (n.is_type<language::for_statement>()) or + (n.is_type<language::while_statement>()) or (n.is_type<language::do_while_statement>())) { if (!n.children.empty()) { std::shared_ptr block_symbol_table = std::make_shared<SymbolTable>(symbol_table); n.m_symbol_table = block_symbol_table; diff --git a/tests/test_DoWhileProcessor.cpp b/tests/test_DoWhileProcessor.cpp index 8e4f7a2c9..9ef421988 100644 --- a/tests/test_DoWhileProcessor.cpp +++ b/tests/test_DoWhileProcessor.cpp @@ -105,6 +105,41 @@ do { CHECK_WHILE_PROCESSOR_RESULT(data, "i", 12ul); } + SECTION("do-while lifetime variable") + { + std::string_view data = R"( +let i:N, i = 3; +let j:N, j = 0; +do { + j = 5; + let j:N, j = 2; + i = j; +} while(false); +)"; + CHECK_WHILE_PROCESSOR_RESULT(data, "i", 2ul); + CHECK_WHILE_PROCESSOR_RESULT(data, "j", 5ul); + } + + SECTION("empty do-while symbol table untouched") + { + std::string_view data = R"( +let i:N, i = 3; +do {} while(false); +)"; + CHECK_WHILE_PROCESSOR_RESULT(data, "i", 3ul); + } + + SECTION("single instruction do-while symbol table untouched") + { + std::string_view data = R"( +let i:N, i = 3; +do + i = 2; +while(false); +)"; + CHECK_WHILE_PROCESSOR_RESULT(data, "i", 2ul); + } + SECTION("errors") { SECTION("bad test type") diff --git a/tests/test_WhileProcessor.cpp b/tests/test_WhileProcessor.cpp index e886b6213..028d8eae0 100644 --- a/tests/test_WhileProcessor.cpp +++ b/tests/test_WhileProcessor.cpp @@ -101,6 +101,40 @@ while(i<10) { CHECK_WHILE_PROCESSOR_RESULT(data, "i", 12ul); } + SECTION("while lifetime variable") + { + std::string_view data = R"( +let i:N, i = 3; +let j:N, j = 0; +while(i != 2) { + j = 5; + let j:N, j = 2; + i = j; +} +)"; + CHECK_WHILE_PROCESSOR_RESULT(data, "i", 2ul); + CHECK_WHILE_PROCESSOR_RESULT(data, "j", 5ul); + } + + SECTION("while symbol table untouched") + { + std::string_view data = R"( +let i:N, i = 3; +while(i != 3); +)"; + CHECK_WHILE_PROCESSOR_RESULT(data, "i", 3ul); + } + + SECTION("single instruction while symbol table untouched") + { + std::string_view data = R"( +let i:N, i = 3; +while (i == 3) + i = 2; +)"; + CHECK_WHILE_PROCESSOR_RESULT(data, "i", 2ul); + } + SECTION("errors") { SECTION("bad test type") -- GitLab