diff --git a/src/language/ASTNodeDataTypeBuilder.cpp b/src/language/ASTNodeDataTypeBuilder.cpp index dfde6bb6ad0ce993f5367a468b583103ad4bd240..3e003392007b8ccc5250c14fed31a94e36d3be22 100644 --- a/src/language/ASTNodeDataTypeBuilder.cpp +++ b/src/language/ASTNodeDataTypeBuilder.cpp @@ -320,8 +320,9 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const ASTNodeDataType data_type{ASTNodeDataType::undefined_t}; if (image_domain_node.children.size() > 0) { - throw parse_error("compound data type is not implemented yet", image_domain_node.begin()); + data_type = image_domain_node.m_data_type; } else { +#warning check if it is really useful to compute exact types here? if (image_domain_node.is_type<language::B_set>()) { data_type = ASTNodeDataType::bool_t; } else if (image_domain_node.is_type<language::Z_set>()) { diff --git a/src/language/ASTNodeFunctionExpressionBuilder.cpp b/src/language/ASTNodeFunctionExpressionBuilder.cpp index ebf00082e315227a23ab2a5f9f520d6a758cc398..8833958c6009246f8fbb3a0745bf2912786929b1 100644 --- a/src/language/ASTNodeFunctionExpressionBuilder.cpp +++ b/src/language/ASTNodeFunctionExpressionBuilder.cpp @@ -140,26 +140,30 @@ PUGS_INLINE std::unique_ptr<INodeProcessor> ASTNodeFunctionExpressionBuilder::_getFunctionProcessor(const ASTNodeDataType expression_value_type, const ASTNodeDataType return_value_type, - ASTNode& node) + ASTNode& node, + ASTNode& function_component_expression, + ASTNodeDataVariant& node_value) { auto get_function_processor_for_expression_value = [&](const auto& return_v) -> std::unique_ptr<INodeProcessor> { using ReturnT = std::decay_t<decltype(return_v)>; switch (expression_value_type) { case ASTNodeDataType::bool_t: { - return std::make_unique<FunctionExpressionProcessor<ReturnT, bool>>(node); + return std::make_unique<FunctionExpressionProcessor<ReturnT, bool>>(function_component_expression, node_value); } case ASTNodeDataType::unsigned_int_t: { - return std::make_unique<FunctionExpressionProcessor<ReturnT, uint64_t>>(node); + return std::make_unique<FunctionExpressionProcessor<ReturnT, uint64_t>>(function_component_expression, + node_value); } case ASTNodeDataType::int_t: { - return std::make_unique<FunctionExpressionProcessor<ReturnT, int64_t>>(node); + return std::make_unique<FunctionExpressionProcessor<ReturnT, int64_t>>(function_component_expression, node_value); } case ASTNodeDataType::double_t: { - return std::make_unique<FunctionExpressionProcessor<ReturnT, double>>(node); + return std::make_unique<FunctionExpressionProcessor<ReturnT, double>>(function_component_expression, node_value); } case ASTNodeDataType::string_t: { if constexpr (std::is_same_v<ReturnT, std::string>) { - return std::make_unique<FunctionExpressionProcessor<ReturnT, std::string>>(node); + return std::make_unique<FunctionExpressionProcessor<ReturnT, std::string>>(function_component_expression, + node_value); } else { throw parse_error("invalid string conversion", std::vector{node.children[1]->begin()}); } @@ -211,21 +215,52 @@ ASTNodeFunctionExpressionBuilder::ASTNodeFunctionExpressionBuilder(ASTNode& node FunctionDescriptor& function_descriptor = node.m_symbol_table->functionTable()[function_id]; - if (function_descriptor.definitionNode().children[1]->is_type<language::expression_list>()) { - // LCOV_EXCL_START - throw parse_error("unexpected error: function expression list is not implemented yet", - std::vector{function_descriptor.definitionNode().children[1]->begin()}); - // LCOV_EXCL_STOP - } - std::unique_ptr function_processor = std::make_unique<FunctionProcessor>(); this->_buildArgumentProcessors(function_descriptor, node, *function_processor); - const ASTNodeDataType expression_value_type = function_descriptor.definitionNode().children[1]->m_data_type; - const ASTNodeDataType return_value_type = node.m_data_type; - function_processor->addFunctionExpressionProcessor( - this->_getFunctionProcessor(expression_value_type, return_value_type, node)); + ASTNode& function_image_domain = *function_descriptor.domainMappingNode().children[1]; + ASTNode& function_expression = *function_descriptor.definitionNode().children[1]; + + auto add_component_expression = [&](ASTNode& expression_node, ASTNode& domain_node, ASTNodeDataVariant& value) { + ASTNodeDataType expression_value_type = expression_node.m_data_type; + ASTNodeDataType return_value_type = ASTNodeDataType::undefined_t; + + ASTNode& image_domain_node = domain_node; + + if (image_domain_node.is_type<language::B_set>()) { + return_value_type = ASTNodeDataType::bool_t; + } else if (image_domain_node.is_type<language::Z_set>()) { + return_value_type = ASTNodeDataType::int_t; + } else if (image_domain_node.is_type<language::N_set>()) { + return_value_type = ASTNodeDataType::unsigned_int_t; + } else if (image_domain_node.is_type<language::R_set>()) { + return_value_type = ASTNodeDataType::double_t; + } else if (image_domain_node.is_type<language::string_type>()) { + return_value_type = ASTNodeDataType::string_t; + } + + Assert(return_value_type != ASTNodeDataType::undefined_t); + + function_processor->addFunctionExpressionProcessor( + this->_getFunctionProcessor(expression_value_type, return_value_type, node, expression_node, value)); + }; + + if (function_expression.is_type<language::expression_list>()) { + Assert(function_image_domain.is_type<language::type_expression>()); + ASTNode& image_domain_node = function_image_domain; + const size_t& nb_component = function_expression.children.size(); + + AggregateDataVariant aggregate_value(nb_component); + + for (size_t i = 0; i < function_expression.children.size(); ++i) { + add_component_expression(*function_expression.children[i], *image_domain_node.children[i], aggregate_value[i]); + } + + node.m_value = std::move(aggregate_value); + } else { + add_component_expression(function_expression, function_image_domain, node.m_value); + } node.m_node_processor = std::move(function_processor); } diff --git a/src/language/ASTNodeFunctionExpressionBuilder.hpp b/src/language/ASTNodeFunctionExpressionBuilder.hpp index 4bcd172b9a46b8300d0e14c6eb1db4b182564ea1..f8f69e9c6c9f3363db9d9e3c57fdf0c8d6bbc521 100644 --- a/src/language/ASTNodeFunctionExpressionBuilder.hpp +++ b/src/language/ASTNodeFunctionExpressionBuilder.hpp @@ -27,7 +27,9 @@ class ASTNodeFunctionExpressionBuilder PUGS_INLINE std::unique_ptr<INodeProcessor> _getFunctionProcessor(const ASTNodeDataType expression_value_type, const ASTNodeDataType return_value_type, - ASTNode& node); + ASTNode& node, + ASTNode& function_component_expression, + ASTNodeDataVariant& node_value); public: ASTNodeFunctionExpressionBuilder(ASTNode& node); diff --git a/src/language/node_processor/FunctionProcessor.hpp b/src/language/node_processor/FunctionProcessor.hpp index a4e803b14093b55fdf9259f2be53c4555ac3bfe8..ccc7ce560b9ca09213dd4a8aebc796dfea66442b 100644 --- a/src/language/node_processor/FunctionProcessor.hpp +++ b/src/language/node_processor/FunctionProcessor.hpp @@ -39,7 +39,7 @@ template <typename ReturnType, typename ExpressionValueType> class FunctionExpressionProcessor final : public INodeProcessor { private: - ASTNode& m_node; + ASTNodeDataVariant& m_value; ASTNode& m_function_expression; public: @@ -49,23 +49,16 @@ class FunctionExpressionProcessor final : public INodeProcessor m_function_expression.execute(exec_policy); if constexpr (std::is_same_v<ReturnType, ExpressionValueType>) { - m_node.m_value = m_function_expression.m_value; + m_value = m_function_expression.m_value; } else if constexpr (std::is_same_v<ReturnType, std::string>) { - m_node.m_value = std::to_string(std::get<ExpressionValueType>(m_function_expression.m_value)); + m_value = std::to_string(std::get<ExpressionValueType>(m_function_expression.m_value)); } else { - m_node.m_value = static_cast<ReturnType>(std::get<ExpressionValueType>(m_function_expression.m_value)); + m_value = static_cast<ReturnType>(std::get<ExpressionValueType>(m_function_expression.m_value)); } } - FunctionExpressionProcessor(ASTNode& node) - : m_node{node}, m_function_expression{[&]() -> ASTNode& { - auto [i_symbol, found] = m_node.m_symbol_table->find(m_node.children[0]->string(), m_node.begin()); - Assert(found); - uint64_t function_id = std::get<uint64_t>(i_symbol->attributes().value()); - - FunctionDescriptor& function_descriptor = m_node.m_symbol_table->functionTable()[function_id]; - return *function_descriptor.definitionNode().children[1]; - }()} + FunctionExpressionProcessor(ASTNode& function_component_expression, ASTNodeDataVariant& value) + : m_value{value}, m_function_expression{function_component_expression} {} };