diff --git a/src/language/ASTNodeExpressionBuilder.cpp b/src/language/ASTNodeExpressionBuilder.cpp index 839404a00966c0e61c4d892d303c432f5713f996..f70b8010524899c858795733ca77588d730d899c 100644 --- a/src/language/ASTNodeExpressionBuilder.cpp +++ b/src/language/ASTNodeExpressionBuilder.cpp @@ -2,6 +2,7 @@ #include <ASTNodeAffectationExpressionBuilder.hpp> #include <ASTNodeBinaryOperatorExpressionBuilder.hpp> +#include <ASTNodeFunctionExpressionBuilder.hpp> #include <ASTNodeIncDecExpressionBuilder.hpp> #include <ASTNodeUnaryOperatorExpressionBuilder.hpp> @@ -11,7 +12,6 @@ #include <node_processor/DoWhileProcessor.hpp> #include <node_processor/FakeProcessor.hpp> #include <node_processor/ForProcessor.hpp> -#include <node_processor/FunctionProcessor.hpp> #include <node_processor/IfProcessor.hpp> #include <node_processor/NameProcessor.hpp> #include <node_processor/OStreamProcessor.hpp> @@ -32,7 +32,7 @@ ASTNodeExpressionBuilder::_buildExpression(ASTNode& n) n.m_node_processor = std::make_unique<FakeProcessor>(); } else if (n.is<language::function_evaluation>()) { - n.m_node_processor = std::make_unique<FunctionProcessor>(n); + ASTNodeFunctionExpressionBuilder{n}; } else if (n.is<language::real>()) { n.m_node_processor = std::make_unique<FakeProcessor>(); diff --git a/src/language/ASTNodeFunctionExpressionBuilder.cpp b/src/language/ASTNodeFunctionExpressionBuilder.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e3238d45ba078254f801bff0120ab2bf1ef8124d --- /dev/null +++ b/src/language/ASTNodeFunctionExpressionBuilder.cpp @@ -0,0 +1,76 @@ +#include <ASTNodeFunctionExpressionBuilder.hpp> +#include <PEGGrammar.hpp> + +#include <FunctionTable.hpp> +#include <SymbolTable.hpp> + +#include <node_processor/FunctionProcessor.hpp> + +ASTNodeFunctionExpressionBuilder::ASTNodeFunctionExpressionBuilder(ASTNode& node) +{ + auto [i_symbol, found] = node.m_symbol_table->find(node.children[0]->string(), node.begin()); + Assert(found); + uint64_t function_id = std::get<uint64_t>(i_symbol->attributes().value()); + + FunctionDescriptor& function_descriptor = node.m_symbol_table->functionTable()[function_id]; + +#warning compute the right value type + const ASTNodeDataType return_value_type = ASTNodeDataType::double_t; + const ASTNodeDataType expression_value_type = function_descriptor.definitionNode().children[1]->m_data_type; + + auto set_function_processor = [&](ASTNode& node) { + auto set_function_processor_for_expression_value = [&](const auto& return_v) { + using ReturnT = std::decay_t<decltype(return_v)>; + switch (expression_value_type) { + case ASTNodeDataType::bool_t: { + node.m_node_processor = std::make_unique<FunctionProcessor<ReturnT, bool>>(node); + break; + } + case ASTNodeDataType::unsigned_int_t: { + node.m_node_processor = std::make_unique<FunctionProcessor<ReturnT, uint64_t>>(node); + break; + } + case ASTNodeDataType::int_t: { + node.m_node_processor = std::make_unique<FunctionProcessor<ReturnT, int64_t>>(node); + break; + } + case ASTNodeDataType::double_t: { + node.m_node_processor = std::make_unique<FunctionProcessor<ReturnT, double>>(node); + break; + } + default: { + throw parse_error("unexpected error: undefined expression value type for function", + std::vector{node.children[1]->begin()}); + } + } + }; + + auto set_function_processor_for_value = [&]() { + switch (return_value_type) { + case ASTNodeDataType::bool_t: { + set_function_processor_for_expression_value(bool{}); + break; + } + case ASTNodeDataType::unsigned_int_t: { + set_function_processor_for_expression_value(uint64_t{}); + break; + } + case ASTNodeDataType::int_t: { + set_function_processor_for_expression_value(int64_t{}); + break; + } + case ASTNodeDataType::double_t: { + set_function_processor_for_expression_value(double{}); + break; + } + default: { + throw parse_error("unexpected error: undefined return type for function", std::vector{node.begin()}); + } + } + }; + + set_function_processor_for_value(); + }; + + set_function_processor(node); +} diff --git a/src/language/ASTNodeFunctionExpressionBuilder.hpp b/src/language/ASTNodeFunctionExpressionBuilder.hpp new file mode 100644 index 0000000000000000000000000000000000000000..adf3cb48d7b21091289de28297ca2c786f1a6a5e --- /dev/null +++ b/src/language/ASTNodeFunctionExpressionBuilder.hpp @@ -0,0 +1,11 @@ +#ifndef AST_NODE_FUNCTION_EXPRESSION_BUILDER_HPP +#define AST_NODE_FUNCTION_EXPRESSION_BUILDER_HPP + +#include <ASTNode.hpp> + +struct ASTNodeFunctionExpressionBuilder +{ + ASTNodeFunctionExpressionBuilder(ASTNode& node); +}; + +#endif // AST_NODE_FUNCTION_EXPRESSION_BUILDER_HPP diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt index ab42c18cc035467baa7bb3dcccc72d55d53d51a0..1e6777998f93cd2de07d1e416413d2725ae44a0c 100644 --- a/src/language/CMakeLists.txt +++ b/src/language/CMakeLists.txt @@ -18,6 +18,7 @@ add_library( ASTNodeDeclarationCleaner.cpp ASTNodeEmptyBlockCleaner.cpp ASTNodeExpressionBuilder.cpp + ASTNodeFunctionExpressionBuilder.cpp ASTNodeIncDecExpressionBuilder.cpp ASTNodeJumpPlacementChecker.cpp ASTNodeUnaryOperatorExpressionBuilder.cpp diff --git a/src/language/node_processor/FunctionProcessor.hpp b/src/language/node_processor/FunctionProcessor.hpp index 4527b0b6ebe3dd337b43f71ce7b88a1025d94038..57394f993d26322eb0fc6c8590bcbfaa8c8bc1d5 100644 --- a/src/language/node_processor/FunctionProcessor.hpp +++ b/src/language/node_processor/FunctionProcessor.hpp @@ -6,8 +6,11 @@ #include <PEGGrammar.hpp> +#include <ASTPrinter.hpp> + #include <node_processor/INodeProcessor.hpp> +template <typename ReturnType, typename ExpressionValueType> class FunctionProcessor final : public INodeProcessor { private: @@ -15,9 +18,8 @@ class FunctionProcessor final : public INodeProcessor FunctionDescriptor& m_function_descriptor; - public: void - execute(ExecUntilBreakOrContinue& exec_policy) + _executeArguments(ExecUntilBreakOrContinue& exec_policy) { // Compute arguments values ASTNode& arguments_values = *m_node.children[1]; @@ -33,15 +35,31 @@ class FunctionProcessor final : public INodeProcessor auto [i_symbol, found] = arguments.m_symbol_table->find(arguments.string(), arguments.begin()); Assert(found); - i_symbol->attributes().value() = arguments_values.m_value; + if (i_symbol->attributes().dataType() == arguments_values.m_data_type) { + i_symbol->attributes().value() = arguments_values.m_value; + } else { + throw parse_error("argument type conversion not implemented yet!", arguments_values.begin()); + } } else { - throw parse_error("argument list not implemented yet!", definition_node.children[0]->begin()); + throw parse_error("argument list not implemented yet!", arguments_values.begin()); } + } + public: + void + execute(ExecUntilBreakOrContinue& exec_policy) + { + this->_executeArguments(exec_policy); + + ASTNode& definition_node = m_function_descriptor.definitionNode(); ASTNode& function_expression = *definition_node.children[1]; function_expression.execute(exec_policy); - m_node.m_value = function_expression.m_value; + if constexpr (std::is_same_v<ReturnType, ExpressionValueType>) { + m_node.m_value = function_expression.m_value; + } else { + m_node.m_value = static_cast<ReturnType>(std::get<ExpressionValueType>(function_expression.m_value)); + } } FunctionProcessor(ASTNode& node)