Skip to content
Snippets Groups Projects
Commit e55b1f0f authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Allow types conversion in function calls

In order to have a full scalar function support, it remains
- to allow multiple parameters calls, and
- to compute the correct (scalar) returned type
parent fe0adc0d
No related branches found
No related tags found
1 merge request!37Feature/language
...@@ -6,6 +6,101 @@ ...@@ -6,6 +6,101 @@
#include <node_processor/FunctionProcessor.hpp> #include <node_processor/FunctionProcessor.hpp>
template <typename SymbolType>
PUGS_INLINE std::unique_ptr<INodeProcessor>
ASTNodeFunctionExpressionBuilder::_getArgumentProcessor(ASTNode& argument_node, SymbolType& parameter_symbol)
{
auto get_function_argument_processor_for_parameter_type =
[&](const auto& argument_v) -> std::unique_ptr<INodeProcessor> {
using ArgumentT = std::decay_t<decltype(argument_v)>;
switch (parameter_symbol.attributes().dataType()) {
case ASTNodeDataType::bool_t: {
return std::make_unique<FunctionArgumentProcessor<ArgumentT, bool>>(argument_node, parameter_symbol);
}
case ASTNodeDataType::unsigned_int_t: {
return std::make_unique<FunctionArgumentProcessor<ArgumentT, uint64_t>>(argument_node, parameter_symbol);
}
case ASTNodeDataType::int_t: {
return std::make_unique<FunctionArgumentProcessor<ArgumentT, int64_t>>(argument_node, parameter_symbol);
}
case ASTNodeDataType::double_t: {
return std::make_unique<FunctionArgumentProcessor<ArgumentT, double>>(argument_node, parameter_symbol);
}
default: {
throw parse_error("unexpected error: undefined parameter type for function", std::vector{argument_node.begin()});
}
}
};
auto get_function_argument_processor_for_argument_type = [&]() {
switch (argument_node.m_data_type) {
case ASTNodeDataType::bool_t: {
return get_function_argument_processor_for_parameter_type(bool{});
}
case ASTNodeDataType::unsigned_int_t: {
return get_function_argument_processor_for_parameter_type(uint64_t{});
}
case ASTNodeDataType::int_t: {
return get_function_argument_processor_for_parameter_type(int64_t{});
}
case ASTNodeDataType::double_t: {
return get_function_argument_processor_for_parameter_type(double{});
}
default: {
throw parse_error("unexpected error: undefined argument type for function", std::vector{argument_node.begin()});
}
}
};
return get_function_argument_processor_for_argument_type();
}
PUGS_INLINE
std::unique_ptr<INodeProcessor>
ASTNodeFunctionExpressionBuilder::_getArgumentProcessor(FunctionDescriptor& function_descriptor, ASTNode& argument_node)
{
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);
return *i_symbol;
} else {
throw parse_error("argument list not implemented yet!", function_descriptor.definitionNode().begin());
}
}()};
return std::make_unique<FunctionArgumentProcessor<double, double>>(argument_node, symbol);
}
PUGS_INLINE
void
ASTNodeFunctionExpressionBuilder::_buildArgumentProcessors(FunctionDescriptor& function_descriptor,
ASTNode& node,
FunctionProcessor& function_processor)
{
ASTNode& definition_node = function_descriptor.definitionNode();
ASTNode& parameter_variables = *definition_node.children[0];
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);
function_processor.addArgumentProcessor(this->_getArgumentProcessor(argument_nodes, *i_parameter_symbol));
}
}
PUGS_INLINE PUGS_INLINE
std::unique_ptr<INodeProcessor> std::unique_ptr<INodeProcessor>
ASTNodeFunctionExpressionBuilder::_getFunctionProcessor(const ASTNodeDataType expression_value_type, ASTNodeFunctionExpressionBuilder::_getFunctionProcessor(const ASTNodeDataType expression_value_type,
...@@ -59,9 +154,9 @@ ASTNodeFunctionExpressionBuilder::_getFunctionProcessor(const ASTNodeDataType ex ...@@ -59,9 +154,9 @@ ASTNodeFunctionExpressionBuilder::_getFunctionProcessor(const ASTNodeDataType ex
ASTNodeFunctionExpressionBuilder::ASTNodeFunctionExpressionBuilder(ASTNode& node) ASTNodeFunctionExpressionBuilder::ASTNodeFunctionExpressionBuilder(ASTNode& node)
{ {
auto [i_symbol, found] = node.m_symbol_table->find(node.children[0]->string(), node.begin()); auto [i_function_symbol, found] = node.m_symbol_table->find(node.children[0]->string(), node.begin());
Assert(found); Assert(found);
uint64_t function_id = std::get<uint64_t>(i_symbol->attributes().value()); uint64_t function_id = std::get<uint64_t>(i_function_symbol->attributes().value());
FunctionDescriptor& function_descriptor = node.m_symbol_table->functionTable()[function_id]; FunctionDescriptor& function_descriptor = node.m_symbol_table->functionTable()[function_id];
...@@ -71,12 +166,14 @@ ASTNodeFunctionExpressionBuilder::ASTNodeFunctionExpressionBuilder(ASTNode& node ...@@ -71,12 +166,14 @@ ASTNodeFunctionExpressionBuilder::ASTNodeFunctionExpressionBuilder(ASTNode& node
} }
#warning compute the right value type #warning compute the right value type
const ASTNodeDataType return_value_type = ASTNodeDataType::double_t; const ASTNodeDataType return_value_type = ASTNodeDataType::double_t;
const ASTNodeDataType expression_value_type = function_descriptor.definitionNode().children[1]->m_data_type;
std::unique_ptr function_processor = std::make_unique<FunctionProcessor>(); std::unique_ptr function_processor = std::make_unique<FunctionProcessor>();
this->_buildArgumentProcessors(function_descriptor, node, *function_processor);
function_processor->addFunctionExpressionProcessor( function_processor->addFunctionExpressionProcessor(
this->_getFunctionProcessor(function_descriptor.definitionNode().children[1]->m_data_type, return_value_type, this->_getFunctionProcessor(expression_value_type, return_value_type, node));
node));
node.m_node_processor = std::move(function_processor); node.m_node_processor = std::move(function_processor);
} }
...@@ -4,9 +4,25 @@ ...@@ -4,9 +4,25 @@
#include <ASTNode.hpp> #include <ASTNode.hpp>
#include <node_processor/INodeProcessor.hpp> #include <node_processor/INodeProcessor.hpp>
class FunctionProcessor;
class FunctionDescriptor;
class ASTNodeFunctionExpressionBuilder class ASTNodeFunctionExpressionBuilder
{ {
private: private:
template <typename SymbolType>
PUGS_INLINE std::unique_ptr<INodeProcessor> _getArgumentProcessor(ASTNode& argument_node,
SymbolType& parameter_symbol);
PUGS_INLINE
std::unique_ptr<INodeProcessor> _getArgumentProcessor(FunctionDescriptor& function_descriptor,
ASTNode& argument_node);
PUGS_INLINE
void _buildArgumentProcessors(FunctionDescriptor& function_descriptor,
ASTNode& node,
FunctionProcessor& function_processor);
PUGS_INLINE PUGS_INLINE
std::unique_ptr<INodeProcessor> _getFunctionProcessor(const ASTNodeDataType expression_value_type, std::unique_ptr<INodeProcessor> _getFunctionProcessor(const ASTNodeDataType expression_value_type,
const ASTNodeDataType return_value_type, const ASTNodeDataType return_value_type,
......
...@@ -10,65 +10,59 @@ ...@@ -10,65 +10,59 @@
#include <node_processor/INodeProcessor.hpp> #include <node_processor/INodeProcessor.hpp>
template <typename ReturnType, typename ExpressionValueType> template <typename ProvidedValueType, typename ExpectedValueType>
class FunctionExpressionProcessor final : public INodeProcessor class FunctionArgumentProcessor final : public INodeProcessor
{ {
private: private:
ASTNode& m_node; ASTNode& m_provided_value_node;
ASTNodeDataVariant& m_symbol_value;
FunctionDescriptor& m_function_descriptor;
public:
void void
_executeArguments(ExecUntilBreakOrContinue& exec_policy) execute(ExecUntilBreakOrContinue& exec_policy)
{ {
// Compute arguments values m_provided_value_node.execute(exec_policy);
ASTNode& arguments_values = *m_node.children[1];
arguments_values.execute(exec_policy);
// Copy arguments to function arguments if constexpr (std::is_same_v<ExpectedValueType, ProvidedValueType>) {
ASTNode& definition_node = m_function_descriptor.definitionNode(); m_symbol_value = m_provided_value_node.m_value;
ASTNode& arguments = *definition_node.children[0];
if (arguments.is<language::name>()) {
Assert(arguments_values.children.size() == 0);
auto [i_symbol, found] = arguments.m_symbol_table->find(arguments.string(), arguments.begin());
Assert(found);
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 { } else {
throw parse_error("argument list not implemented yet!", arguments_values.begin()); m_symbol_value = static_cast<ExpectedValueType>(std::get<ProvidedValueType>(m_provided_value_node.m_value));
} }
} }
FunctionArgumentProcessor(ASTNode& provided_value_node, SymbolTable::Symbol& argument_symbol)
: m_provided_value_node{provided_value_node}, m_symbol_value{argument_symbol.attributes().value()}
{}
};
template <typename ReturnType, typename ExpressionValueType>
class FunctionExpressionProcessor final : public INodeProcessor
{
private:
ASTNode& m_node;
ASTNode& m_function_expression;
public: public:
void void
execute(ExecUntilBreakOrContinue& exec_policy) execute(ExecUntilBreakOrContinue& exec_policy)
{ {
this->_executeArguments(exec_policy); m_function_expression.execute(exec_policy);
ASTNode& definition_node = m_function_descriptor.definitionNode();
ASTNode& function_expression = *definition_node.children[1];
function_expression.execute(exec_policy);
if constexpr (std::is_same_v<ReturnType, ExpressionValueType>) { if constexpr (std::is_same_v<ReturnType, ExpressionValueType>) {
m_node.m_value = function_expression.m_value; m_node.m_value = m_function_expression.m_value;
} else { } else {
m_node.m_value = static_cast<ReturnType>(std::get<ExpressionValueType>(function_expression.m_value)); m_node.m_value = static_cast<ReturnType>(std::get<ExpressionValueType>(m_function_expression.m_value));
} }
} }
FunctionExpressionProcessor(ASTNode& node) FunctionExpressionProcessor(ASTNode& node)
: m_node{node}, m_function_descriptor{[&]() -> FunctionDescriptor& { : 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()); auto [i_symbol, found] = m_node.m_symbol_table->find(m_node.children[0]->string(), m_node.begin());
Assert(found); Assert(found);
uint64_t function_id = std::get<uint64_t>(i_symbol->attributes().value()); uint64_t function_id = std::get<uint64_t>(i_symbol->attributes().value());
return m_node.m_symbol_table->functionTable()[function_id]; FunctionDescriptor& function_descriptor = m_node.m_symbol_table->functionTable()[function_id];
return *function_descriptor.definitionNode().children[1];
}()} }()}
{} {}
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment