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)
n.children[1]->children[0]->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
const std::string& symbol = n.children[0]->string();
......@@ -66,7 +73,18 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n)
Assert(found);
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};
if (type_node.is<language::B_set>()) {
data_type = ASTNodeDataType::bool_t;
......@@ -82,14 +100,24 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n)
Assert(data_type != ASTNodeDataType::undefined_t); // LCOV_EXCL_LINE
n.children[2]->children[0]->m_data_type = data_type;
const std::string& symbol = n.children[2]->children[0]->string();
symbol_node.m_data_type = data_type;
const std::string& symbol = symbol_node.string();
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);
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;
} else if (n.is<language::name>()) {
std::shared_ptr<SymbolTable>& symbol_table = n.m_symbol_table;
......@@ -173,6 +201,11 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n)
} else if (n.is<language::function_evaluation>()) {
std::cout << rang::fgB::red << "returned type of function evaluation is incorrect" << rang::style::reset << "\n";
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>
auto [i_symbol, success] = symbol_table->add(symbol, n.children[0]->begin());
if (not success) {
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()});
}
......@@ -37,17 +37,29 @@ ASTSymbolTableBuilder::buildSymbolTable(ASTNode& n, std::shared_ptr<SymbolTable>
auto [i_symbol, success] = symbol_table->add(symbol, n.children[1]->begin());
if (not success) {
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()});
}
} 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());
if (not success) {
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()});
}
// 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>()) {
auto [i_symbol, found] = symbol_table->find(n.string(), n.begin());
if (not found) {
......
......@@ -57,6 +57,7 @@ parser(const std::string& filename)
ASTSymbolInitializationChecker{*root_node};
ASTNodeDataTypeBuilder{*root_node};
{
std::string dot_filename{"parse_tree.dot"};
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