diff --git a/src/language/ASTNodeCFunctionExpressionBuilder.cpp b/src/language/ASTNodeCFunctionExpressionBuilder.cpp index 02ab715f8c0f6deb16fc97421b46553dc9c66c45..ca9f36e6a6db1e71e395889c57ef94162a247272 100644 --- a/src/language/ASTNodeCFunctionExpressionBuilder.cpp +++ b/src/language/ASTNodeCFunctionExpressionBuilder.cpp @@ -1,16 +1,67 @@ #include <ASTNodeCFunctionExpressionBuilder.hpp> #include <PEGGrammar.hpp> -#include <FunctionTable.hpp> #include <SymbolTable.hpp> +#include <node_processor/CFunctionProcessor.hpp> + +PUGS_INLINE std::unique_ptr<INodeProcessor> +ASTNodeCFunctionExpressionBuilder::_getArgumentProcessor(ASTNode& argument_node) +{ +#warning use correct types + return std::make_unique<CFunctionArgumentProcessor<double, double>>(argument_node); +} + +PUGS_INLINE +void +ASTNodeCFunctionExpressionBuilder::_storeArgumentProcessor(ASTNode& argument_node, + CFunctionProcessor& c_function_processor) +{ + c_function_processor.addArgumentProcessor(this->_getArgumentProcessor(argument_node)); +} + +PUGS_INLINE +void +ASTNodeCFunctionExpressionBuilder::_buildArgumentProcessors(ASTNode& node, CFunctionProcessor& c_function_processor) +{ + ASTNode& argument_nodes = *node.children[1]; + + const size_t arguments_number = argument_nodes.is<language::expression_list>() ? argument_nodes.children.size() : 1; + +#warning use the correct number of parameters_domain_node + const size_t parameters_number = 1; + + if (arguments_number != parameters_number) { + std::ostringstream error_message; + error_message << "bad number of arguments: expecting " << rang::fgB::yellow << parameters_number + << rang::style::reset << ", provided " << rang::fgB::yellow << arguments_number << rang::style::reset; + throw parse_error(error_message.str(), argument_nodes.begin()); + } + + if (arguments_number > 1) { + for (size_t i = 0; i < arguments_number; ++i) { + ASTNode& argument_node = *argument_nodes.children[i]; + this->_storeArgumentProcessor(argument_node, c_function_processor); + } + } else { + this->_storeArgumentProcessor(argument_nodes, c_function_processor); + } +} + ASTNodeCFunctionExpressionBuilder::ASTNodeCFunctionExpressionBuilder(ASTNode& node) { auto [i_function_symbol, found] = node.m_symbol_table->find(node.children[0]->string(), node.begin()); Assert(found); Assert(i_function_symbol->attributes().dataType() == ASTNodeDataType::c_function_t); - // uint64_t function_id = std::get<uint64_t>(i_function_symbol->attributes().value()); +#warning use the correct arguments type + const ASTNodeDataType c_function_argument_type = ASTNodeDataType::double_t; + + std::unique_ptr c_function_processor = std::make_unique<CFunctionProcessor>(); + + this->_buildArgumentProcessors(node, *c_function_processor); + + ASTNodeDataType c_function_return_type = ASTNodeDataType::double_t; - throw parse_error("CFunction processor not implemented yet", node.begin()); + node.m_node_processor = std::move(c_function_processor); } diff --git a/src/language/ASTNodeCFunctionExpressionBuilder.hpp b/src/language/ASTNodeCFunctionExpressionBuilder.hpp index ca40e4718de2a1d2a1486b963b17621b63af7e04..f8d1951001bfe6e5912ceb3179680de0d33dbb73 100644 --- a/src/language/ASTNodeCFunctionExpressionBuilder.hpp +++ b/src/language/ASTNodeCFunctionExpressionBuilder.hpp @@ -4,8 +4,18 @@ #include <ASTNode.hpp> #include <node_processor/INodeProcessor.hpp> +class CFunctionProcessor; + class ASTNodeCFunctionExpressionBuilder { + PUGS_INLINE std::unique_ptr<INodeProcessor> _getArgumentProcessor(ASTNode& argument_node); + + PUGS_INLINE + void _storeArgumentProcessor(ASTNode& argument_node, CFunctionProcessor& c_function_processor); + + PUGS_INLINE + void _buildArgumentProcessors(ASTNode& node, CFunctionProcessor& c_function_processor); + public: ASTNodeCFunctionExpressionBuilder(ASTNode& node); }; diff --git a/src/language/ASTNodeFunctionExpressionBuilder.cpp b/src/language/ASTNodeFunctionExpressionBuilder.cpp index 910bd31264745164646d9e74f413961bb06b87e0..9cf9b18fd4d176767f08f486900ef1fc720996ae 100644 --- a/src/language/ASTNodeFunctionExpressionBuilder.cpp +++ b/src/language/ASTNodeFunctionExpressionBuilder.cpp @@ -168,13 +168,13 @@ ASTNodeFunctionExpressionBuilder::ASTNodeFunctionExpressionBuilder(ASTNode& node throw parse_error("unexpected error: function expression list is not implemented yet", std::vector{function_descriptor.definitionNode().children[1]->begin()}); } - const ASTNodeDataType return_value_type = node.m_data_type; - const ASTNodeDataType expression_value_type = function_descriptor.definitionNode().children[1]->m_data_type; 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)); diff --git a/src/language/node_processor/CFunctionProcessor.hpp b/src/language/node_processor/CFunctionProcessor.hpp new file mode 100644 index 0000000000000000000000000000000000000000..241196bf45e75dc0a484d364a482fe206ce0b8c5 --- /dev/null +++ b/src/language/node_processor/CFunctionProcessor.hpp @@ -0,0 +1,77 @@ +#ifndef CFUNCTION_PROCESSOR_HPP +#define CFUNCTION_PROCESSOR_HPP + +#include <PEGGrammar.hpp> + +#include <node_processor/INodeProcessor.hpp> + +template <typename ProvidedValueType, typename ExpectedValueType> +class CFunctionArgumentProcessor final : public INodeProcessor +{ + private: + ASTNode& m_provided_value_node; + + public: + void + execute(ExecUntilBreakOrContinue& exec_policy) + { + m_provided_value_node.execute(exec_policy); + + // if constexpr (std::is_same_v<ExpectedValueType, ProvidedValueType>) { + // m_symbol_value = m_provided_value_node.m_value; + // } else { + // m_symbol_value = static_cast<ExpectedValueType>(std::get<ProvidedValueType>(m_provided_value_node.m_value)); + // } + } + + CFunctionArgumentProcessor(ASTNode& provided_value_node) : m_provided_value_node{provided_value_node} {} +}; + +template <typename ReturnType, typename ExpressionValueType> +class CFunctionExpressionProcessor final : public INodeProcessor +{ + private: + ASTNode& m_node; + + public: + void + execute(ExecUntilBreakOrContinue& exec_policy) + { + // if constexpr (std::is_same_v<ReturnType, ExpressionValueType>) { + // m_node.m_value = m_function_expression.m_value; + // } else { + // m_node.m_value = static_cast<ReturnType>(std::get<ExpressionValueType>(m_function_expression.m_value)); + // } + } + + CFunctionExpressionProcessor(ASTNode& node) : m_node{node} {} +}; + +class CFunctionProcessor : public INodeProcessor +{ + private: + std::vector<std::unique_ptr<INodeProcessor>> m_argument_processors; + + public: + void + addArgumentProcessor(std::unique_ptr<INodeProcessor>&& argument_processor) + { + m_argument_processors.emplace_back(std::move(argument_processor)); + } + + void + execute(ExecUntilBreakOrContinue& exec_policy) + { + for (auto& argument_processor : m_argument_processors) { + argument_processor->execute(exec_policy); + } + + std::cerr << __FILE__ << ':' << __LINE__ << ": " << rang::fgB::red + << "execution of CFunctionProcessor not finished!" << rang::style::reset << '\n'; + std::exit(1); + } + + CFunctionProcessor() = default; +}; + +#endif // CFUNCTION_PROCESSOR_HPP