Skip to content

Commit 47a1d0c

Browse files
XX Wrap symbols from global scope into a function
1 parent a5aa754 commit 47a1d0c

11 files changed

+131
-12
lines changed

examples/expr2.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1-
def main0():
2-
x: i32
3-
x = (2+3)*5
4-
print(x)
1+
from ltypes import i32
52

6-
main0()
3+
x: list[i32]
4+
x = [1,2,3]
5+
print(x, x[0])
6+
7+
# def main0():
8+
# x: list[i32] = [1]
9+
# print(x, x[0])
10+
# print(x[0])
11+
12+
# main0()
713

814
# Not implemented yet in LPython:
915
#if __name__ == "__main__":

src/libasr/ASR.asdl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@
2828

2929
module ASR {
3030

31+
-- `main` in `TranslationUnit` designates a function name similar to the main
32+
-- function in C (temporary solution)
3133
unit
32-
= TranslationUnit(symbol_table global_scope, node* items)
34+
= TranslationUnit(symbol_table global_scope, identifier? main, node* items)
3335

3436
-- # Documentation for the symbol type
3537

src/libasr/asr_scopes.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,27 @@ std::string SymbolTable::get_unique_name(const std::string &name) {
134134
return unique_name;
135135
}
136136

137+
void SymbolTable::move_symbols_from_global_scope(SymbolTable *fn_scope,
138+
std::vector<std::string> &syms) {
139+
for (auto &a : scope) {
140+
switch (a.second->type) {
141+
case (ASR::symbolType::Variable) : {
142+
ASR::Variable_t *v = ASR::down_cast<ASR::Variable_t>(a.second);
143+
if (ASR::is_a<ASR::List_t>(*v->m_type)
144+
|| ASR::is_a<ASR::Tuple_t>(*v->m_type)
145+
|| ASR::is_a<ASR::Dict_t>(*v->m_type)) {
146+
v->m_parent_symtab = fn_scope;
147+
fn_scope->add_symbol(a.first, (ASR::symbol_t *)v);
148+
syms.push_back(a.first);
149+
break;
150+
}
151+
}
152+
default : {
153+
LCompilersException("Moving the symbol:`"
154+
"` from global scope is not implemented yet");
155+
};
156+
}
157+
}
158+
}
159+
137160
} // namespace LCompilers

src/libasr/asr_scopes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ struct SymbolTable {
8080
size_t n_scope_names, char **m_scope_names);
8181

8282
std::string get_unique_name(const std::string &name);
83+
84+
void move_symbols_from_global_scope(SymbolTable *fn_scope,
85+
std::vector<std::string> &syms);
8386
};
8487

8588
} // namespace LCompilers

src/libasr/asr_utils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ ASR::Module_t* load_module(Allocator &al, SymbolTable *symtab,
180180
ASR::asr_t *orig_asr_owner = symtab->asr_owner;
181181
ASR::TranslationUnit_t *tu
182182
= ASR::down_cast2<ASR::TranslationUnit_t>(ASR::make_TranslationUnit_t(al, loc,
183-
symtab, nullptr, 0));
183+
symtab, "_global_statements", nullptr, 0));
184184

185185
// Load any dependent modules recursively
186186
bool rerun = true;

src/libasr/asr_utils.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2090,6 +2090,46 @@ class ReplaceReturnWithGotoVisitor: public ASR::BaseStmtReplacer<ReplaceReturnWi
20902090

20912091
};
20922092

2093+
class VarExprReplacer: public ASR::BaseExprReplacer<VarExprReplacer>
2094+
{
2095+
private:
2096+
Allocator &al;
2097+
SymbolTable *current_scope;
2098+
2099+
public:
2100+
VarExprReplacer(Allocator& al_, SymbolTable *current_scope_) :
2101+
al(al_), current_scope(current_scope_)
2102+
{}
2103+
2104+
void replace_Var(ASR::Var_t *x) {
2105+
std::string sym_name = ASRUtils::symbol_name(x->m_v);
2106+
ASR::symbol_t *s = current_scope->resolve_symbol(sym_name);
2107+
LCOMPILERS_ASSERT(s != nullptr)
2108+
*current_expr = ASRUtils::EXPR(ASR::make_Var_t(al,
2109+
x->base.base.loc, s));
2110+
}
2111+
};
2112+
2113+
class VarExprVisitor : public ASR::CallReplacerOnExpressionsVisitor
2114+
<VarExprVisitor>
2115+
{
2116+
private:
2117+
2118+
VarExprReplacer replacer;
2119+
2120+
public:
2121+
2122+
VarExprVisitor(Allocator& al_, SymbolTable *current_scope) :
2123+
replacer(al_, current_scope)
2124+
{ }
2125+
2126+
void call_replacer() {
2127+
replacer.current_expr = current_expr;
2128+
replacer.replace_expr(*current_expr);
2129+
}
2130+
2131+
};
2132+
20932133
// Singleton LabelGenerator so that it generates
20942134
// unique labels for different statements, from
20952135
// whereever it is called (be it ASR passes, be it

