diff --git a/src/language/ASTNodeDataTypeFlattener.cpp b/src/language/ASTNodeDataTypeFlattener.cpp index b499c6f3802b243ad4ece3970c937e1b6ff75a51..31059e273b9ff37f8ca7d48043d6aa5b3d9b3ef3 100644 --- a/src/language/ASTNodeDataTypeFlattener.cpp +++ b/src/language/ASTNodeDataTypeFlattener.cpp @@ -7,7 +7,7 @@ ASTNodeDataTypeFlattener::ASTNodeDataTypeFlattener(ASTNode& node, FlattenedDataType& flattened_datatype) { - if (node.is_type<language::expression_list>()) { + if (node.is_type<language::expression_list>() or node.is_type<language::function_argument_list>()) { for (auto& child_node : node.children) { ASTNodeDataTypeFlattener{*child_node, flattened_datatype}; } diff --git a/src/language/ASTNodeExpressionBuilder.cpp b/src/language/ASTNodeExpressionBuilder.cpp index e745d24f82ff2c22c609701dcab9a0431e551ee3..238d61bd0382ba9d1ef4e68784881f7ed5529785 100644 --- a/src/language/ASTNodeExpressionBuilder.cpp +++ b/src/language/ASTNodeExpressionBuilder.cpp @@ -55,10 +55,7 @@ ASTNodeExpressionBuilder::_buildExpression(ASTNode& n) } else if (n.is_type<language::false_kw>()) { n.m_node_processor = std::make_unique<ValueProcessor>(n); - } else if (n.is_type<language::function_argument_list>()) { - n.m_node_processor = std::make_unique<FakeProcessor>(); - - } else if (n.is_type<language::expression_list>()) { + } else if ((n.is_type<language::function_argument_list>()) or (n.is_type<language::expression_list>())) { n.m_node_processor = std::make_unique<ASTNodeExpressionListProcessor>(n); } else if (n.is_type<language::name_list>()) { diff --git a/src/language/ASTNodeFunctionExpressionBuilder.cpp b/src/language/ASTNodeFunctionExpressionBuilder.cpp index 358892b6694ce7548aae331082bc4c5dde8e6f51..172c4c48100e03c940ff649f52b7bb88f3e765ce 100644 --- a/src/language/ASTNodeFunctionExpressionBuilder.cpp +++ b/src/language/ASTNodeFunctionExpressionBuilder.cpp @@ -4,26 +4,29 @@ #include <FunctionTable.hpp> #include <SymbolTable.hpp> +#include <ASTNodeDataTypeFlattener.hpp> + #include <node_processor/FunctionProcessor.hpp> template <typename SymbolType> -PUGS_INLINE std::unique_ptr<INodeProcessor> +PUGS_INLINE std::unique_ptr<IFunctionArgumentConverter> ASTNodeFunctionExpressionBuilder::_getArgumentProcessor(SymbolType& parameter_symbol, ASTNode& argument_node) { - auto get_function_argument_processor_for = [&](const auto& parameter_v) -> std::unique_ptr<INodeProcessor> { + auto get_function_argument_processor_for = + [&](const auto& parameter_v) -> std::unique_ptr<IFunctionArgumentConverter> { using ParameterT = std::decay_t<decltype(parameter_v)>; switch (argument_node.m_data_type) { case ASTNodeDataType::bool_t: { - return std::make_unique<FunctionArgumentProcessor<ParameterT, bool>>(parameter_symbol, argument_node); + return std::make_unique<FunctionArgumentConverter<ParameterT, bool>>(parameter_symbol); } case ASTNodeDataType::unsigned_int_t: { - return std::make_unique<FunctionArgumentProcessor<ParameterT, uint64_t>>(parameter_symbol, argument_node); + return std::make_unique<FunctionArgumentConverter<ParameterT, uint64_t>>(parameter_symbol); } case ASTNodeDataType::int_t: { - return std::make_unique<FunctionArgumentProcessor<ParameterT, int64_t>>(parameter_symbol, argument_node); + return std::make_unique<FunctionArgumentConverter<ParameterT, int64_t>>(parameter_symbol); } case ASTNodeDataType::double_t: { - return std::make_unique<FunctionArgumentProcessor<ParameterT, double>>(parameter_symbol, argument_node); + return std::make_unique<FunctionArgumentConverter<ParameterT, double>>(parameter_symbol); } // LCOV_EXCL_START default: { @@ -33,22 +36,22 @@ ASTNodeFunctionExpressionBuilder::_getArgumentProcessor(SymbolType& parameter_sy } }; - auto get_function_argument_processor_for_string = [&]() -> std::unique_ptr<INodeProcessor> { + auto get_function_argument_processor_for_string = [&]() -> std::unique_ptr<IFunctionArgumentConverter> { switch (argument_node.m_data_type) { case ASTNodeDataType::bool_t: { - return std::make_unique<FunctionArgumentProcessor<std::string, bool>>(parameter_symbol, argument_node); + return std::make_unique<FunctionArgumentConverter<std::string, bool>>(parameter_symbol); } case ASTNodeDataType::unsigned_int_t: { - return std::make_unique<FunctionArgumentProcessor<std::string, uint64_t>>(parameter_symbol, argument_node); + return std::make_unique<FunctionArgumentConverter<std::string, uint64_t>>(parameter_symbol); } case ASTNodeDataType::int_t: { - return std::make_unique<FunctionArgumentProcessor<std::string, int64_t>>(parameter_symbol, argument_node); + return std::make_unique<FunctionArgumentConverter<std::string, int64_t>>(parameter_symbol); } case ASTNodeDataType::double_t: { - return std::make_unique<FunctionArgumentProcessor<std::string, double>>(parameter_symbol, argument_node); + return std::make_unique<FunctionArgumentConverter<std::string, double>>(parameter_symbol); } case ASTNodeDataType::string_t: { - return std::make_unique<FunctionArgumentProcessor<std::string, std::string>>(parameter_symbol, argument_node); + return std::make_unique<FunctionArgumentConverter<std::string, std::string>>(parameter_symbol); } // LCOV_EXCL_START default: { @@ -103,18 +106,26 @@ ASTNodeFunctionExpressionBuilder::_storeArgumentProcessor(ASTNode& parameter_var } PUGS_INLINE -void -ASTNodeFunctionExpressionBuilder::_buildArgumentProcessors(FunctionDescriptor& function_descriptor, - ASTNode& node, - FunctionProcessor& function_processor) +std::unique_ptr<FunctionProcessor> +ASTNodeFunctionExpressionBuilder::_buildArgumentProcessors(FunctionDescriptor& function_descriptor, ASTNode& node) { + ASTNode& function_expression = *function_descriptor.definitionNode().children[1]; + + Assert(function_expression.m_symbol_table->hasContext()); + const SymbolTable::Context& context = function_expression.m_symbol_table->context(); + const ASTNode& definition_node = function_descriptor.definitionNode(); ASTNode& parameter_variables = *definition_node.children[0]; ASTNode& argument_nodes = *node.children[1]; - const size_t arguments_number = - argument_nodes.is_type<language::function_argument_list>() ? argument_nodes.children.size() : 1; + std::unique_ptr function_processor = std::make_unique<FunctionProcessor>(argument_nodes, context); + + ASTNodeDataTypeFlattener::FlattenedDataType flattened_datatype; + ASTNodeDataTypeFlattener{argument_nodes, flattened_datatype}; + + const size_t arguments_number = flattened_datatype.size(); + const size_t parameters_number = parameter_variables.is_type<language::name_list>() ? parameter_variables.children.size() : 1; @@ -129,11 +140,13 @@ ASTNodeFunctionExpressionBuilder::_buildArgumentProcessors(FunctionDescriptor& f for (size_t i = 0; i < arguments_number; ++i) { ASTNode& parameter_variable = *parameter_variables.children[i]; ASTNode& argument_node = *argument_nodes.children[i]; - this->_storeArgumentProcessor(parameter_variable, argument_node, function_processor); + this->_storeArgumentProcessor(parameter_variable, argument_node, *function_processor); } } else { - this->_storeArgumentProcessor(parameter_variables, argument_nodes, function_processor); + this->_storeArgumentProcessor(parameter_variables, argument_nodes, *function_processor); } + + return function_processor; } PUGS_INLINE @@ -212,15 +225,7 @@ ASTNodeFunctionExpressionBuilder::ASTNodeFunctionExpressionBuilder(ASTNode& node FunctionDescriptor& function_descriptor = node.m_symbol_table->functionTable()[function_id]; - ASTNode& function_image_domain = *function_descriptor.domainMappingNode().children[1]; - ASTNode& function_expression = *function_descriptor.definitionNode().children[1]; - - Assert(function_expression.m_symbol_table->hasContext()); - const SymbolTable::Context& context = function_expression.m_symbol_table->context(); - - std::unique_ptr function_processor = std::make_unique<FunctionProcessor>(context); - - this->_buildArgumentProcessors(function_descriptor, node, *function_processor); + std::unique_ptr function_processor = this->_buildArgumentProcessors(function_descriptor, node); auto add_component_expression = [&](ASTNode& expression_node, ASTNode& domain_node) { ASTNodeDataType expression_value_type = expression_node.m_data_type; @@ -246,6 +251,9 @@ ASTNodeFunctionExpressionBuilder::ASTNodeFunctionExpressionBuilder(ASTNode& node this->_getFunctionProcessor(expression_value_type, return_value_type, node, expression_node)); }; + ASTNode& function_image_domain = *function_descriptor.domainMappingNode().children[1]; + ASTNode& function_expression = *function_descriptor.definitionNode().children[1]; + if (function_expression.is_type<language::expression_list>()) { Assert(function_image_domain.is_type<language::type_expression>()); ASTNode& image_domain_node = function_image_domain; diff --git a/src/language/ASTNodeFunctionExpressionBuilder.hpp b/src/language/ASTNodeFunctionExpressionBuilder.hpp index 193d60e27ad27e6c705676b1fcf3fdf2baf85330..5358844eda6d9d1e4b54db986a815af96e974363 100644 --- a/src/language/ASTNodeFunctionExpressionBuilder.hpp +++ b/src/language/ASTNodeFunctionExpressionBuilder.hpp @@ -6,13 +6,14 @@ class FunctionProcessor; class FunctionDescriptor; +class IFunctionArgumentConverter; class ASTNodeFunctionExpressionBuilder { private: template <typename SymbolType> - PUGS_INLINE std::unique_ptr<INodeProcessor> _getArgumentProcessor(SymbolType& parameter_symbol, - ASTNode& argument_node); + PUGS_INLINE std::unique_ptr<IFunctionArgumentConverter> _getArgumentProcessor(SymbolType& parameter_symbol, + ASTNode& argument_node); PUGS_INLINE void _storeArgumentProcessor(ASTNode& parameter_variable, @@ -20,9 +21,7 @@ class ASTNodeFunctionExpressionBuilder FunctionProcessor& function_processor); PUGS_INLINE - void _buildArgumentProcessors(FunctionDescriptor& function_descriptor, - ASTNode& node, - FunctionProcessor& function_processor); + std::unique_ptr<FunctionProcessor> _buildArgumentProcessors(FunctionDescriptor& function_descriptor, ASTNode& node); PUGS_INLINE std::unique_ptr<INodeProcessor> _getFunctionProcessor(const ASTNodeDataType expression_value_type, diff --git a/src/language/node_processor/FunctionProcessor.hpp b/src/language/node_processor/FunctionProcessor.hpp index d584f77e4a482aae0e1acf47961529c33a3c8cee..7c1e06917fab5ba5c2261ab963e8aa214174d43d 100644 --- a/src/language/node_processor/FunctionProcessor.hpp +++ b/src/language/node_processor/FunctionProcessor.hpp @@ -8,31 +8,36 @@ #include <node_processor/INodeProcessor.hpp> +#include <node_processor/ASTNodeExpressionListProcessor.hpp> + +struct IFunctionArgumentConverter +{ + virtual DataVariant convert(ExecutionPolicy& exec_policy, DataVariant&& value) = 0; +}; + template <typename ExpectedValueType, typename ProvidedValueType> -class FunctionArgumentProcessor final : public INodeProcessor +class FunctionArgumentConverter final : public IFunctionArgumentConverter { private: size_t m_symbol_id; - ASTNode& m_provided_value_node; public: DataVariant - execute(ExecutionPolicy& exec_policy) + convert(ExecutionPolicy& exec_policy, DataVariant&& value) { if constexpr (std::is_same_v<ExpectedValueType, ProvidedValueType>) { - exec_policy.currentContext()[m_symbol_id] = m_provided_value_node.execute(exec_policy); + exec_policy.currentContext()[m_symbol_id] = std::move(value); } else if constexpr (std::is_same_v<ExpectedValueType, std::string>) { - exec_policy.currentContext()[m_symbol_id] = - std::to_string(std::get<ProvidedValueType>(m_provided_value_node.execute(exec_policy))); + exec_policy.currentContext()[m_symbol_id] = std::move(std::to_string(std::get<ProvidedValueType>(value))); } else { exec_policy.currentContext()[m_symbol_id] = - static_cast<ExpectedValueType>(std::get<ProvidedValueType>(m_provided_value_node.execute(exec_policy))); + std::move(static_cast<ExpectedValueType>(std::get<ProvidedValueType>(value))); } return {}; } - FunctionArgumentProcessor(SymbolTable::Symbol& argument_symbol, ASTNode& provided_value_node) - : m_symbol_id{std::get<size_t>(argument_symbol.attributes().value())}, m_provided_value_node{provided_value_node} + FunctionArgumentConverter(SymbolTable::Symbol& argument_symbol) + : m_symbol_id{std::get<size_t>(argument_symbol.attributes().value())} {} }; @@ -63,17 +68,19 @@ class FunctionExpressionProcessor final : public INodeProcessor class FunctionProcessor : public INodeProcessor { private: + ASTNode& m_argument_node; + const size_t m_context_size; const int32_t m_context_id; - std::vector<std::unique_ptr<INodeProcessor>> m_argument_processors; + std::vector<std::unique_ptr<IFunctionArgumentConverter>> m_argument_converters; std::vector<std::unique_ptr<INodeProcessor>> m_function_expression_processors; public: void - addArgumentProcessor(std::unique_ptr<INodeProcessor>&& argument_processor) + addArgumentProcessor(std::unique_ptr<IFunctionArgumentConverter>&& argument_converter) { - m_argument_processors.emplace_back(std::move(argument_processor)); + m_argument_converters.emplace_back(std::move(argument_converter)); } void @@ -90,8 +97,15 @@ class FunctionProcessor : public INodeProcessor std::make_shared<ExecutionPolicy::Context::Values>( m_context_size)}}; - for (auto& argument_processor : m_argument_processors) { - argument_processor->execute(context_exec_policy); + if (m_argument_node.is_type<language::function_argument_list>()) { + AggregateDataVariant argument_values{ + std::get<AggregateDataVariant>(m_argument_node.execute(context_exec_policy))}; + + for (size_t i = 0; i < m_argument_converters.size(); ++i) { + m_argument_converters[i]->convert(context_exec_policy, std::move(argument_values[i])); + } + } else { + m_argument_converters[0]->convert(context_exec_policy, std::move(m_argument_node.execute(context_exec_policy))); } if (m_function_expression_processors.size() == 1) { @@ -107,7 +121,9 @@ class FunctionProcessor : public INodeProcessor } } - FunctionProcessor(const SymbolTable::Context& context) : m_context_size{context.size()}, m_context_id{context.id()} {} + FunctionProcessor(ASTNode& argument_node, const SymbolTable::Context& context) + : m_argument_node{argument_node}, m_context_size{context.size()}, m_context_id{context.id()} + {} }; #endif // FUNCTION_PROCESSOR_HPP diff --git a/tests/test_ASTNodeCFunctionExpressionBuilder.cpp b/tests/test_ASTNodeCFunctionExpressionBuilder.cpp index da62df5a0e1e9d2adf4b6ba53d5673e428fa7e2c..162c34c07b5f4ba639efcf91032847a7cc7f74a2 100644 --- a/tests/test_ASTNodeCFunctionExpressionBuilder.cpp +++ b/tests/test_ASTNodeCFunctionExpressionBuilder.cpp @@ -411,7 +411,7 @@ R2toB(1., 0.); (root:ASTNodeListProcessor) `-(language::function_evaluation:CFunctionProcessor) +-(language::name:R2toB:NameProcessor) - `-(language::function_argument_list:FakeProcessor) + `-(language::function_argument_list:ASTNodeExpressionListProcessor) +-(language::real:1.:ValueProcessor) `-(language::real:0.:ValueProcessor) )"; diff --git a/tests/test_ASTNodeFunctionEvaluationExpressionBuilder.cpp b/tests/test_ASTNodeFunctionEvaluationExpressionBuilder.cpp index 80844f7bebca9e7fa9c9bbb78ff356a734408712..5c97bf253bc47ab0af77fdc95b57f602371e2852 100644 --- a/tests/test_ASTNodeFunctionEvaluationExpressionBuilder.cpp +++ b/tests/test_ASTNodeFunctionEvaluationExpressionBuilder.cpp @@ -71,7 +71,7 @@ sum(1,2); (root:ASTNodeListProcessor) `-(language::function_evaluation:FunctionProcessor) +-(language::name:sum:NameProcessor) - `-(language::function_argument_list:FakeProcessor) + `-(language::function_argument_list:ASTNodeExpressionListProcessor) +-(language::integer:1:ValueProcessor) `-(language::integer:2:ValueProcessor) )";