Select Git revision
ASTSymbolInitializationChecker.cpp
ASTSymbolInitializationChecker.cpp 2.98 KiB
#include <ASTSymbolInitializationChecker.hpp>
#include <SymbolTable.hpp>
#include <PEGGrammar.hpp>
void
ASTSymbolInitializationChecker::_checkSymbolInitialization(ASTNode& node)
{
if (node.is<language::declaration>()) {
const std::string& symbol = node.children[1]->string();
auto [i_symbol, found] = node.m_symbol_table->find(symbol, node.children[1]->begin());
Assert(found, "unexpected error, should have been detected through declaration checking");
if (node.children.size() == 3) {
this->_checkSymbolInitialization(*node.children[2]);
i_symbol->attributes().setIsInitialized();
}
} else if (node.is<language::let_declaration>()) {
const std::string& symbol = node.children[0]->string();
auto [i_symbol, found] = node.m_symbol_table->find(symbol, node.children[0]->begin());
Assert(found, "unexpected error, should have been detected through declaration checking");
i_symbol->attributes().setIsInitialized();
auto& function_table = node.m_symbol_table->functionTable();
uint64_t function_id = std::get<uint64_t>(i_symbol->attributes().value());
auto& function_descriptor = function_table[function_id];
this->_checkSymbolInitialization(function_descriptor.definitionNode());
} else if (node.is<language::function_definition>()) {
const std::string& symbol = node.children[0]->string();
auto [i_symbol, found] = node.m_symbol_table->find(symbol, node.children[0]->begin());
Assert(found, "unexpected error, should have been detected through declaration checking");
i_symbol->attributes().setIsInitialized();
this->_checkSymbolInitialization(*node.children[1]);
} else if (node.is<language::eq_op>()) {
// first checks for right hand side
this->_checkSymbolInitialization(*node.children[1]);
// then marks left hand side as initialized
const std::string& symbol = node.children[0]->string();
auto [i_symbol, found] = node.m_symbol_table->find(symbol, node.children[0]->begin());
Assert(found, "unexpected error, should have been detected through declaration checking");
i_symbol->attributes().setIsInitialized();
} else if (node.is<language::name>()) {
auto [i_symbol, found] = node.m_symbol_table->find(node.string(), node.begin());
Assert(found, "unexpected error, should have been detected through declaration checking");
if (not i_symbol->attributes().isInitialized()) {
std::ostringstream error_message;
error_message << "uninitialized symbol '" << rang::fg::red << node.string() << rang::fg::reset << '\'';
throw parse_error(error_message.str(), std::vector{node.begin()});
}
}
if (not(node.is<language::declaration>() or node.is<language::let_declaration>() or node.is<language::eq_op>())) {
for (auto& child : node.children) {
this->_checkSymbolInitialization(*child);
}
}
}
ASTSymbolInitializationChecker::ASTSymbolInitializationChecker(ASTNode& root_node)
{
Assert(root_node.is_root());
this->_checkSymbolInitialization(root_node);
}