Skip to content

Commit

Permalink
Always insert global symbols to _global_symbols module
Browse files Browse the repository at this point in the history
  • Loading branch information
czgdp1807 committed Apr 21, 2023
1 parent b28a440 commit ba15bf1
Show file tree
Hide file tree
Showing 52 changed files with 7,668 additions and 7,351 deletions.
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

0 comments on commit ba15bf1

Please sign in to comment.