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

Fix function domains and arguments definition

Symbol table is now populated correctly.
It remains the case of
``
let g : R*N -> R, x -> x;
``
where `x` is a complex type. It produces a clean error message and this
development is postponed to a far(?) future since it will require compound types
management (or at least heterogeneous arrays)
parent e3602c80
No related branches found
No related tags found
1 merge request!37Feature/language
...@@ -56,6 +56,13 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) ...@@ -56,6 +56,13 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n)
n.children[1]->children[0]->m_data_type = ASTNodeDataType::typename_t; n.children[1]->children[0]->m_data_type = ASTNodeDataType::typename_t;
n.children[1]->children[1]->m_data_type = ASTNodeDataType::typename_t; n.children[1]->children[1]->m_data_type = ASTNodeDataType::typename_t;
// build types for compound types
for (auto& child : n.children[1]->children[0]->children) {
this->_buildNodeDataTypes(*child);
}
for (auto& child : n.children[1]->children[1]->children) {
this->_buildNodeDataTypes(*child);
}
{ // Function data type { // Function data type
const std::string& symbol = n.children[0]->string(); const std::string& symbol = n.children[0]->string();
...@@ -66,7 +73,18 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) ...@@ -66,7 +73,18 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n)
Assert(found); Assert(found);
i_symbol->second.setDataType(n.children[0]->m_data_type); i_symbol->second.setDataType(n.children[0]->m_data_type);
} }
auto& type_node = *(n.children[1]->children[0]);
if (n.children[1]->children[0]->children.size() != n.children[2]->children[0]->children.size()) {
std::ostringstream message;
message << "Compound data type deduction is not yet implemented\n"
<< "note: number of product spaces (" << n.children[1]->children[0]->children.size() << ") "
<< rang::fgB::yellow << n.children[1]->children[0]->string() << rang::style::reset
<< " differs from number of variables (" << n.children[2]->children[0]->children.size() << ") "
<< rang::fgB::yellow << n.children[2]->children[0]->string() << rang::style::reset << std::ends;
throw parse_error(message.str(), n.children[0]->begin());
}
auto simple_type_allocator = [&](const ASTNode& type_node, ASTNode& symbol_node) {
ASTNodeDataType data_type{ASTNodeDataType::undefined_t}; ASTNodeDataType data_type{ASTNodeDataType::undefined_t};
if (type_node.is<language::B_set>()) { if (type_node.is<language::B_set>()) {
data_type = ASTNodeDataType::bool_t; data_type = ASTNodeDataType::bool_t;
...@@ -82,14 +100,24 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) ...@@ -82,14 +100,24 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n)
Assert(data_type != ASTNodeDataType::undefined_t); // LCOV_EXCL_LINE Assert(data_type != ASTNodeDataType::undefined_t); // LCOV_EXCL_LINE
n.children[2]->children[0]->m_data_type = data_type; symbol_node.m_data_type = data_type;
const std::string& symbol = n.children[2]->children[0]->string(); const std::string& symbol = symbol_node.string();
std::shared_ptr<SymbolTable>& symbol_table = n.m_symbol_table; std::shared_ptr<SymbolTable>& symbol_table = n.m_symbol_table;
auto [i_symbol, found] = symbol_table->find(symbol, n.children[2]->children[0]->begin()); auto [i_symbol, found] = symbol_table->find(symbol, symbol_node.begin());
Assert(found); Assert(found);
i_symbol->second.setDataType(data_type); i_symbol->second.setDataType(data_type);
};
if (n.children[1]->children[0]->children.size() == 0) {
simple_type_allocator(*n.children[1]->children[0], *n.children[2]->children[0]);
} else {
for (size_t i = 0; i < n.children[1]->children[0]->children.size(); ++i) {
simple_type_allocator(*n.children[1]->children[0]->children[i], *n.children[2]->children[0]->children[i]);
}
}
n.m_data_type = ASTNodeDataType::void_t; n.m_data_type = ASTNodeDataType::void_t;
} else if (n.is<language::name>()) { } else if (n.is<language::name>()) {
std::shared_ptr<SymbolTable>& symbol_table = n.m_symbol_table; std::shared_ptr<SymbolTable>& symbol_table = n.m_symbol_table;
...@@ -173,6 +201,11 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) ...@@ -173,6 +201,11 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n)
} else if (n.is<language::function_evaluation>()) { } else if (n.is<language::function_evaluation>()) {
std::cout << rang::fgB::red << "returned type of function evaluation is incorrect" << rang::style::reset << "\n"; std::cout << rang::fgB::red << "returned type of function evaluation is incorrect" << rang::style::reset << "\n";
n.m_data_type = ASTNodeDataType::double_t; n.m_data_type = ASTNodeDataType::double_t;
} else if (n.is<language::B_set>() or n.is<language::Z_set>() or n.is<language::N_set>() or
n.is<language::R_set>() or n.is<language::string_type>()) {
n.m_data_type = ASTNodeDataType::typename_t;
} else if (n.is<language::name_list>() or n.is<language::expression_list>()) {
n.m_data_type = ASTNodeDataType::void_t;
} }
} }
} }
......
...@@ -22,7 +22,7 @@ ASTSymbolTableBuilder::buildSymbolTable(ASTNode& n, std::shared_ptr<SymbolTable> ...@@ -22,7 +22,7 @@ ASTSymbolTableBuilder::buildSymbolTable(ASTNode& n, std::shared_ptr<SymbolTable>
auto [i_symbol, success] = symbol_table->add(symbol, n.children[0]->begin()); auto [i_symbol, success] = symbol_table->add(symbol, n.children[0]->begin());
if (not success) { if (not success) {
std::ostringstream error_message; std::ostringstream error_message;
error_message << "symbol '" << rang::fg::red << symbol << rang::fg::reset << '\'' << " was already defined!"; error_message << "symbol '" << rang::fg::red << symbol << rang::fg::reset << "' was already defined!";
throw parse_error(error_message.str(), std::vector{n.begin()}); throw parse_error(error_message.str(), std::vector{n.begin()});
} }
...@@ -37,17 +37,29 @@ ASTSymbolTableBuilder::buildSymbolTable(ASTNode& n, std::shared_ptr<SymbolTable> ...@@ -37,17 +37,29 @@ ASTSymbolTableBuilder::buildSymbolTable(ASTNode& n, std::shared_ptr<SymbolTable>
auto [i_symbol, success] = symbol_table->add(symbol, n.children[1]->begin()); auto [i_symbol, success] = symbol_table->add(symbol, n.children[1]->begin());
if (not success) { if (not success) {
std::ostringstream error_message; std::ostringstream error_message;
error_message << "symbol '" << rang::fg::red << symbol << rang::fg::reset << '\'' << " was already defined!"; error_message << "symbol '" << rang::fg::red << symbol << rang::fg::reset << "' was already defined!";
throw parse_error(error_message.str(), std::vector{n.begin()}); throw parse_error(error_message.str(), std::vector{n.begin()});
} }
} else if (n.is<language::function_definition>()) { } else if (n.is<language::function_definition>()) {
const std::string& symbol = n.children[0]->string(); auto register_symbol = [&](const std::string& symbol) {
auto [i_symbol, success] = symbol_table->add(symbol, n.children[0]->begin()); auto [i_symbol, success] = symbol_table->add(symbol, n.children[0]->begin());
if (not success) { if (not success) {
std::ostringstream error_message; std::ostringstream error_message;
error_message << "symbol '" << rang::fg::red << symbol << rang::fg::reset << '\'' << " was already defined!"; error_message << "symbol '" << rang::fg::red << symbol << rang::fg::reset << "' was already defined!";
throw parse_error(error_message.str(), std::vector{n.begin()}); throw parse_error(error_message.str(), std::vector{n.begin()});
} }
// Symbols will be initialized at call
i_symbol->second.setIsInitialized();
};
if (n.children[0]->is<language::name>()) {
register_symbol(n.children[0]->string());
} else { // treats the case of list of parameters
Assert(n.children[0]->is<language::name_list>());
for (auto& child : n.children[0]->children) {
register_symbol(child->string());
}
}
} else if (n.is<language::name>()) { } else if (n.is<language::name>()) {
auto [i_symbol, found] = symbol_table->find(n.string(), n.begin()); auto [i_symbol, found] = symbol_table->find(n.string(), n.begin());
if (not found) { if (not found) {
......
...@@ -57,6 +57,7 @@ parser(const std::string& filename) ...@@ -57,6 +57,7 @@ parser(const std::string& filename)
ASTSymbolInitializationChecker{*root_node}; ASTSymbolInitializationChecker{*root_node};
ASTNodeDataTypeBuilder{*root_node}; ASTNodeDataTypeBuilder{*root_node};
{ {
std::string dot_filename{"parse_tree.dot"}; std::string dot_filename{"parse_tree.dot"};
std::ofstream fout(dot_filename); std::ofstream fout(dot_filename);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment