Skip to content

Always insert global symbols to _global_symbols module #1732

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 21, 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
68 changes: 68 additions & 0 deletions integration_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,72 @@ macro(RUN)
endif()
endmacro(RUN)

# only compiles till object file
# to make sure that the generated code is syntactically correct
# but we cannot generate an executable due to --disable-main option enabled.
macro(COMPILE)
set(options FAIL)
set(oneValueArgs NAME IMPORT_PATH)
set(multiValueArgs LABELS EXTRAFILES)
cmake_parse_arguments(COMPILE "${options}" "${oneValueArgs}"
"${multiValueArgs}" ${ARGN} )
set(name ${COMPILE_NAME})
set(import_path ${COMPILE_IMPORT_PATH})
if (NOT name)
message(FATAL_ERROR "Must specify the NAME argument")
endif()

if (${KIND} IN_LIST COMPILE_LABELS)
if (KIND STREQUAL "llvm")
if (import_path)
add_custom_command(
OUTPUT ${name}.o
COMMAND lpython --disable-main -c -I ${CMAKE_CURRENT_SOURCE_DIR}/${import_path} ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py -o ${name}.o
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py
VERBATIM)
else ()
add_custom_command(
OUTPUT ${name}.o
COMMAND lpython --disable-main -c ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py -o ${name}.o
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py
VERBATIM)
endif()

add_library(${name} OBJECT ${name}.o)
elseif(KIND STREQUAL "c")
if (import_path)
add_custom_command(
OUTPUT ${name}.c
COMMAND lpython --disable-main -I ${CMAKE_CURRENT_SOURCE_DIR}/${import_path} --show-c ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py > ${name}.c
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py
VERBATIM)
else ()
add_custom_command(
OUTPUT ${name}.c
COMMAND lpython --disable-main --show-c ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py > ${name}.c
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py
VERBATIM)
endif()

add_library(${name} OBJECT ${name}.c)
target_link_libraries(${name} lpython_rtlib)
elseif(KIND STREQUAL "cpython")
# CPython test
set(PY_MOD "")

add_test(${name} python ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py)
set_tests_properties(${name} PROPERTIES
ENVIRONMENT "PYTHONPATH=${CMAKE_SOURCE_DIR}/../src/runtime/lpython:${CMAKE_SOURCE_DIR}/..;LPYTHON_PY_MOD_NAME=${PY_MOD};LPYTHON_PY_MOD_PATH=${CMAKE_CURRENT_BINARY_DIR}")
if (RUN_LABELS)
set_tests_properties(${name} PROPERTIES LABELS "${RUN_LABELS}")
endif()
if (${RUN_FAIL})
set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE)
endif()
endif()
endif()
endmacro(COMPILE)


# Test zero and non-zero exit code and assert statements
RUN(NAME array_01_decl LABELS cpython llvm c)
Expand Down Expand Up @@ -456,3 +522,5 @@ RUN(NAME global_syms_06 LABELS cpython llvm c)

# Intrinsic Functions
RUN(NAME intrinsics_01 LABELS cpython llvm) # any

COMPILE(NAME import_order_01 LABELS cpython llvm c) # any
7 changes: 7 additions & 0 deletions integration_tests/import_order_01.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from import_order_01b import f
from lpython import i32, ccallback

@ccallback
def main1():
a: i32 = f()
print(a)
4 changes: 4 additions & 0 deletions integration_tests/import_order_01b.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from lpython import i32

def f() -> i32:
return 42
2 changes: 1 addition & 1 deletion integration_tests/variable_decl_03.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from lpython import f64

def f() -> f64:
return 5.5
return abs(-5.5)

