Skip to content

Import Global statements #1617

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

Merged
merged 2 commits into from
Apr 1, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions integration_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -441,4 +441,5 @@ RUN(NAME test_argv_01 LABELS llvm) # TODO: Test using CPython
RUN(NAME global_syms_01 LABELS cpython llvm c)
RUN(NAME global_syms_02 LABELS cpython llvm c)
RUN(NAME global_syms_03_b LABELS cpython llvm c)
RUN(NAME global_syms_03_c LABELS cpython llvm c)
RUN(NAME global_syms_04 LABELS cpython llvm c wasm wasm_x64)
8 changes: 7 additions & 1 deletion integration_tests/global_syms_03_a.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
from lpython import i32
from lpython import i32, f64

print("Imported from global_syms_03_a")

l_1: list[str] = ['Monday', 'Tuesday', 'Wednesday']
l_1.append('Thursday')

def populate_lists() -> list[i32]:
return [10, -20]
l_2: list[i32] = populate_lists()

l_3: list[f64]
l_3 = [1.0, 2.0, 3.0]
2 changes: 1 addition & 1 deletion integration_tests/global_syms_03_b.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from global_syms_03_a import l_1, l_2

assert len(l_1) == 3
assert len(l_1) == 4
assert l_1[1] == "Tuesday"
assert l_2[1] == -20
5 changes: 5 additions & 0 deletions integration_tests/global_syms_03_c.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import global_syms_03_a

