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

Continue function processing handling

Expression processor are now defined.
Evaluation works for some simple functions.

Functions such as `f : X -> X, x -> expression` is close to being functional
parent 59adbfed
No related branches found
No related tags found
1 merge request!37Feature/language
......@@ -231,5 +231,14 @@ ASTNodeDataTypeBuilder::ASTNodeDataTypeBuilder(ASTNode& node)
node.m_data_type = ASTNodeDataType::void_t;
this->_buildNodeDataTypes(node);
FunctionTable& function_table = node.m_symbol_table->functionTable();
for (size_t function_id = 0; function_id < function_table.size(); ++function_id) {
FunctionDescriptor& function_descriptor = function_table[function_id];
ASTNode& function_expression = function_descriptor.definitionNode();
this->_buildNodeDataTypes(function_expression);
}
std::cout << " - build node data types\n";
}
......@@ -11,6 +11,7 @@
#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>
......@@ -27,16 +28,11 @@ ASTNodeExpressionBuilder::_buildExpression(ASTNode& n)
n.is<language::pluseq_op>() or n.is<language::minuseq_op>())) {
ASTNodeAffectationExpressionBuilder{n};
} else if (n.is<language::let_declaration>()) {
std::cerr << rang::fgB::red << "\"let expression\" is not defined correctly (declaration should be removed)"
<< rang::style::reset << '\n';
} else if (n.is<language::function_definition>()) {
n.m_node_processor = std::make_unique<FakeProcessor>();
return;
} else if (n.is<language::function_evaluation>()) {
std::cerr << rang::fgB::red << "\"function evaluation\" is not defined yet" << rang::style::reset << '\n';
n.m_node_processor = std::make_unique<FakeProcessor>();
return;
n.m_node_processor = std::make_unique<FunctionProcessor>(n);
} else if (n.is<language::real>()) {
n.m_node_processor = std::make_unique<FakeProcessor>();
......@@ -105,12 +101,19 @@ ASTNodeExpressionBuilder::_buildExpression(ASTNode& n)
}
}
ASTNodeExpressionBuilder::ASTNodeExpressionBuilder(ASTNode& n)
ASTNodeExpressionBuilder::ASTNodeExpressionBuilder(ASTNode& node)
{
Assert(n.is_root());
n.m_node_processor = std::make_unique<ASTNodeListProcessor>(n);
for (auto& child : n.children) {
Assert(node.is_root());
node.m_node_processor = std::make_unique<ASTNodeListProcessor>(node);
for (auto& child : node.children) {
this->_buildExpression(*child);
}
std::cout << " - build node types\n";
// Build expressions of functions
FunctionTable& function_table = node.m_symbol_table->functionTable();
for (size_t function_id = 0; function_id < function_table.size(); ++function_id) {
FunctionDescriptor& function_descriptor = function_table[function_id];
ASTNode& function_expression = function_descriptor.definitionNode();
this->_buildExpression(function_expression);
}
}
......@@ -49,6 +49,13 @@ class FunctionTable
std::vector<FunctionDescriptor> m_function_descriptor_list;
public:
PUGS_INLINE
size_t
size() const
{
return m_function_descriptor_list.size();
}
PUGS_INLINE
FunctionDescriptor& operator[](size_t function_id)
{
......
#ifndef FUNCTION_PROCESSOR_HPP
#define FUNCTION_PROCESSOR_HPP
#include <FunctionTable.hpp>
#include <SymbolTable.hpp>
#include <PEGGrammar.hpp>
#include <node_processor/INodeProcessor.hpp>
class FunctionProcessor final : public INodeProcessor
{
private:
ASTNode& m_node;
FunctionDescriptor& m_function_descriptor;
public:
void
execute(ExecUntilBreakOrContinue& exec_policy)
{
// Compute arguments values
ASTNode& arguments_values = *m_node.children[1];
arguments_values.execute(exec_policy);
// Copy arguments to function arguments
ASTNode& definition_node = m_function_descriptor.definitionNode();
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);
i_symbol->attributes().value() = arguments_values.m_value;
} else {
throw parse_error("argument list not implemented yet!", definition_node.children[0]->begin());
}
ASTNode& function_expression = *definition_node.children[1];
function_expression.execute(exec_policy);
m_node.m_value = function_expression.m_value;
}
FunctionProcessor(ASTNode& node)
: m_node{node}, m_function_descriptor{[&]() -> FunctionDescriptor& {
auto [i_symbol, found] = m_node.m_symbol_table->find(m_node.children[0]->string(), m_node.begin());
Assert(found);
uint64_t function_id = std::get<uint64_t>(i_symbol->attributes().value());
return m_node.m_symbol_table->functionTable()[function_id];
}()}
{}
};
#endif // FUNCTION_PROCESSOR_HPP
......@@ -854,6 +854,7 @@ continue;
string_input input{data, "test.pgs"};
auto ast = ASTBuilder::build(input);
ASTSymbolTableBuilder{*ast};
ASTNodeDataTypeBuilder{*ast};
// One is sure that language::ignored is not treated so its a good candidate
......
#include <catch2/catch.hpp>
#include <ASTBuilder.hpp>
#include <ASTSymbolTableBuilder.hpp>
#include <ASTNodeDataTypeBuilder.hpp>
#include <ASTNodeJumpPlacementChecker.hpp>
......@@ -19,7 +20,7 @@ for(;;) {
string_input input{data, "test.pgs"};
auto ast = ASTBuilder::build(input);
ASTSymbolTableBuilder{*ast};
ASTNodeDataTypeBuilder{*ast};
REQUIRE_NOTHROW(ASTNodeJumpPlacementChecker{*ast});
......@@ -35,7 +36,7 @@ while(true) {
string_input input{data, "test.pgs"};
auto ast = ASTBuilder::build(input);
ASTSymbolTableBuilder{*ast};
ASTNodeDataTypeBuilder{*ast};
REQUIRE_NOTHROW(ASTNodeJumpPlacementChecker{*ast});
......@@ -51,7 +52,7 @@ do {
string_input input{data, "test.pgs"};
auto ast = ASTBuilder::build(input);
ASTSymbolTableBuilder{*ast};
ASTNodeDataTypeBuilder{*ast};
REQUIRE_NOTHROW(ASTNodeJumpPlacementChecker{*ast});
......@@ -67,7 +68,7 @@ do {
string_input input{data, "test.pgs"};
auto ast = ASTBuilder::build(input);
ASTSymbolTableBuilder{*ast};
ASTNodeDataTypeBuilder{*ast};
ast->children[0]->m_data_type = ASTNodeDataType::undefined_t;
......@@ -88,7 +89,7 @@ for(;;) {
string_input input{data, "test.pgs"};
auto ast = ASTBuilder::build(input);
ASTSymbolTableBuilder{*ast};
ASTNodeDataTypeBuilder{*ast};
REQUIRE_NOTHROW(ASTNodeJumpPlacementChecker{*ast});
......@@ -104,7 +105,7 @@ while(true) {
string_input input{data, "test.pgs"};
auto ast = ASTBuilder::build(input);
ASTSymbolTableBuilder{*ast};
ASTNodeDataTypeBuilder{*ast};
REQUIRE_NOTHROW(ASTNodeJumpPlacementChecker{*ast});
......@@ -120,7 +121,7 @@ do {
string_input input{data, "test.pgs"};
auto ast = ASTBuilder::build(input);
ASTSymbolTableBuilder{*ast};
ASTNodeDataTypeBuilder{*ast};
REQUIRE_NOTHROW(ASTNodeJumpPlacementChecker{*ast});
......@@ -136,7 +137,7 @@ do {
string_input input{data, "test.pgs"};
auto ast = ASTBuilder::build(input);
ASTSymbolTableBuilder{*ast};
ASTNodeDataTypeBuilder{*ast};
ast->children[0]->m_data_type = ASTNodeDataType::undefined_t;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment