diff --git a/tests/test_ASTNodeBuiltinFunctionExpressionBuilder.cpp b/tests/test_ASTNodeBuiltinFunctionExpressionBuilder.cpp index 9795ded186f5f7fee9236ec7473bd7c5f32d528b..2954cd8db2e691ea2206b30b158f9596a8290081 100644 --- a/tests/test_ASTNodeBuiltinFunctionExpressionBuilder.cpp +++ b/tests/test_ASTNodeBuiltinFunctionExpressionBuilder.cpp @@ -8,182 +8,16 @@ #include <language/ast/ASTNodeFunctionExpressionBuilder.hpp> #include <language/ast/ASTNodeTypeCleaner.hpp> #include <language/ast/ASTSymbolTableBuilder.hpp> -#include <language/utils/ASTNodeDataTypeTraits.hpp> #include <language/utils/ASTPrinter.hpp> -#include <language/utils/BuiltinFunctionEmbedder.hpp> -#include <language/utils/TypeDescriptor.hpp> #include <utils/Demangle.hpp> +#include <test_BuiltinFunctionRegister.hpp> + #include <pegtl/string_input.hpp> #include <memory> #include <unordered_map> -template <> -inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const double>> = {ASTNodeDataType::type_id_t, - "builtin_t"}; -const auto builtin_data_type = ast_node_data_type_from<std::shared_ptr<const double>>; - -namespace test_only -{ -class BuiltinFunctionRegister -{ - private: - std::unordered_map<std::string, std::shared_ptr<IBuiltinFunctionEmbedder>> m_name_builtin_function_map; - - void - _populateNameBuiltinFunctionMap() - { - m_name_builtin_function_map.insert(std::make_pair("RtoR", std::make_shared<BuiltinFunctionEmbedder<double(double)>>( - [](double x) -> double { return x + 1; }))); - - m_name_builtin_function_map.insert( - std::make_pair("ZtoR", std::make_shared<BuiltinFunctionEmbedder<double(int64_t)>>( - [](int64_t z) -> double { return 0.5 * z; }))); - - m_name_builtin_function_map.insert( - std::make_pair("NtoR", std::make_shared<BuiltinFunctionEmbedder<double(uint64_t)>>( - [](uint64_t n) -> double { return 0.5 * n; }))); - - m_name_builtin_function_map.insert(std::make_pair("BtoR", std::make_shared<BuiltinFunctionEmbedder<double(bool)>>( - [](bool b) -> double { return b; }))); - - m_name_builtin_function_map.insert( - std::make_pair("RRtoB", std::make_shared<BuiltinFunctionEmbedder<bool(double, double)>>( - [](double x, double y) -> bool { return x > y; }))); - - m_name_builtin_function_map.insert( - std::make_pair("StoB", std::make_shared<BuiltinFunctionEmbedder<bool(std::string)>>( - [](const std::string& s) -> bool { return s.size() > 0; }))); - - m_name_builtin_function_map.insert( - std::make_pair("RtoR1", std::make_shared<BuiltinFunctionEmbedder<TinyVector<1>(double)>>( - [](double r) -> TinyVector<1> { return {r}; }))); - - m_name_builtin_function_map.insert( - std::make_pair("R1toR", std::make_shared<BuiltinFunctionEmbedder<double(TinyVector<1>)>>( - [](TinyVector<1> x) -> double { return x[0]; }))); - - m_name_builtin_function_map.insert( - std::make_pair("R2toR", std::make_shared<BuiltinFunctionEmbedder<double(TinyVector<2>)>>( - [](TinyVector<2> x) -> double { return x[0] + x[1]; }))); - - m_name_builtin_function_map.insert( - std::make_pair("R3toR", std::make_shared<BuiltinFunctionEmbedder<double(const TinyVector<3>&)>>( - [](const TinyVector<3>& x) -> double { return x[0] + x[1] + x[2]; }))); - - m_name_builtin_function_map.insert( - std::make_pair("R3R2toR", - std::make_shared<BuiltinFunctionEmbedder<double(TinyVector<3>, TinyVector<2>)>>( - [](TinyVector<3> x, TinyVector<2> y) -> double { return x[0] * y[1] + (y[0] - x[2]) * x[1]; }))); - - m_name_builtin_function_map.insert( - std::make_pair("fidToR", std::make_shared<BuiltinFunctionEmbedder<double(const FunctionSymbolId&)>>( - [](const FunctionSymbolId&) -> double { return 0; }))); - - m_name_builtin_function_map.insert( - std::make_pair("builtinToBuiltin", - std::make_shared< - BuiltinFunctionEmbedder<std::shared_ptr<const double>(std::shared_ptr<const double>)>>( - [](std::shared_ptr<const double> x) -> std::shared_ptr<const double> { return x; }))); - - m_name_builtin_function_map.insert( - std::make_pair("tuple_BtoR", std::make_shared<BuiltinFunctionEmbedder<double(std::vector<bool>)>>( - [](const std::vector<bool>&) -> double { return 0.5; }))); - - m_name_builtin_function_map.insert( - std::make_pair("tuple_NtoR", std::make_shared<BuiltinFunctionEmbedder<double(std::vector<uint64_t>)>>( - [](const std::vector<uint64_t>&) -> double { return 0.5; }))); - - m_name_builtin_function_map.insert( - std::make_pair("tuple_ZtoR", std::make_shared<BuiltinFunctionEmbedder<double(std::vector<int64_t>)>>( - [](const std::vector<int64_t>&) -> double { return 0.5; }))); - - m_name_builtin_function_map.insert( - std::make_pair("tuple_RtoB", std::make_shared<BuiltinFunctionEmbedder<bool(std::vector<double>)>>( - [](const std::vector<double>&) -> bool { return false; }))); - - m_name_builtin_function_map.insert( - std::make_pair("tuple_stringtoB", std::make_shared<BuiltinFunctionEmbedder<bool(std::vector<std::string>)>>( - [](const std::vector<std::string>&) -> bool { return true; }))); - - m_name_builtin_function_map.insert( - std::make_pair("tuple_builtinToB", - std::make_shared<BuiltinFunctionEmbedder<bool(std::vector<std::shared_ptr<const double>>)>>( - [](const std::vector<std::shared_ptr<const double>>&) -> bool { return true; }))); - - m_name_builtin_function_map.insert( - std::make_pair("tuple_R1ToR", - std::make_shared<BuiltinFunctionEmbedder<double(const std::vector<TinyVector<1>>&)>>( - [](const std::vector<TinyVector<1>>&) -> double { return 1; }))); - - m_name_builtin_function_map.insert( - std::make_pair("tuple_R2ToR", - std::make_shared<BuiltinFunctionEmbedder<double(const std::vector<TinyVector<2>>&)>>( - [](const std::vector<TinyVector<2>>&) -> double { return 1; }))); - - m_name_builtin_function_map.insert( - std::make_pair("tuple_R3ToR", std::make_shared<BuiltinFunctionEmbedder<double(const std::vector<TinyVector<3>>)>>( - [](const std::vector<TinyVector<3>>&) -> double { return 0; }))); - } - - void - _addBuiltinTypeAndVariables(ASTNode& ast) - { - SymbolTable& symbol_table = *ast.m_symbol_table; - auto [i_symbol, success] = symbol_table.add(builtin_data_type.nameOfTypeId(), ast.begin()); - if (not success) { - throw UnexpectedError("cannot add '" + builtin_data_type.nameOfTypeId() + "' type for testing"); - } - - i_symbol->attributes().setDataType(ASTNodeDataType::type_name_id_t); - i_symbol->attributes().setIsInitialized(); - i_symbol->attributes().value() = symbol_table.typeEmbedderTable().size(); - symbol_table.typeEmbedderTable().add(std::make_shared<TypeDescriptor>(builtin_data_type.nameOfTypeId())); - - auto [i_symbol_a, success_a] = symbol_table.add("a", ast.begin()); - if (not success_a) { - throw UnexpectedError("cannot add 'a' of type builtin_t for testing"); - } - i_symbol_a->attributes().setDataType(ast_node_data_type_from<std::shared_ptr<const double>>); - i_symbol_a->attributes().setIsInitialized(); - auto [i_symbol_b, success_b] = symbol_table.add("b", ast.begin()); - if (not success_b) { - throw UnexpectedError("cannot add 'b' of type builtin_t for testing"); - } - i_symbol_b->attributes().setDataType(ast_node_data_type_from<std::shared_ptr<const double>>); - i_symbol_b->attributes().setIsInitialized(); - } - - public: - BuiltinFunctionRegister(ASTNode& root_node) - { - SymbolTable& symbol_table = *root_node.m_symbol_table; - - auto& builtin_function_embedder_table = symbol_table.builtinFunctionEmbedderTable(); - - this->_populateNameBuiltinFunctionMap(); - this->_addBuiltinTypeAndVariables(root_node); - - for (const auto& [symbol_name, builtin_function] : m_name_builtin_function_map) { - auto [i_symbol, success] = symbol_table.add(symbol_name, root_node.begin()); - - if (not success) { - std::ostringstream error_message; - error_message << "cannot add symbol '" << symbol_name << "' it is already defined"; - throw parse_error(error_message.str(), root_node.begin()); - } - - i_symbol->attributes().setDataType(ASTNodeDataType::builtin_function_t); - i_symbol->attributes().setIsInitialized(); - i_symbol->attributes().value() = builtin_function_embedder_table.size(); - - builtin_function_embedder_table.add(builtin_function); - } - } -}; -} // namespace test_only - #define CHECK_AST(data, expected_output) \ { \ static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>); \ @@ -193,7 +27,7 @@ class BuiltinFunctionRegister string_input input{data, "test.pgs"}; \ auto ast = ASTBuilder::build(input); \ \ - test_only::BuiltinFunctionRegister{*ast}; \ + test_only::test_BuiltinFunctionRegister{*ast}; \ \ ASTSymbolTableBuilder{*ast}; \ ASTNodeDataTypeBuilder{*ast}; \ @@ -217,12 +51,13 @@ class BuiltinFunctionRegister string_input input{data, "test.pgs"}; \ auto ast = ASTBuilder::build(input); \ \ - test_only::BuiltinFunctionRegister{*ast}; \ + test_only::test_BuiltinFunctionRegister{*ast}; \ \ ASTSymbolTableBuilder{*ast}; \ ASTNodeDataTypeBuilder{*ast}; \ \ ASTNodeTypeCleaner<language::var_declaration>{*ast}; \ + ASTNodeTypeCleaner<language::fct_declaration>{*ast}; \ REQUIRE_THROWS_WITH(ASTNodeExpressionBuilder{*ast}, Catch::Matchers::Contains(expected_error)); \ } diff --git a/tests/test_BuiltinFunctionProcessor.cpp b/tests/test_BuiltinFunctionProcessor.cpp index 0fc0888920ba5ae969594c5ab5efdf24cca38986..a2a690a19fedb243b36fe23d88c0aa9b04079f5c 100644 --- a/tests/test_BuiltinFunctionProcessor.cpp +++ b/tests/test_BuiltinFunctionProcessor.cpp @@ -9,6 +9,8 @@ #include <language/ast/ASTSymbolTableBuilder.hpp> #include <language/modules/MathModule.hpp> +#include <test_BuiltinFunctionRegister.hpp> + #define CHECK_BUILTIN_FUNCTION_EVALUATION_RESULT(data, variable_name, expected_value) \ { \ string_input input{data, "test.pgs"}; \ @@ -46,6 +48,29 @@ REQUIRE(value == expected_value); \ } +#define CHECK_AST_THROWS_WITH(data, expected_error) \ + { \ + static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>); \ + static_assert((std::is_same_v<std::decay_t<decltype(expected_error)>, std::string_view>) or \ + (std::is_same_v<std::decay_t<decltype(expected_error)>, std::string>)); \ + \ + string_input input{data, "test.pgs"}; \ + auto ast = ASTBuilder::build(input); \ + \ + test_only::test_BuiltinFunctionRegister{*ast}; \ + \ + ASTSymbolTableBuilder{*ast}; \ + ASTNodeDataTypeBuilder{*ast}; \ + \ + ASTNodeTypeCleaner<language::var_declaration>{*ast}; \ + ASTNodeTypeCleaner<language::fct_declaration>{*ast}; \ + \ + ASTNodeExpressionBuilder{*ast}; \ + ExecutionPolicy exec_policy; \ + \ + REQUIRE_THROWS_WITH(ast->execute(exec_policy), Catch::Matchers::Contains(expected_error)); \ + } + // clazy:excludeall=non-pod-global-static TEST_CASE("BuiltinFunctionProcessor", "[language]") @@ -264,5 +289,16 @@ let z:Z, z = round(-1.2); } } REQUIRE_FALSE(missing_test); + + SECTION("catch runtime error") + { + std::string_view data = R"( +runtimeError(); +)"; + + std::string error = "runtime error"; + + CHECK_AST_THROWS_WITH(data, error); + } } } diff --git a/tests/test_BuiltinFunctionRegister.hpp b/tests/test_BuiltinFunctionRegister.hpp new file mode 100644 index 0000000000000000000000000000000000000000..fdf46213388b23e46c1457a56ea213cf17ac83f0 --- /dev/null +++ b/tests/test_BuiltinFunctionRegister.hpp @@ -0,0 +1,178 @@ +#ifndef TEST_BUILTIN_FUNCTION_REGISTER_H +#define TEST_BUILTIN_FUNCTION_REGISTER_H + +#include <language/utils/ASTNodeDataTypeTraits.hpp> +#include <language/utils/BuiltinFunctionEmbedder.hpp> +#include <language/utils/TypeDescriptor.hpp> +#include <utils/Exceptions.hpp> + +template <> +inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const double>> = {ASTNodeDataType::type_id_t, + "builtin_t"}; +const auto builtin_data_type = ast_node_data_type_from<std::shared_ptr<const double>>; + +namespace test_only +{ +class test_BuiltinFunctionRegister +{ + private: + std::unordered_map<std::string, std::shared_ptr<IBuiltinFunctionEmbedder>> m_name_builtin_function_map; + + void + _populateNameBuiltinFunctionMap() + { + m_name_builtin_function_map.insert( + std::make_pair("runtimeError", std::make_shared<BuiltinFunctionEmbedder<void(void)>>( + [](void) -> void { throw NormalError("runtime error"); }))); + + m_name_builtin_function_map.insert(std::make_pair("RtoR", std::make_shared<BuiltinFunctionEmbedder<double(double)>>( + [](double x) -> double { return x + 1; }))); + + m_name_builtin_function_map.insert( + std::make_pair("ZtoR", std::make_shared<BuiltinFunctionEmbedder<double(int64_t)>>( + [](int64_t z) -> double { return 0.5 * z; }))); + + m_name_builtin_function_map.insert( + std::make_pair("NtoR", std::make_shared<BuiltinFunctionEmbedder<double(uint64_t)>>( + [](uint64_t n) -> double { return 0.5 * n; }))); + + m_name_builtin_function_map.insert(std::make_pair("BtoR", std::make_shared<BuiltinFunctionEmbedder<double(bool)>>( + [](bool b) -> double { return b; }))); + + m_name_builtin_function_map.insert( + std::make_pair("RRtoB", std::make_shared<BuiltinFunctionEmbedder<bool(double, double)>>( + [](double x, double y) -> bool { return x > y; }))); + + m_name_builtin_function_map.insert( + std::make_pair("StoB", std::make_shared<BuiltinFunctionEmbedder<bool(std::string)>>( + [](const std::string& s) -> bool { return s.size() > 0; }))); + + m_name_builtin_function_map.insert( + std::make_pair("RtoR1", std::make_shared<BuiltinFunctionEmbedder<TinyVector<1>(double)>>( + [](double r) -> TinyVector<1> { return {r}; }))); + + m_name_builtin_function_map.insert( + std::make_pair("R1toR", std::make_shared<BuiltinFunctionEmbedder<double(TinyVector<1>)>>( + [](TinyVector<1> x) -> double { return x[0]; }))); + + m_name_builtin_function_map.insert( + std::make_pair("R2toR", std::make_shared<BuiltinFunctionEmbedder<double(TinyVector<2>)>>( + [](TinyVector<2> x) -> double { return x[0] + x[1]; }))); + + m_name_builtin_function_map.insert( + std::make_pair("R3toR", std::make_shared<BuiltinFunctionEmbedder<double(const TinyVector<3>&)>>( + [](const TinyVector<3>& x) -> double { return x[0] + x[1] + x[2]; }))); + + m_name_builtin_function_map.insert( + std::make_pair("R3R2toR", + std::make_shared<BuiltinFunctionEmbedder<double(TinyVector<3>, TinyVector<2>)>>( + [](TinyVector<3> x, TinyVector<2> y) -> double { return x[0] * y[1] + (y[0] - x[2]) * x[1]; }))); + + m_name_builtin_function_map.insert( + std::make_pair("fidToR", std::make_shared<BuiltinFunctionEmbedder<double(const FunctionSymbolId&)>>( + [](const FunctionSymbolId&) -> double { return 0; }))); + + m_name_builtin_function_map.insert( + std::make_pair("builtinToBuiltin", + std::make_shared< + BuiltinFunctionEmbedder<std::shared_ptr<const double>(std::shared_ptr<const double>)>>( + [](std::shared_ptr<const double> x) -> std::shared_ptr<const double> { return x; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_BtoR", std::make_shared<BuiltinFunctionEmbedder<double(std::vector<bool>)>>( + [](const std::vector<bool>&) -> double { return 0.5; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_NtoR", std::make_shared<BuiltinFunctionEmbedder<double(std::vector<uint64_t>)>>( + [](const std::vector<uint64_t>&) -> double { return 0.5; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_ZtoR", std::make_shared<BuiltinFunctionEmbedder<double(std::vector<int64_t>)>>( + [](const std::vector<int64_t>&) -> double { return 0.5; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_RtoB", std::make_shared<BuiltinFunctionEmbedder<bool(std::vector<double>)>>( + [](const std::vector<double>&) -> bool { return false; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_stringtoB", std::make_shared<BuiltinFunctionEmbedder<bool(std::vector<std::string>)>>( + [](const std::vector<std::string>&) -> bool { return true; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_builtinToB", + std::make_shared<BuiltinFunctionEmbedder<bool(std::vector<std::shared_ptr<const double>>)>>( + [](const std::vector<std::shared_ptr<const double>>&) -> bool { return true; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_R1ToR", + std::make_shared<BuiltinFunctionEmbedder<double(const std::vector<TinyVector<1>>&)>>( + [](const std::vector<TinyVector<1>>&) -> double { return 1; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_R2ToR", + std::make_shared<BuiltinFunctionEmbedder<double(const std::vector<TinyVector<2>>&)>>( + [](const std::vector<TinyVector<2>>&) -> double { return 1; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_R3ToR", std::make_shared<BuiltinFunctionEmbedder<double(const std::vector<TinyVector<3>>)>>( + [](const std::vector<TinyVector<3>>&) -> double { return 0; }))); + } + + void + _addBuiltinTypeAndVariables(ASTNode& ast) + { + SymbolTable& symbol_table = *ast.m_symbol_table; + auto [i_symbol, success] = symbol_table.add(builtin_data_type.nameOfTypeId(), ast.begin()); + if (not success) { + throw UnexpectedError("cannot add '" + builtin_data_type.nameOfTypeId() + "' type for testing"); + } + + i_symbol->attributes().setDataType(ASTNodeDataType::type_name_id_t); + i_symbol->attributes().setIsInitialized(); + i_symbol->attributes().value() = symbol_table.typeEmbedderTable().size(); + symbol_table.typeEmbedderTable().add(std::make_shared<TypeDescriptor>(builtin_data_type.nameOfTypeId())); + + auto [i_symbol_a, success_a] = symbol_table.add("a", ast.begin()); + if (not success_a) { + throw UnexpectedError("cannot add 'a' of type builtin_t for testing"); + } + i_symbol_a->attributes().setDataType(ast_node_data_type_from<std::shared_ptr<const double>>); + i_symbol_a->attributes().setIsInitialized(); + auto [i_symbol_b, success_b] = symbol_table.add("b", ast.begin()); + if (not success_b) { + throw UnexpectedError("cannot add 'b' of type builtin_t for testing"); + } + i_symbol_b->attributes().setDataType(ast_node_data_type_from<std::shared_ptr<const double>>); + i_symbol_b->attributes().setIsInitialized(); + } + + public: + test_BuiltinFunctionRegister(ASTNode& root_node) + { + SymbolTable& symbol_table = *root_node.m_symbol_table; + + auto& builtin_function_embedder_table = symbol_table.builtinFunctionEmbedderTable(); + + this->_populateNameBuiltinFunctionMap(); + this->_addBuiltinTypeAndVariables(root_node); + + for (const auto& [symbol_name, builtin_function] : m_name_builtin_function_map) { + auto [i_symbol, success] = symbol_table.add(symbol_name, root_node.begin()); + + if (not success) { + std::ostringstream error_message; + error_message << "cannot add symbol '" << symbol_name << "' it is already defined"; + throw parse_error(error_message.str(), root_node.begin()); + } + + i_symbol->attributes().setDataType(ASTNodeDataType::builtin_function_t); + i_symbol->attributes().setIsInitialized(); + i_symbol->attributes().value() = builtin_function_embedder_table.size(); + + builtin_function_embedder_table.add(builtin_function); + } + } +}; +} // namespace test_only + +#endif /* TEST_BUILTIN_FUNCTION_REGISTER_H */