Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store all nodes for a specific symbol #934

Merged
merged 11 commits into from
Sep 26, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/language/templates/pybind/pysymtab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ void init_symtab_module(py::module& m) {
.def("get_id", &Symbol::get_id)
.def("get_status", &Symbol::get_status)
.def("get_properties", &Symbol::get_properties)
.def("get_node", &Symbol::get_node)
.def("get_node", [](const std::shared_ptr<Symbol>& s){ return s->get_nodes().front(); })
.def("get_original_name", &Symbol::get_original_name)
.def("get_name", &Symbol::get_name)
.def("has_any_property", &Symbol::has_any_property)
Expand Down
15 changes: 15 additions & 0 deletions src/symtab/symbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "symtab/symbol.hpp"
#include "utils/logger.hpp"
#include <ast/ast.hpp>

namespace nmodl {
namespace symtab {
Expand Down Expand Up @@ -49,5 +50,19 @@ std::string Symbol::to_string() const {
return s;
}

std::vector<ast::Ast*> Symbol::get_nodes_by_token(
std::initializer_list<ast::AstNodeType> l) const noexcept {
std::vector<ast::Ast*> _nodes;
for (const auto& n: nodes) {
for (const auto& m: l) {
if (n->get_node_type() == m) {
_nodes.push_back(n);
break;
}
}
}
return nodes;
}

} // namespace symtab
} // namespace nmodl
24 changes: 17 additions & 7 deletions src/symtab/symbol.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "lexer/modtoken.hpp"
#include "symtab/symbol_properties.hpp"
#include <ast/ast_decl.hpp>
alkino marked this conversation as resolved.
Show resolved Hide resolved


namespace nmodl {
Expand Down Expand Up @@ -65,7 +66,7 @@ class Symbol {
/// Variable can appear multiple times in the mod file. This node
/// represent the first occurance of the variable in the input. Currently
/// we don't track all AST nodes.
alkino marked this conversation as resolved.
Show resolved Hide resolved
ast::Ast* node = nullptr;
std::vector<ast::Ast*> nodes = {};

/// token associated with symbol (from node)
ModToken token;
Expand Down Expand Up @@ -113,17 +114,19 @@ class Symbol {
Symbol() = delete;

Symbol(std::string name, ast::Ast* node)
: name(std::move(name))
, node(node) {}
: name(std::move(name)) {
nodes.push_back(node);
}

Symbol(std::string name, ModToken token)
: name(std::move(name))
, token(std::move(token)) {}

Symbol(std::string name, ast::Ast* node, ModToken token)
: name(std::move(name))
, node(node)
, token(std::move(token)) {}
, token(std::move(token)) {
nodes.push_back(node);
}

/// \}

Expand Down Expand Up @@ -236,10 +239,17 @@ class Symbol {
return status;
}

ast::Ast* get_node() const noexcept {
return node;
void add_node(ast::Ast* node) noexcept {
nodes.push_back(node);
}

std::vector<ast::Ast*> get_nodes() const noexcept {
return nodes;
}

std::vector<ast::Ast*> get_nodes_by_token(
alkino marked this conversation as resolved.
Show resolved Hide resolved
std::initializer_list<ast::AstNodeType> l) const noexcept;

ModToken get_token() const noexcept {
return token;
}
Expand Down
29 changes: 16 additions & 13 deletions src/symtab/symbol_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <utility>

#include "ast/ast.hpp"
#include "ast/ast_decl.hpp"
#include "symtab/symbol_table.hpp"
#include "utils/logger.hpp"
#include "utils/table_data.hpp"
Expand Down Expand Up @@ -54,15 +55,12 @@ SymbolTable::SymbolTable(const SymbolTable& table)

bool SymbolTable::is_method_defined(const std::string& name) const {
auto symbol = lookup_in_scope(name);
if (symbol != nullptr) {
auto node = symbol->get_node();
if (node != nullptr) {
if (node->is_procedure_block() || node->is_function_block()) {
return true;
}
}
if (symbol == nullptr) {
return false;
}
return false;
auto nodes = symbol->get_nodes_by_token(
{AstNodeType::FUNCTION_BLOCK, AstNodeType::PROCEDURE_BLOCK});
return !nodes.empty();
}


Expand Down Expand Up @@ -202,12 +200,14 @@ std::shared_ptr<Symbol> ModelSymbolTable::lookup(const std::string& name) {
void ModelSymbolTable::emit_message(const std::shared_ptr<Symbol>& first,
const std::shared_ptr<Symbol>& second,
bool redefinition) {
auto node = first->get_node();
auto nodes = first->get_nodes();
std::string name = first->get_name();
auto properties = to_string(second->get_properties());
std::string type = "UNKNOWN";
if (node != nullptr) {
type = node->get_node_type_name();
// Here we take the first one, because this is a redefinition
alkino marked this conversation as resolved.
Show resolved Hide resolved
if (!nodes.empty()) {
// Here we take the first one, because this is a redefinition
type = nodes.front()->get_node_type_name();
}

if (redefinition) {
Expand Down Expand Up @@ -318,6 +318,7 @@ std::shared_ptr<Symbol> ModelSymbolTable::insert(const std::shared_ptr<Symbol>&
emit_message(symbol, search_symbol, true);
} else {
search_symbol->add_properties(symbol->get_properties());
search_symbol->add_node(symbol->get_nodes().front());
}
return search_symbol;
}
Expand Down Expand Up @@ -457,8 +458,9 @@ void SymbolTable::Table::print(std::ostream& stream, std::string title, int inde
TableData table;
table.title = std::move(title);
table.headers = {
"NAME", "PROPERTIES", "STATUS", "LOCATION", "VALUE", "# READS", "# WRITES"};
"NAME", "# NODES", "PROPERTIES", "STATUS", "LOCATION", "VALUE", "# READS", "# WRITES"};
table.alignments = {text_alignment::left,
text_alignment::left,
text_alignment::left,
text_alignment::right,
text_alignment::right,
Expand All @@ -482,13 +484,14 @@ void SymbolTable::Table::print(std::ostream& stream, std::string title, int inde
auto properties = syminfo::to_string(symbol->get_properties());
auto status = syminfo::to_string(symbol->get_status());
auto reads = std::to_string(symbol->get_read_count());
auto nodes = std::to_string(symbol->get_nodes().size());
std::string value;
auto sym_value = symbol->get_value();
if (sym_value) {
value = std::to_string(*sym_value);
}
auto writes = std::to_string(symbol->get_write_count());
table.rows.push_back({name, properties, status, position, value, reads, writes});
table.rows.push_back({name, nodes, properties, status, position, value, reads, writes});
}
table.print(stream, indent);
}
Expand Down
21 changes: 9 additions & 12 deletions src/visitors/inline_visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "visitors/inline_visitor.hpp"

#include "ast/all.hpp"
#include "ast/ast_decl.hpp"
#include "parser/c11_driver.hpp"
#include "utils/logger.hpp"
#include "visitors/local_var_rename_visitor.hpp"
Expand Down Expand Up @@ -210,25 +211,21 @@ void InlineVisitor::visit_function_call(FunctionCall& node) {
return;
}

auto function_definition = symbol->get_node();
if (function_definition == nullptr) {
auto nodes = symbol->get_nodes_by_token(
{AstNodeType::FUNCTION_BLOCK, AstNodeType::PROCEDURE_BLOCK});
if (nodes.empty()) {
throw std::runtime_error("symbol table doesn't have ast node for " + function_name);
}
auto f_block = nodes.front();

/// first inline called function
function_definition->visit_children(*this);
f_block->visit_children(*this);

bool inlined = false;

if (function_definition->is_procedure_block()) {
auto proc = dynamic_cast<ProcedureBlock*>(function_definition);
assert(proc);
inlined = inline_function_call(*proc, node, *caller_block);
} else if (function_definition->is_function_block()) {
auto func = dynamic_cast<FunctionBlock*>(function_definition);
assert(func);
inlined = inline_function_call(*func, node, *caller_block);
}
auto block = dynamic_cast<ast::Block*>(f_block);
assert(block);
inlined = inline_function_call(*block, node, *caller_block);

if (inlined) {
symbol->mark_inlined();
Expand Down
3 changes: 2 additions & 1 deletion src/visitors/solve_block_visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ ast::SolutionExpression* SolveBlockVisitor::create_solution_expression(
throw std::runtime_error(
fmt::format("SolveBlockVisitor :: cannot find the block '{}' to solve it", block_name));
}
auto node_to_solve = solve_node_symbol->get_node();
auto nodes_to_solve = solve_node_symbol->get_nodes();
auto node_to_solve = nodes_to_solve.front();
alkino marked this conversation as resolved.
Show resolved Hide resolved

/// in case of derivimplicit method if neuron solver is used (i.e. not sympy) then
/// the solution is not in place but we have to create a callback to newton solver
Expand Down
6 changes: 3 additions & 3 deletions src/visitors/symtab_visitor_helper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ void SymtabVisitor::setup_symbol(ast::Node* node, NmodlType property) {
auto name = use_ion->get_name()->get_node_name();
for (const auto& variable: codegen::Ion::get_possible_variables(name)) {
std::string ion_variable(codegen::naming::ION_VARNAME_PREFIX + variable);
auto symbol = std::make_shared<symtab::Symbol>(ion_variable, nullptr, ModToken());
auto symbol = std::make_shared<symtab::Symbol>(ion_variable, ModToken());
symbol->add_property(NmodlType::codegen_var);
modsymtab->insert(symbol);
}
Expand Down Expand Up @@ -169,13 +169,13 @@ static void add_external_symbols(symtab::ModelSymbolTable* symtab) {
ModToken tok(true);
auto variables = nmodl::get_external_variables();
for (auto variable: variables) {
auto symbol = std::make_shared<Symbol>(variable, nullptr, tok);
auto symbol = std::make_shared<Symbol>(variable, tok);
symbol->add_property(NmodlType::extern_neuron_variable);
symtab->insert(symbol);
}
auto methods = nmodl::get_external_functions();
for (auto method: methods) {
auto symbol = std::make_shared<Symbol>(method, nullptr, tok);
auto symbol = std::make_shared<Symbol>(method, tok);
symbol->add_property(NmodlType::extern_method);
symtab->insert(symbol);
}
Expand Down