src/libasr/asr_verify.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -533,14 +533,20 @@ class VerifyVisitor : public BaseWalkVisitor<VerifyVisitor>
533533
"ExternalSymbol::m_original_name must match external->m_name");
534534
ASR::Module_t *m = ASRUtils::get_sym_module(x.m_external);
535535
ASR::StructType_t* sm = nullptr;
536+
ASR::Function_t* fn = nullptr;
536537
bool is_valid_owner = false;
537538
is_valid_owner = m != nullptr;
538539
std::string asr_owner_name = "";
539540
if( !is_valid_owner ) {
541+
is_valid_owner = true;
540542
ASR::symbol_t* asr_owner_sym = ASRUtils::get_asr_owner(x.m_external);
541-
is_valid_owner = ASR::is_a<ASR::StructType_t>(*asr_owner_sym);
542-
sm = ASR::down_cast<ASR::StructType_t>(asr_owner_sym);
543-
asr_owner_name = sm->m_name;
543+
if ( ASR::is_a<ASR::StructType_t>(*asr_owner_sym) ) {
544+
sm = ASR::down_cast<ASR::StructType_t>(asr_owner_sym);
545+
asr_owner_name = sm->m_name;
546+
} else if (ASR::is_a<ASR::Function_t>(*asr_owner_sym)) {
547+
fn = ASR::down_cast<ASR::Function_t>(asr_owner_sym);
548+
asr_owner_name = fn->m_name;
549+
}
544550
} else {
545551
asr_owner_name = m->m_name;
546552
}
@@ -554,6 +560,8 @@ class VerifyVisitor : public BaseWalkVisitor<VerifyVisitor>
554560
s = m->m_symtab->find_scoped_symbol(x.m_original_name, x.n_scope_names, x.m_scope_names);
555561
} else if( sm ) {
556562
s = sm->m_symtab->resolve_symbol(std::string(x.m_original_name));
563+
} else if( fn ) {
564+
s = fn->m_symtab->resolve_symbol(std::string(x.m_original_name));
557565
}
558566
require(s != nullptr,
559567
"ExternalSymbol::m_original_name ('"

src/libasr/pass/global_stmts.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,38 @@ void pass_wrap_global_stmts_into_function(Allocator &al,
162162
}
163163
}
164164

165+
void pass_wrap_global_vars_into_function(Allocator &al, ASR::TranslationUnit_t &unit) {
166+
std::vector<std::string> symbols;
167+
ASR::symbol_t *fn_s = unit.m_global_scope->get_symbol(unit.m_main);
168+
169+
// Move symbols that fails in the global scope
170+
unit.m_global_scope->move_symbols_from_global_scope(
171+
ASR::down_cast<ASR::Function_t>(fn_s)->m_symtab, symbols);
172+
173+
// Create ExternalSymbol and erase the actual symbols
174+
// that are moved into the function
175+
for (auto &sym: symbols) {
176+
ASR::symbol_t *var_s = unit.m_global_scope->get_symbol(sym);
177+
ASR::Variable_t *v = ASR::down_cast<ASR::Variable_t>(var_s);
178+
var_s = (ASR::symbol_t *) ASR::make_ExternalSymbol_t(al,
179+
v->base.base.loc, unit.m_global_scope, v->m_name, var_s,
180+
ASRUtils::symbol_name(ASRUtils::get_asr_owner(var_s)),
181+
nullptr, 0, v->m_name, ASR::accessType::Public);
182+
unit.m_global_scope->erase_symbol(sym);
183+
unit.m_global_scope->add_symbol(v->m_name, var_s);
184+
}
185+
186+
// Replace the Var_t with correct symbol_table
187+
ASRUtils::VarExprVisitor replace_sym(al, unit.m_global_scope);
188+
replace_sym.visit_TranslationUnit(unit);
189+
190+
#if defined(WITH_LFORTRAN_ASSERT)
191+
diag::Diagnostics diagnostics;
192+
if (!asr_verify(unit, true, diagnostics)) {
193+
std::cerr << diagnostics.render2();
194+
throw LCompilersException("Verify failed");
195+
};
196+
#endif
197+
}
198+
165199
} // namespace LCompilers

src/libasr/pass/global_stmts.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ namespace LCompilers {
88

99
void pass_wrap_global_stmts_into_function(Allocator &al, ASR::TranslationUnit_t &unit,
1010
const LCompilers::PassOptions& pass_options);
11+
void pass_wrap_global_vars_into_function(Allocator &al,
12+
ASR::TranslationUnit_t &unit);
1113

1214
} // namespace LCompilers
1315

src/libasr/pass/global_stmts_program.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ void pass_wrap_global_stmts_into_program(Allocator &al,
2626
prog_body.reserve(al, 1);
2727
if (unit.n_items > 0) {
2828
pass_wrap_global_stmts_into_function(al, unit, pass_options);
29+
pass_wrap_global_vars_into_function(al, unit);
2930
ASR::symbol_t *fn = unit.m_global_scope->get_symbol(program_fn_name);
3031
if (ASR::is_a<ASR::Function_t>(*fn)
3132
&& ASR::down_cast<ASR::Function_t>(fn)->m_return_var == nullptr) {

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3267,7 +3267,7 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
32673267
// ASRUtils::get_tu_symtab() can be used, which has an assert
32683268
// for asr_owner.
32693269
ASR::asr_t *tmp0 = ASR::make_TranslationUnit_t(al, x.base.base.loc,
3270-
current_scope, nullptr, 0);
3270+
current_scope, "_lpython_main_program", nullptr, 0);
32713271

32723272
ASR::Module_t* module_sym = nullptr;
32733273

@@ -6248,7 +6248,7 @@ Result<ASR::TranslationUnit_t*> python_ast_to_asr(Allocator &al, LocationManager
62486248
pass_options.run_fun = "_lpython_main_program";
62496249
pass_options.runtime_library_dir = get_runtime_library_dir();
62506250
pass_wrap_global_stmts_into_program(al, *tu, pass_options);
6251-
LCOMPILERS_ASSERT(asr_verify(*tu, true, diagnostics));
6251+
// LCOMPILERS_ASSERT(asr_verify(*tu, true, diagnostics));
62526252
}
62536253
}
62546254

0 commit comments

Comments
 (0)