From 4a456ca0a7defaadcf9ae38dd9b1e9119a4dca80 Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Tue, 8 Oct 2019 18:08:45 +0200 Subject: [PATCH] Add support for scalar functions of multiple arguments Now `` let f : R*R->R, (x,y)->x*y; cout << f(2.3,4) << "\n"; `` prints the expected value `9.2` --- src/language/ASTNodeExpressionBuilder.cpp | 6 +++ .../ASTNodeFunctionExpressionBuilder.cpp | 49 +++++++++---------- .../ASTNodeFunctionExpressionBuilder.hpp | 5 +- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/src/language/ASTNodeExpressionBuilder.cpp b/src/language/ASTNodeExpressionBuilder.cpp index f70b80105..516307662 100644 --- a/src/language/ASTNodeExpressionBuilder.cpp +++ b/src/language/ASTNodeExpressionBuilder.cpp @@ -45,6 +45,12 @@ ASTNodeExpressionBuilder::_buildExpression(ASTNode& n) } else if (n.is<language::false_kw>()) { n.m_node_processor = std::make_unique<FakeProcessor>(); + } else if (n.is<language::expression_list>()) { + n.m_node_processor = std::make_unique<FakeProcessor>(); + + } else if (n.is<language::name_list>()) { + n.m_node_processor = std::make_unique<FakeProcessor>(); + } else if (n.is<language::name>()) { n.m_node_processor = std::make_unique<NameProcessor>(n); diff --git a/src/language/ASTNodeFunctionExpressionBuilder.cpp b/src/language/ASTNodeFunctionExpressionBuilder.cpp index 780145e14..ba200386c 100644 --- a/src/language/ASTNodeFunctionExpressionBuilder.cpp +++ b/src/language/ASTNodeFunctionExpressionBuilder.cpp @@ -56,25 +56,18 @@ ASTNodeFunctionExpressionBuilder::_getArgumentProcessor(ASTNode& argument_node, } PUGS_INLINE -std::unique_ptr<INodeProcessor> -ASTNodeFunctionExpressionBuilder::_getArgumentProcessor(FunctionDescriptor& function_descriptor, ASTNode& argument_node) +void +ASTNodeFunctionExpressionBuilder::_storeArgumentProcessor(ASTNode& parameter_variable, + ASTNode& argument_node, + FunctionProcessor& function_processor) { - SymbolTable::Symbol& symbol{[&]() -> SymbolTable::Symbol& { - ASTNode& definition_node = function_descriptor.definitionNode(); - ASTNode& argument_variable = *definition_node.children[0]; - - if (argument_variable.is<language::name>()) { - auto [i_symbol, found] = - argument_variable.m_symbol_table->find(argument_variable.string(), argument_variable.begin()); - Assert(found); + Assert(parameter_variable.is<language::name>(), "unexpected parameter type!"); - return *i_symbol; - } else { - throw parse_error("argument list not implemented yet!", function_descriptor.definitionNode().begin()); - } - }()}; + auto [i_parameter_symbol, found] = + parameter_variable.m_symbol_table->find(parameter_variable.string(), parameter_variable.begin()); + Assert(found); - return std::make_unique<FunctionArgumentProcessor<double, double>>(argument_node, symbol); + function_processor.addArgumentProcessor(this->_getArgumentProcessor(argument_node, *i_parameter_symbol)); } PUGS_INLINE @@ -88,16 +81,22 @@ ASTNodeFunctionExpressionBuilder::_buildArgumentProcessors(FunctionDescriptor& f ASTNode& argument_nodes = *node.children[1]; - if (argument_nodes.is<language::expression_list>()) { - throw parse_error("argument list not implemented yet!", argument_nodes.begin()); - } else { - Assert(parameter_variables.is<language::name>(), "unexpected parameter type!"); - - auto [i_parameter_symbol, found] = - parameter_variables.m_symbol_table->find(parameter_variables.string(), parameter_variables.begin()); - Assert(found); + if (parameter_variables.children.size() != argument_nodes.children.size()) { + std::ostringstream error_message; + error_message << "bad number of arguments: expecting " << rang::fgB::yellow << parameter_variables.children.size() + << rang::style::reset << ", provided " << rang::fgB::yellow << argument_nodes.children.size() + << rang::style::reset; + throw parse_error(error_message.str(), argument_nodes.begin()); + } - function_processor.addArgumentProcessor(this->_getArgumentProcessor(argument_nodes, *i_parameter_symbol)); + if (parameter_variables.children.size() > 0) { + for (size_t i = 0; i < parameter_variables.children.size(); ++i) { + ASTNode& parameter_variable = *parameter_variables.children[i]; + ASTNode& argument_node = *argument_nodes.children[i]; + this->_storeArgumentProcessor(parameter_variable, argument_node, function_processor); + } + } else { + this->_storeArgumentProcessor(parameter_variables, argument_nodes, function_processor); } } diff --git a/src/language/ASTNodeFunctionExpressionBuilder.hpp b/src/language/ASTNodeFunctionExpressionBuilder.hpp index f3c9a4fec..7ece3d660 100644 --- a/src/language/ASTNodeFunctionExpressionBuilder.hpp +++ b/src/language/ASTNodeFunctionExpressionBuilder.hpp @@ -15,8 +15,9 @@ class ASTNodeFunctionExpressionBuilder SymbolType& parameter_symbol); PUGS_INLINE - std::unique_ptr<INodeProcessor> _getArgumentProcessor(FunctionDescriptor& function_descriptor, - ASTNode& argument_node); + void _storeArgumentProcessor(ASTNode& parameter_variable, + ASTNode& argument_node, + FunctionProcessor& function_processor); PUGS_INLINE void _buildArgumentProcessors(FunctionDescriptor& function_descriptor, -- GitLab