Skip to content
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
9 changes: 5 additions & 4 deletions integration_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ macro(RUN)
if (import_path)
add_custom_command(
OUTPUT ${name}.o
COMMAND lpython -c -I ${import_path} ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py -o ${name}.o
COMMAND lpython -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 ()
Expand Down Expand Up @@ -109,7 +109,7 @@ macro(RUN)

add_test(${name} python ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py)
set_tests_properties(${name} PROPERTIES
ENVIRONMENT "PYTHONPATH=${CMAKE_SOURCE_DIR}/../src/runtime/ltypes;LPYTHON_PY_MOD_NAME=${PY_MOD};LPYTHON_PY_MOD_PATH=${CMAKE_CURRENT_BINARY_DIR}")
ENVIRONMENT "PYTHONPATH=${CMAKE_SOURCE_DIR}/../src/runtime/ltypes:${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()
Expand Down Expand Up @@ -248,9 +248,10 @@ RUN(NAME test_for_loop LABELS cpython llvm c)
RUN(NAME modules_01 LABELS cpython llvm wasm wasm_x86)
RUN(NAME modules_02 LABELS cpython llvm wasm wasm_x86)
RUN(NAME test_import_01 LABELS cpython llvm)
RUN(NAME test_import_02 IMPORT_PATH integration_tests
LABELS cpython llvm)
RUN(NAME test_import_02 LABELS cpython llvm)
RUN(NAME test_import_03 LABELS cpython llvm)
RUN(NAME test_import_04 IMPORT_PATH ..
LABELS cpython llvm)
RUN(NAME test_math LABELS cpython llvm)
RUN(NAME test_numpy_01 LABELS cpython llvm c)
RUN(NAME test_numpy_02 LABELS cpython llvm c)
Expand Down
8 changes: 8 additions & 0 deletions integration_tests/test_import_04.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import test_modules

def main0():
print(test_modules.sin(0.5))
print(test_modules.cos(0.5))
assert abs(test_modules.sin(0.5) + test_modules.cos(0.5) - 1.0) <= 1e-12

main0()
45 changes: 36 additions & 9 deletions src/lpython/semantics/python_ast_to_asr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,11 +421,12 @@ ASR::Module_t* load_module(Allocator &al, SymbolTable *symtab,
}

ASR::symbol_t* import_from_module(Allocator &al, ASR::Module_t *m, SymbolTable *current_scope,
std::string mname, std::string cur_sym_name, std::string new_sym_name,
std::string /*mname*/, std::string cur_sym_name, std::string& new_sym_name,
const Location &loc, bool skip_current_scope_check=false) {
new_sym_name = ASRUtils::get_mangled_name(m, new_sym_name);
ASR::symbol_t *t = m->m_symtab->resolve_symbol(cur_sym_name);
if (!t) {
throw SemanticError("The symbol '" + cur_sym_name + "' not found in the module '" + mname + "'",
throw SemanticError("The symbol '" + cur_sym_name + "' not found in the module '" + std::string(m->m_name) + "'",
loc);
}
if (!skip_current_scope_check &&
Expand Down Expand Up @@ -481,11 +482,19 @@ ASR::symbol_t* import_from_module(Allocator &al, ASR::Module_t *m, SymbolTable *
} else if (ASR::is_a<ASR::ExternalSymbol_t>(*t)) {
ASR::ExternalSymbol_t *es = ASR::down_cast<ASR::ExternalSymbol_t>(t);
SymbolTable *symtab = current_scope;
while (symtab->parent != nullptr) symtab = symtab->parent;
ASR::symbol_t *sym = symtab->get_symbol(es->m_module_name);
// while (symtab->parent != nullptr) symtab = symtab->parent;
ASR::symbol_t *sym = symtab->resolve_symbol(es->m_module_name);
ASR::Module_t *m = ASR::down_cast<ASR::Module_t>(sym);
return import_from_module(al, m, symtab, es->m_name,
return import_from_module(al, m, symtab, es->m_module_name,
cur_sym_name, new_sym_name, loc);
} else if (ASR::is_a<ASR::Module_t>(*t)) {
ASR::Module_t* mt = ASR::down_cast<ASR::Module_t>(t);
std::string mangled_cur_sym_name = ASRUtils::get_mangled_name(mt, new_sym_name);
if( cur_sym_name == mangled_cur_sym_name ) {
throw SemanticError("Importing modules isn't supported yet.", loc);
}
return import_from_module(al, mt, current_scope, std::string(mt->m_name),
cur_sym_name, new_sym_name, loc);
} else {
throw SemanticError("Only Subroutines, Functions, Variables and "
"ExternalSymbol are currently supported in 'import'", loc);
Expand Down Expand Up @@ -1007,6 +1016,7 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
std::string mod_name = ASR::down_cast<ASR::ExternalSymbol_t>(stemp)->m_module_name;
ASR::symbol_t *mt = symtab->resolve_symbol(mod_name);
ASR::Module_t *m = ASR::down_cast<ASR::Module_t>(mt);
local_sym = ASRUtils::get_mangled_name(m, local_sym);
stemp = import_from_module(al, m, symtab, mod_name,
remote_sym, local_sym, loc);
LFORTRAN_ASSERT(ASR::is_a<ASR::ExternalSymbol_t>(*stemp));
Expand Down Expand Up @@ -3534,7 +3544,18 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
throw SemanticError("The module '" + msym + "' cannot be loaded",
x.base.base.loc);
}
current_module_dependencies.push_back(al, s2c(al, msym));
if( msym == "__init__" ) {
for( auto item: ASRUtils::symbol_symtab(t)->get_scope() ) {
if( ASR::is_a<ASR::ExternalSymbol_t>(*item.second) &&
!present(current_module_dependencies,
ASR::down_cast<ASR::ExternalSymbol_t>(item.second)->m_module_name) ) {
current_module_dependencies.push_back(al,
ASR::down_cast<ASR::ExternalSymbol_t>(item.second)->m_module_name);
}
}
} else {
current_module_dependencies.push_back(al, s2c(al, msym));
}
}

ASR::Module_t *m = ASR::down_cast<ASR::Module_t>(t);
Expand All @@ -3544,7 +3565,7 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
}
std::string new_sym_name = ASRUtils::get_mangled_name(m, remote_sym);
ASR::symbol_t *t = import_from_module(al, m, current_scope, msym,
remote_sym, new_sym_name, x.base.base.loc, false);
remote_sym, new_sym_name, x.base.base.loc, true);
current_scope->add_symbol(new_sym_name, t);
}

Expand Down Expand Up @@ -4614,7 +4635,7 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
ASR::symbol_t *sym = current_scope->resolve_symbol(sym_name);
if (!sym) {
sym = import_from_module(al, m, current_scope, value,
x.m_attr, sym_name, x.base.base.loc, true);
x.m_attr, sym_name, x.base.base.loc, false);
LFORTRAN_ASSERT(ASR::is_a<ASR::ExternalSymbol_t>(*sym));
current_scope->add_symbol(sym_name, sym);
}
Expand Down Expand Up @@ -5898,7 +5919,13 @@ Result<ASR::TranslationUnit_t*> python_ast_to_asr(Allocator &al, LocationManager
} else {
return res2.error;
}
LFORTRAN_ASSERT(asr_verify(*tu, true, diagnostics));
#if defined(WITH_LFORTRAN_ASSERT)
diag::Diagnostics diagnostics;
if (!asr_verify(*tu, true, diagnostics)) {
std::cerr << diagnostics.render2();
throw LCompilersException("Verify failed");
};
#endif
}

if (main_module) {
Expand Down
1 change: 1 addition & 0 deletions test_modules/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .mathfn import sin, cos
1 change: 1 addition & 0 deletions test_modules/mathfn/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .sin import sin, cos
7 changes: 7 additions & 0 deletions test_modules/mathfn/sin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from ltypes import f64

def sin(x: f64) -> f64:
return x + 1.0

def cos(x: f64) -> f64:
return x - 1.0