def main():
t1: f64 = f() * 1e6
Expand Down
254 changes: 128 additions & 126 deletions src/libasr/pass/global_stmts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,146 +20,148 @@ using ASRUtils::EXPR;
*/
void pass_wrap_global_stmts_into_function(Allocator &al,
ASR::TranslationUnit_t &unit, const LCompilers::PassOptions& pass_options) {
if (unit.n_items == 0) {
return ;
}

std::string fn_name_s = pass_options.run_fun;
if (unit.n_items > 0) {
// Add an anonymous function
Str s;
s.from_str_view(fn_name_s);
char *fn_name = s.c_str(al);
SymbolTable *fn_scope = al.make_new<SymbolTable>(unit.m_global_scope);
// Add an anonymous function
Str s;
s.from_str_view(fn_name_s);
char *fn_name = s.c_str(al);
SymbolTable *fn_scope = al.make_new<SymbolTable>(unit.m_global_scope);

ASR::ttype_t *type;
Location loc = unit.base.base.loc;
ASR::asr_t *return_var=nullptr;
ASR::expr_t *return_var_ref=nullptr;
char *var_name;
int idx = 1;
ASR::ttype_t *type;
Location loc = unit.base.base.loc;
ASR::asr_t *return_var=nullptr;
ASR::expr_t *return_var_ref=nullptr;
char *var_name;
int idx = 1;

Vec<ASR::stmt_t*> body;
body.reserve(al, unit.n_items);
for (size_t i=0; i<unit.n_items; i++) {
if (unit.m_items[i]->type == ASR::asrType::expr) {
ASR::expr_t *target;
ASR::expr_t *value = EXPR(unit.m_items[i]);
// Create a new variable with the right type
if (ASRUtils::expr_type(value)->type == ASR::ttypeType::Integer) {
s.from_str(al, fn_name_s + std::to_string(idx));
var_name = s.c_str(al);
Vec<ASR::stmt_t*> body;
body.reserve(al, unit.n_items);
for (size_t i=0; i<unit.n_items; i++) {
if (unit.m_items[i]->type == ASR::asrType::expr) {
ASR::expr_t *target;
ASR::expr_t *value = EXPR(unit.m_items[i]);
// Create a new variable with the right type
if (ASRUtils::expr_type(value)->type == ASR::ttypeType::Integer) {
s.from_str(al, fn_name_s + std::to_string(idx));
var_name = s.c_str(al);

int a_kind = down_cast<ASR::Integer_t>(ASRUtils::expr_type(value))->m_kind;
int a_kind = down_cast<ASR::Integer_t>(ASRUtils::expr_type(value))->m_kind;

type = ASRUtils::TYPE(ASR::make_Integer_t(al, loc, a_kind, nullptr, 0));
return_var = ASR::make_Variable_t(al, loc,
fn_scope, var_name, nullptr, 0, ASRUtils::intent_local, nullptr, nullptr,
ASR::storage_typeType::Default, type,
ASR::abiType::BindC,
ASR::Public, ASR::presenceType::Required, false);
return_var_ref = EXPR(ASR::make_Var_t(al, loc,
down_cast<ASR::symbol_t>(return_var)));
fn_scope->add_symbol(std::string(var_name), down_cast<ASR::symbol_t>(return_var));
target = return_var_ref;
idx++;
} else if (ASRUtils::expr_type(value)->type == ASR::ttypeType::Real) {
s.from_str(al, fn_name_s + std::to_string(idx));
var_name = s.c_str(al);
type = ASRUtils::expr_type(value);
return_var = ASR::make_Variable_t(al, loc,
fn_scope, var_name, nullptr, 0, ASRUtils::intent_local, nullptr, nullptr,
ASR::storage_typeType::Default, type,
ASR::abiType::BindC,
ASR::Public, ASR::presenceType::Required, false);
return_var_ref = EXPR(ASR::make_Var_t(al, loc,
down_cast<ASR::symbol_t>(return_var)));
fn_scope->add_symbol(std::string(var_name), down_cast<ASR::symbol_t>(return_var));
target = return_var_ref;
idx++;
} else if (ASRUtils::expr_type(value)->type == ASR::ttypeType::Complex) {
s.from_str(al, fn_name_s + std::to_string(idx));
var_name = s.c_str(al);
type = ASRUtils::expr_type(value);
return_var = ASR::make_Variable_t(al, loc,
fn_scope, var_name, nullptr, 0, ASRUtils::intent_local, nullptr, nullptr,
ASR::storage_typeType::Default, type,
ASR::abiType::BindC,
ASR::Public, ASR::presenceType::Required, false);
return_var_ref = EXPR(ASR::make_Var_t(al, loc,
down_cast<ASR::symbol_t>(return_var)));
fn_scope->add_symbol(std::string(var_name), down_cast<ASR::symbol_t>(return_var));
target = return_var_ref;
idx++;
} else {
throw LCompilersException("Return type not supported in interactive mode");
}
ASR::stmt_t* asr_stmt = ASRUtils::STMT(ASR::make_Assignment_t(al, loc, target, value, nullptr));
body.push_back(al, asr_stmt);
} else if (unit.m_items[i]->type == ASR::asrType::stmt) {
ASR::stmt_t* asr_stmt = ASRUtils::STMT(unit.m_items[i]);
body.push_back(al, asr_stmt);
return_var = nullptr;
type = ASRUtils::TYPE(ASR::make_Integer_t(al, loc, a_kind, nullptr, 0));
return_var = ASR::make_Variable_t(al, loc,
fn_scope, var_name, nullptr, 0, ASRUtils::intent_local, nullptr, nullptr,
ASR::storage_typeType::Default, type,
ASR::abiType::BindC,
ASR::Public, ASR::presenceType::Required, false);
return_var_ref = EXPR(ASR::make_Var_t(al, loc,
down_cast<ASR::symbol_t>(return_var)));
fn_scope->add_symbol(std::string(var_name), down_cast<ASR::symbol_t>(return_var));
target = return_var_ref;
idx++;
} else if (ASRUtils::expr_type(value)->type == ASR::ttypeType::Real) {
s.from_str(al, fn_name_s + std::to_string(idx));
var_name = s.c_str(al);
type = ASRUtils::expr_type(value);
return_var = ASR::make_Variable_t(al, loc,
fn_scope, var_name, nullptr, 0, ASRUtils::intent_local, nullptr, nullptr,
ASR::storage_typeType::Default, type,
ASR::abiType::BindC,
ASR::Public, ASR::presenceType::Required, false);
return_var_ref = EXPR(ASR::make_Var_t(al, loc,
down_cast<ASR::symbol_t>(return_var)));
fn_scope->add_symbol(std::string(var_name), down_cast<ASR::symbol_t>(return_var));
target = return_var_ref;
idx++;
} else if (ASRUtils::expr_type(value)->type == ASR::ttypeType::Complex) {
s.from_str(al, fn_name_s + std::to_string(idx));
var_name = s.c_str(al);
type = ASRUtils::expr_type(value);
return_var = ASR::make_Variable_t(al, loc,
fn_scope, var_name, nullptr, 0, ASRUtils::intent_local, nullptr, nullptr,
ASR::storage_typeType::Default, type,
ASR::abiType::BindC,
ASR::Public, ASR::presenceType::Required, false);
return_var_ref = EXPR(ASR::make_Var_t(al, loc,
down_cast<ASR::symbol_t>(return_var)));
fn_scope->add_symbol(std::string(var_name), down_cast<ASR::symbol_t>(return_var));
target = return_var_ref;
idx++;
} else {
throw LCompilersException("Unsupported type of global scope node");
throw LCompilersException("Return type not supported in interactive mode");
}
ASR::stmt_t* asr_stmt = ASRUtils::STMT(ASR::make_Assignment_t(al, loc, target, value, nullptr));
body.push_back(al, asr_stmt);
} else if (unit.m_items[i]->type == ASR::asrType::stmt) {
ASR::stmt_t* asr_stmt = ASRUtils::STMT(unit.m_items[i]);
body.push_back(al, asr_stmt);
return_var = nullptr;
} else {
throw LCompilersException("Unsupported type of global scope node");
}
}

if (return_var) {
// The last item was an expression, create a function returning it
if (return_var) {
// The last item was an expression, create a function returning it

// The last defined `return_var` is the actual return value
ASR::down_cast2<ASR::Variable_t>(return_var)->m_intent = ASRUtils::intent_return_var;
// The last defined `return_var` is the actual return value
ASR::down_cast2<ASR::Variable_t>(return_var)->m_intent = ASRUtils::intent_return_var;


ASR::asr_t *fn = ASRUtils::make_Function_t_util(
al, loc,
/* a_symtab */ fn_scope,
/* a_name */ fn_name,
nullptr, 0,
/* a_args */ nullptr,
/* n_args */ 0,
/* a_body */ body.p,
/* n_body */ body.size(),
/* a_return_var */ return_var_ref,
ASR::abiType::BindC,
ASR::Public, ASR::Implementation,
nullptr,
false, false, false, false, false,
nullptr, 0,
nullptr, 0,
false, false, false);
std::string sym_name = fn_name;
if (unit.m_global_scope->get_symbol(sym_name) != nullptr) {
throw LCompilersException("Function already defined");
}
unit.m_global_scope->add_symbol(sym_name, down_cast<ASR::symbol_t>(fn));
} else {
// The last item was a statement, create a subroutine (returning
// nothing)
ASR::asr_t *fn = ASRUtils::make_Function_t_util(
al, loc,
/* a_symtab */ fn_scope,
/* a_name */ fn_name,
nullptr, 0,
/* a_args */ nullptr,
/* n_args */ 0,
/* a_body */ body.p,
/* n_body */ body.size(),
nullptr,
ASR::abiType::Source,
ASR::Public, ASR::Implementation, nullptr,
false, false, false, false, false,
nullptr, 0,
nullptr, 0,
false, false, false);
std::string sym_name = fn_name;
if (unit.m_global_scope->get_symbol(sym_name) != nullptr) {
throw LCompilersException("Function already defined");
}
unit.m_global_scope->add_symbol(sym_name, down_cast<ASR::symbol_t>(fn));
ASR::asr_t *fn = ASRUtils::make_Function_t_util(
al, loc,
/* a_symtab */ fn_scope,
/* a_name */ fn_name,
nullptr, 0,
/* a_args */ nullptr,
/* n_args */ 0,
/* a_body */ body.p,
/* n_body */ body.size(),
/* a_return_var */ return_var_ref,
ASR::abiType::BindC,
ASR::Public, ASR::Implementation,
nullptr,
false, false, false, false, false,
nullptr, 0,
nullptr, 0,
false, false, false);
std::string sym_name = fn_name;
if (unit.m_global_scope->get_symbol(sym_name) != nullptr) {
throw LCompilersException("Function already defined");
}
unit.m_global_scope->add_symbol(sym_name, down_cast<ASR::symbol_t>(fn));
} else {
// The last item was a statement, create a subroutine (returning
// nothing)
ASR::asr_t *fn = ASRUtils::make_Function_t_util(
al, loc,
/* a_symtab */ fn_scope,
/* a_name */ fn_name,
nullptr, 0,
/* a_args */ nullptr,
/* n_args */ 0,
/* a_body */ body.p,
/* n_body */ body.size(),
nullptr,
ASR::abiType::Source,
ASR::Public, ASR::Implementation, nullptr,
false, false, false, false, false,
nullptr, 0,
nullptr, 0,
false, false, false);
std::string sym_name = fn_name;
if (unit.m_global_scope->get_symbol(sym_name) != nullptr) {
throw LCompilersException("Function already defined");
}
unit.m_items = nullptr;
unit.n_items = 0;
PassUtils::UpdateDependenciesVisitor v(al);
v.visit_TranslationUnit(unit);
unit.m_global_scope->add_symbol(sym_name, down_cast<ASR::symbol_t>(fn));
}
unit.m_items = nullptr;
unit.n_items = 0;
PassUtils::UpdateDependenciesVisitor v(al);
v.visit_TranslationUnit(unit);
}

} // namespace LCompilers
Loading