assert len(global_syms_03_a.l_1) == 4
assert global_syms_03_a.l_1[3] == "Thursday"
assert global_syms_03_a.l_3 == [1.0, 2.0, 3.0]
64 changes: 1 addition & 63 deletions src/libasr/asr_scopes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,10 @@ std::string SymbolTable::get_unique_name(const std::string &name) {

void SymbolTable::move_symbols_from_global_scope(Allocator &al,
SymbolTable *module_scope, Vec<char *> &syms,
Vec<char *> &mod_dependencies, Vec<char *> &func_dependencies,
Vec<ASR::stmt_t*> &var_init) {
Vec<char *> &mod_dependencies) {
// TODO: This isn't scalable. We have write a visitor in asdl_cpp.py
syms.reserve(al, 4);
mod_dependencies.reserve(al, 4);
func_dependencies.reserve(al, 4);
var_init.reserve(al, 4);
for (auto &a : scope) {
switch (a.second->type) {
case (ASR::symbolType::Module): {
Expand Down Expand Up @@ -206,47 +203,6 @@ void SymbolTable::move_symbols_from_global_scope(Allocator &al,
es->m_parent_symtab = module_scope;
ASR::symbol_t *s = ASRUtils::symbol_get_past_external(a.second);
LCOMPILERS_ASSERT(s);
if (ASR::is_a<ASR::Variable_t>(*s)) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the initializers of list types are moved into the global_initializer, so I removed all the changes which do the same thing.

ASR::Variable_t *v = ASR::down_cast<ASR::Variable_t>(s);
if (v->m_symbolic_value && !ASR::is_a<ASR::Const_t>(*v->m_type)
&& ASR::is_a<ASR::List_t>(*v->m_type)) {
ASR::expr_t* target = ASRUtils::EXPR(ASR::make_Var_t(
al, v->base.base.loc, (ASR::symbol_t *) es));
ASR::expr_t *value = v->m_symbolic_value;
v->m_symbolic_value = nullptr;
v->m_value = nullptr;
if (ASR::is_a<ASR::FunctionCall_t>(*value)) {
ASR::FunctionCall_t *call =
ASR::down_cast<ASR::FunctionCall_t>(value);
ASR::Module_t *m = ASRUtils::get_sym_module(s);
ASR::symbol_t *func = m->m_symtab->get_symbol(
ASRUtils::symbol_name(call->m_name));
ASR::Function_t *f = ASR::down_cast<ASR::Function_t>(func);
std::string func_name = std::string(m->m_name) +
"@" + f->m_name;
ASR::symbol_t *es_func;
if (!module_scope->get_symbol(func_name)) {
es_func = ASR::down_cast<ASR::symbol_t>(
ASR::make_ExternalSymbol_t(al, f->base.base.loc,
module_scope, s2c(al, func_name), func, m->m_name,
nullptr, 0, s2c(al, f->m_name), ASR::accessType::Public));
module_scope->add_symbol(func_name, es_func);
if (!present(func_dependencies, s2c(al, func_name))) {
func_dependencies.push_back(al, s2c(al,func_name));
}
} else {
es_func = module_scope->get_symbol(func_name);
}
value = ASRUtils::EXPR(ASR::make_FunctionCall_t(al,
call->base.base.loc, es_func, call->m_original_name,
call->m_args, call->n_args, call->m_type,
call->m_value, call->m_dt));
}
ASR::asr_t* assign = ASR::make_Assignment_t(al,
v->base.base.loc, target, value, nullptr);
var_init.push_back(al, ASRUtils::STMT(assign));
}
}
module_scope->add_symbol(a.first, (ASR::symbol_t *) es);
syms.push_back(al, s2c(al, a.first));
break;
Expand All @@ -271,24 +227,6 @@ void SymbolTable::move_symbols_from_global_scope(Allocator &al,
} case (ASR::symbolType::Variable) : {
ASR::Variable_t *v = ASR::down_cast<ASR::Variable_t>(a.second);
v->m_parent_symtab = module_scope;
// Make the Assignment statement only for the data-types (List,
// Dict, ...), that cannot be handled in the LLVM global scope
if (v->m_symbolic_value && !ASR::is_a<ASR::Const_t>(*v->m_type)
&& ASR::is_a<ASR::List_t>(*v->m_type)) {
ASR::expr_t* v_expr = ASRUtils::EXPR(ASR::make_Var_t(
al, v->base.base.loc, (ASR::symbol_t *) v));
ASR::asr_t* assign = ASR::make_Assignment_t(al,
v->base.base.loc, v_expr, v->m_symbolic_value, nullptr);
var_init.push_back(al, ASRUtils::STMT(assign));
v->m_symbolic_value = nullptr;
v->m_value = nullptr;
Vec<char*> v_dependencies;
v_dependencies.reserve(al, 1);
ASRUtils::collect_variable_dependencies(al,
v_dependencies, v->m_type);
v->m_dependencies = v_dependencies.p;
v->n_dependencies = v_dependencies.size();
}
module_scope->add_symbol(a.first, (ASR::symbol_t *) v);
syms.push_back(al, s2c(al, a.first));
break;
Expand Down
3 changes: 1 addition & 2 deletions src/libasr/asr_scopes.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,7 @@ struct SymbolTable {

void move_symbols_from_global_scope(Allocator &al,
SymbolTable *module_scope, Vec<char *> &syms,
Vec<char *> &mod_dependencies, Vec<char *> &func_dependencies,
Vec<ASR::stmt_t*> &var_init);
Vec<char *> &mod_dependencies);
};

} // namespace LCompilers
Expand Down
21 changes: 1 addition & 20 deletions src/libasr/pass/global_symbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,35 +22,16 @@ void pass_wrap_global_syms_into_module(Allocator &al,
SymbolTable *module_scope = al.make_new<SymbolTable>(unit.m_global_scope);
Vec<char *> moved_symbols;
Vec<char *> mod_dependencies;
Vec<char *> func_dependencies;
Vec<ASR::stmt_t*> var_init;

// Move all the symbols from global into the module scope
unit.m_global_scope->move_symbols_from_global_scope(al, module_scope,
moved_symbols, mod_dependencies, func_dependencies, var_init);
moved_symbols, mod_dependencies);

// Erase the symbols that are moved into the module
for (auto &sym: moved_symbols) {
unit.m_global_scope->erase_symbol(sym);
}

if (module_scope->get_symbol(pass_options.run_fun) && var_init.n > 0) {
ASR::Function_t *f = ASR::down_cast<ASR::Function_t>(
module_scope->get_symbol(pass_options.run_fun));
for (size_t i = 0; i < f->n_body; i++) {
var_init.push_back(al, f->m_body[i]);
}
for (size_t i = 0; i < f->n_dependencies; i++) {
func_dependencies.push_back(al, f->m_dependencies[i]);
}
f->m_body = var_init.p;
f->n_body = var_init.n;
f->m_dependencies = func_dependencies.p;
f->n_dependencies = func_dependencies.n;
// Overwrites the function: `_lpython_main_program`
module_scope->add_symbol(f->m_name, (ASR::symbol_t *) f);
}

ASR::symbol_t *module = (ASR::symbol_t *) ASR::make_Module_t(al, loc,
module_scope, module_name, mod_dependencies.p, mod_dependencies.n,
false, false);
Expand Down
Loading