diff --git a/src/language/SymbolTable.hpp b/src/language/SymbolTable.hpp index e86bd1e45c5eaedce0cba80a6581bd4f25688b0a..420a8fd8cf3ad987ebe308b4a114390f7d83ee8c 100644 --- a/src/language/SymbolTable.hpp +++ b/src/language/SymbolTable.hpp @@ -2,6 +2,7 @@ #define SYMBOL_TABLE_HPP #include <ASTNodeDataType.hpp> +#include <ASTNodeDataVariant.hpp> class SymbolTable { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 71d2efbfb1351ea7f966c9853e28ac9281a70b20..bd30945f2fab3f09362b27e25f74cc830496b9a9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -9,6 +9,7 @@ add_executable (unit_tests test_ItemType.cpp test_PugsAssert.cpp test_RevisionInfo.cpp + test_SymbolTable.cpp test_TinyMatrix.cpp test_TinyVector.cpp ) diff --git a/tests/test_SymbolTable.cpp b/tests/test_SymbolTable.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9d7d02bde1e9f2b3c29ce479694acaa82c8a3489 --- /dev/null +++ b/tests/test_SymbolTable.cpp @@ -0,0 +1,106 @@ +#include <catch2/catch.hpp> + +#include <SymbolTable.hpp> +#include <sstream> + +TEST_CASE("SymbolTable", "[language]") +{ + SECTION("Simple Symbol Table") + { + std::shared_ptr root_st = std::make_shared<SymbolTable>(); + + auto [i_symbol_a, created_a] = root_st->add("a"); + REQUIRE(created_a); + + // Check that one cannot build another "a" in this table + REQUIRE(not root_st->add("a").second); + + auto [i_search_a, found_a] = root_st->find("a"); + REQUIRE(found_a); + REQUIRE(i_search_a == i_symbol_a); + + SECTION("Output uninitialized") + { + std::stringstream st_output; + st_output << '\n' << *root_st; + + REQUIRE(st_output.str() == R"( +-- Symbol table state -- parent : 0 + a: -- +------------------------ +)"); + } + + SECTION("Attributes") + { + // undefined data + auto& attributes_a = i_search_a->second; + REQUIRE(attributes_a.dataType() == ASTNodeDataType::undefined_t); + REQUIRE(not attributes_a.isInitialized()); + + REQUIRE(std::holds_alternative<std::monostate>(attributes_a.value())); + + { + std::stringstream value_output; + value_output << attributes_a; + REQUIRE(value_output.str() == "--"); + } + + // defining data + attributes_a.setIsInitialized(); + REQUIRE(attributes_a.isInitialized()); + + attributes_a.setDataType(ASTNodeDataType::double_t); + REQUIRE(attributes_a.dataType() == ASTNodeDataType::double_t); + + attributes_a.value() = 2.3; + + REQUIRE(std::holds_alternative<double>(attributes_a.value())); + + { + std::stringstream value_output; + value_output << attributes_a; + REQUIRE(value_output.str() == "2.3"); + } + + SECTION("Output initialized") + { + std::stringstream st_output; + st_output << '\n' << *root_st; + + REQUIRE(st_output.str() == R"( +-- Symbol table state -- parent : 0 + a: 2.3 +------------------------ +)"); + } + } + } + + SECTION("Hierarchy Symbol Table") + { + std::shared_ptr root_st = std::make_shared<SymbolTable>(); + auto [i_root_symbol_a, created_root_a] = root_st->add("a"); + REQUIRE(created_root_a); + + std::shared_ptr nested_st = std::make_shared<SymbolTable>(root_st); + + auto [i_search_a, found_a] = nested_st->find("a"); + REQUIRE(found_a); + // symbol "a" is the one defined in root_st + REQUIRE(i_root_symbol_a == i_search_a); + + auto [i_nested_symbol_a, created_nested_a] = nested_st->add("a"); + REQUIRE(created_nested_a); + + auto [i_search_nested_a, found_nested_a] = nested_st->find("a"); + + REQUIRE(found_nested_a); + // found the symbol created in nested symbol table + REQUIRE(&(i_search_nested_a->second) != &(i_root_symbol_a->second)); + REQUIRE(&(i_search_nested_a->second) == &(i_nested_symbol_a->second)); + + auto [i_search_b, found_b] = nested_st->find("b"); + REQUIRE(not found_b); // "b" is not defined in any symbol table + } +}