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

Begin writing of function expression builder

Scalar functions now work slightly.
It remains to
- cast arguments whenever necessary
- compute the right returned value type

In short:
``
let inc : Z -> Z, i -> i+1;
cout << inc(2) << "\n";   // produces 3
cout << inc(2.3) << "\n"; // fails: conversion NIY
``
parent b8b97dbe
No related branches found
No related tags found
1 merge request!37Feature/language
......@@ -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>();
......
#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);
}
#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
......@@ -18,6 +18,7 @@ add_library(
ASTNodeDeclarationCleaner.cpp
ASTNodeEmptyBlockCleaner.cpp
ASTNodeExpressionBuilder.cpp
ASTNodeFunctionExpressionBuilder.cpp
ASTNodeIncDecExpressionBuilder.cpp
ASTNodeJumpPlacementChecker.cpp
ASTNodeUnaryOperatorExpressionBuilder.cpp
......
......@@ -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);
if (i_symbol->attributes().dataType() == arguments_values.m_data_type) {
i_symbol->attributes().value() = arguments_values.m_value;
} else {
throw parse_error("argument list not implemented yet!", definition_node.children[0]->begin());
throw parse_error("argument type conversion not implemented yet!", arguments_values.begin());
}
} else {
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);
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)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment