Skip to content

Commit 0ab254e

Browse files
WIP
1 parent 74800ed commit 0ab254e

File tree

4 files changed

+81
-30
lines changed

4 files changed

+81
-30
lines changed

src/bin/lpython.cpp

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ int emit_asr(const std::string &infile,
164164
diagnostics.diagnostics.clear();
165165
LFortran::Result<LFortran::ASR::TranslationUnit_t*>
166166
r = LFortran::LPython::python_ast_to_asr(al, *ast, diagnostics, true,
167-
compiler_options.disable_main, compiler_options.symtab_only, infile);
167+
compiler_options.disable_main, compiler_options.symtab_only, infile,
168+
compiler_options.import_path);
168169
std::cerr << diagnostics.render(input, lm, compiler_options);
169170
if (!r.ok) {
170171
LFORTRAN_ASSERT(diagnostics.has_error())
@@ -207,7 +208,8 @@ int emit_cpp(const std::string &infile,
207208
diagnostics.diagnostics.clear();
208209
LFortran::Result<LFortran::ASR::TranslationUnit_t*>
209210
r1 = LFortran::LPython::python_ast_to_asr(al, *ast, diagnostics, true,
210-
compiler_options.disable_main, compiler_options.symtab_only, infile);
211+
compiler_options.disable_main, compiler_options.symtab_only, infile,
212+
compiler_options.import_path);
211213
std::cerr << diagnostics.render(input, lm, compiler_options);
212214
if (!r1.ok) {
213215
LFORTRAN_ASSERT(diagnostics.has_error())
@@ -248,7 +250,8 @@ int emit_c(const std::string &infile,
248250
diagnostics.diagnostics.clear();
249251
LFortran::Result<LFortran::ASR::TranslationUnit_t*>
250252
r1 = LFortran::LPython::python_ast_to_asr(al, *ast, diagnostics, true,
251-
compiler_options.disable_main, compiler_options.symtab_only, infile);
253+
compiler_options.disable_main, compiler_options.symtab_only, infile,
254+
compiler_options.import_path);
252255
std::cerr << diagnostics.render(input, lm, compiler_options);
253256
if (!r1.ok) {
254257
LFORTRAN_ASSERT(diagnostics.has_error())
@@ -289,7 +292,8 @@ int emit_wat(const std::string &infile,
289292
diagnostics.diagnostics.clear();
290293
LFortran::Result<LFortran::ASR::TranslationUnit_t*>
291294
r1 = LFortran::LPython::python_ast_to_asr(al, *ast, diagnostics, true,
292-
compiler_options.disable_main, compiler_options.symtab_only, infile);
295+
compiler_options.disable_main, compiler_options.symtab_only, infile,
296+
compiler_options.import_path);
293297
std::cerr << diagnostics.render(input, lm, compiler_options);
294298
if (!r1.ok) {
295299
LFORTRAN_ASSERT(diagnostics.has_error())
@@ -333,7 +337,8 @@ int get_symbols (const std::string &infile,
333337
LFortran::LPython::AST::ast_t* ast = r1.result;
334338
LFortran::Result<LFortran::ASR::TranslationUnit_t*>
335339
x = LFortran::LPython::python_ast_to_asr(al, *ast, diagnostics, true,
336-
compiler_options.disable_main, compiler_options.symtab_only, infile);
340+
compiler_options.disable_main, compiler_options.symtab_only,
341+
infile, compiler_options.import_path);
337342
if (!x.ok) {
338343
std::cout << "{}\n";
339344
return 0;
@@ -426,7 +431,8 @@ int get_errors (const std::string &infile,
426431
LFortran::LPython::AST::ast_t* ast = r1.result;
427432
LFortran::Result<LFortran::ASR::TranslationUnit_t*>
428433
r = LFortran::LPython::python_ast_to_asr(al, *ast, diagnostics, true,
429-
compiler_options.disable_main, compiler_options.symtab_only, infile);
434+
compiler_options.disable_main, compiler_options.symtab_only,
435+
infile, compiler_options.import_path);
430436
}
431437
std::vector<LFortran::LPython::error_highlight> diag_lists;
432438
LFortran::LPython::error_highlight h;
@@ -538,7 +544,8 @@ int emit_llvm(const std::string &infile,
538544
diagnostics.diagnostics.clear();
539545
LFortran::Result<LFortran::ASR::TranslationUnit_t*>
540546
r1 = LFortran::LPython::python_ast_to_asr(al, *ast, diagnostics, true,
541-
compiler_options.disable_main, compiler_options.symtab_only, infile);
547+
compiler_options.disable_main, compiler_options.symtab_only, infile,
548+
compiler_options.import_path);
542549
std::cerr << diagnostics.render(input, lm, compiler_options);
543550
if (!r1.ok) {
544551
LFORTRAN_ASSERT(diagnostics.has_error())
@@ -596,7 +603,8 @@ int compile_python_to_object_file(
596603
LFortran::Result<LFortran::ASR::TranslationUnit_t*>
597604
r1 = LFortran::LPython::python_ast_to_asr(al, *ast, diagnostics,
598605
!(arg_c && compiler_options.disable_main),
599-
compiler_options.disable_main, compiler_options.symtab_only, infile);
606+
compiler_options.disable_main, compiler_options.symtab_only, infile,
607+
compiler_options.import_path);
600608
auto ast_to_asr_end = std::chrono::high_resolution_clock::now();
601609
times.push_back(std::make_pair("AST to ASR", std::chrono::duration<double, std::milli>(ast_to_asr_end - ast_to_asr_start).count()));
602610
std::cerr << diagnostics.render(input, lm, compiler_options);
@@ -679,7 +687,8 @@ int compile_to_binary_wasm(
679687
auto ast_to_asr_start = std::chrono::high_resolution_clock::now();
680688
LFortran::Result<LFortran::ASR::TranslationUnit_t*>
681689
r1 = LFortran::LPython::python_ast_to_asr(al, *ast, diagnostics, true,
682-
compiler_options.disable_main, compiler_options.symtab_only, infile);
690+
compiler_options.disable_main, compiler_options.symtab_only, infile,
691+
compiler_options.import_path);
683692
auto ast_to_asr_end = std::chrono::high_resolution_clock::now();
684693
times.push_back(std::make_pair("AST to ASR", std::chrono::duration<double, std::milli>(ast_to_asr_end - ast_to_asr_start).count()));
685694
std::cerr << diagnostics.render(input, lm, compiler_options);
@@ -927,7 +936,8 @@ EMSCRIPTEN_KEEPALIVE char* emit_asr_from_source(char *input) {
927936
auto casted_ast = (LFortran::LPython::AST::ast_t*)ast.result;
928937
LFortran::Result<LFortran::ASR::TranslationUnit_t*>
929938
asr = LFortran::LPython::python_ast_to_asr(al, *casted_ast, diagnostics, true,
930-
compiler_options.disable_main, compiler_options.symtab_only, "input");
939+
compiler_options.disable_main, compiler_options.symtab_only, "input",
940+
compiler_options.import_path);
931941
out = diagnostics.render(input, lm, compiler_options);
932942
if (asr.ok) {
933943
out += LFortran::pickle(*asr.result, compiler_options.use_colors, compiler_options.indent,
@@ -946,7 +956,8 @@ EMSCRIPTEN_KEEPALIVE char* emit_wat_from_source(char *input) {
946956
auto casted_ast = (LFortran::LPython::AST::ast_t*)ast.result;
947957
LFortran::Result<LFortran::ASR::TranslationUnit_t*>
948958
asr = LFortran::LPython::python_ast_to_asr(al, *casted_ast, diagnostics, true,
949-
compiler_options.disable_main, compiler_options.symtab_only, "input");
959+
compiler_options.disable_main, compiler_options.symtab_only, "input",
960+
compiler_options.import_path);
950961
out = diagnostics.render(input, lm, compiler_options);
951962
if (asr.ok) {
952963
LFortran::Result<LFortran::Vec<uint8_t>>
@@ -974,7 +985,8 @@ EMSCRIPTEN_KEEPALIVE char* emit_cpp_from_source(char *input) {
974985
auto casted_ast = (LFortran::LPython::AST::ast_t*)ast.result;
975986
LFortran::Result<LFortran::ASR::TranslationUnit_t*>
976987
asr = LFortran::LPython::python_ast_to_asr(al, *casted_ast, diagnostics, true,
977-
compiler_options.disable_main, compiler_options.symtab_only, "input");
988+
compiler_options.disable_main, compiler_options.symtab_only, "input",
989+
compiler_options.import_path);
978990
out = diagnostics.render(input, lm, compiler_options);
979991
if (asr.ok) {
980992
auto res = LFortran::asr_to_cpp(al, *asr.result, diagnostics,
@@ -1013,7 +1025,8 @@ EMSCRIPTEN_KEEPALIVE char* emit_wasm_from_source(char *input) {
10131025
auto casted_ast = (LFortran::LPython::AST::ast_t*)ast.result;
10141026
LFortran::Result<LFortran::ASR::TranslationUnit_t*>
10151027
asr = LFortran::LPython::python_ast_to_asr(al, *casted_ast, diagnostics, true,
1016-
compiler_options.disable_main, compiler_options.symtab_only, "input");
1028+
compiler_options.disable_main, compiler_options.symtab_only, "input",
1029+
compiler_options.import_path);
10171030
out = diagnostics.render(input, lm, compiler_options);
10181031
if (asr.ok) {
10191032
LFortran::Result<LFortran::Vec<uint8_t>>
@@ -1114,7 +1127,8 @@ int main(int argc, char *argv[])
11141127
// app.add_flag("-E", arg_E, "Preprocess only; do not compile, assemble or link");
11151128
// app.add_option("-l", arg_l, "Link library option");
11161129
// app.add_option("-L", arg_L, "Library path option");
1117-
// app.add_option("-I", arg_I, "Include path")->allow_extra_args(false);
1130+
app.add_option("-I", compiler_options.import_path, "Specify the path"
1131+
"to look for the module")->allow_extra_args(false);
11181132
// app.add_option("-J", arg_J, "Where to save mod files");
11191133
// app.add_flag("-g", arg_g, "Compile with debugging information");
11201134
// app.add_option("-D", compiler_options.c_preprocessor_defines, "Define <macro>=<value> (or 1 if <value> omitted)")->allow_extra_args(false);

src/libasr/utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ struct CompilerOptions {
3737
bool implicit_typing = false;
3838
bool implicit_interface = false;
3939
std::string target = "";
40+
std::string import_path = "";
4041
Platform platform;
4142

4243
CompilerOptions () : platform{get_platform()} {};

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <complex>
1111
#include <sstream>
1212
#include <iterator>
13+
#include <filesystem>
1314

1415
#include <libasr/asr.h>
1516
#include <libasr/asr_utils.h>
@@ -246,7 +247,7 @@ ASR::TranslationUnit_t* compile_module_till_asr(Allocator& al,
246247
LFortran::LocationManager lm;
247248
lm.in_filename = infile;
248249
Result<ASR::TranslationUnit_t*> r2 = python_ast_to_asr(al, *ast,
249-
diagnostics, false, true, false, infile);
250+
diagnostics, false, true, false, infile, "");
250251
// TODO: Uncomment once a check is added for ensuring
251252
// that module.py file hasn't changed between
252253
// builds.
@@ -287,6 +288,7 @@ ASR::Module_t* load_module(Allocator &al, SymbolTable *symtab,
287288

288289
// Parse the module `module_name`.py to AST
289290
std::string infile0 = module_name + ".py";
291+
std::string module_dir_name = "";
290292
std::string infile0c = infile0 + "c";
291293
std::string path_used = "", infile;
292294
bool compile_module = true;
@@ -309,7 +311,8 @@ ASR::Module_t* load_module(Allocator &al, SymbolTable *symtab,
309311
return nullptr;
310312
}
311313
if (!found) {
312-
err("Could not find the module '" + infile0 + "'", loc);
314+
err("Could not find the module '" + infile0 + "'. If an import path "
315+
"is available, please use the `-I` option to specify it", loc);
313316
}
314317
if (ltypes) return nullptr;
315318

@@ -319,7 +322,12 @@ ASR::Module_t* load_module(Allocator &al, SymbolTable *symtab,
319322

320323
// insert into `symtab`
321324
std::vector<std::pair<std::string, ASR::Module_t*>> children_modules;
322-
ASRUtils::extract_module_python(*mod1, children_modules, module_name);
325+
if (module_name == "__init__") {
326+
module_dir_name = rl_path[0].substr(rl_path[0].find_last_of('/') + 1);
327+
ASRUtils::extract_module_python(*mod1, children_modules, module_dir_name);
328+
} else {
329+
ASRUtils::extract_module_python(*mod1, children_modules, module_name);
330+
}
323331
ASR::Module_t* mod2 = nullptr;
324332
for( auto& a: children_modules ) {
325333
std::string a_name = a.first;
@@ -328,6 +336,10 @@ ASR::Module_t* load_module(Allocator &al, SymbolTable *symtab,
328336
a_mod->m_name = s2c(al, module_name);
329337
a_mod->m_intrinsic = intrinsic;
330338
mod2 = a_mod;
339+
} else if (a_name == module_dir_name) {
340+
a_mod->m_name = s2c(al, module_dir_name);
341+
a_mod->m_intrinsic = intrinsic;
342+
mod2 = a_mod;
331343
}
332344
symtab->add_symbol(a_name, (ASR::symbol_t*)a_mod);
333345
a_mod->m_symtab->parent = symtab;
@@ -413,9 +425,18 @@ ASR::symbol_t* import_from_module(Allocator &al, ASR::Module_t *m, SymbolTable *
413425
ASR::accessType::Public
414426
);
415427
return ASR::down_cast<ASR::symbol_t>(v);
428+
} else if (ASR::is_a<ASR::ExternalSymbol_t>(*t)) {
429+
ASR::ExternalSymbol_t *es = ASR::down_cast<ASR::ExternalSymbol_t>(t);
430+
SymbolTable *symtab = current_scope;
431+
while (symtab->parent != nullptr) symtab = symtab->parent;
432+
ASR::symbol_t *sym = symtab->get_symbol(es->m_module_name);
433+
ASR::Module_t *m = ASR::down_cast<ASR::Module_t>(sym);
434+
435+
return import_from_module(al, m, symtab, es->m_name,
436+
cur_sym_name, new_sym_name, loc);
416437
} else {
417-
throw SemanticError("Only Subroutines, Functions and Variables are currently supported in 'import'",
418-
loc);
438+
throw SemanticError("Only Subroutines, Functions and Variables"
439+
"are currently supported in 'import'", loc);
419440
}
420441
LFORTRAN_ASSERT(false);
421442
return nullptr;
@@ -452,6 +473,7 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
452473
IntrinsicNodeHandler intrinsic_node_handler;
453474
std::map<int, ASR::symbol_t*> &ast_overload;
454475
std::string parent_dir;
476+
std::string import_path;
455477
Vec<ASR::stmt_t*> *current_body;
456478
ASR::ttype_t* ann_assign_target_type;
457479

@@ -461,9 +483,10 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
461483

462484
CommonVisitor(Allocator &al, SymbolTable *symbol_table,
463485
diag::Diagnostics &diagnostics, bool main_module,
464-
std::map<int, ASR::symbol_t*> &ast_overload, std::string parent_dir)
486+
std::map<int, ASR::symbol_t*> &ast_overload, std::string parent_dir,
487+
std::string import_path)
465488
: diag{diagnostics}, al{al}, current_scope{symbol_table}, main_module{main_module},
466-
ast_overload{ast_overload}, parent_dir{parent_dir},
489+
ast_overload{ast_overload}, parent_dir{parent_dir}, import_path{import_path},
467490
current_body{nullptr}, ann_assign_target_type{nullptr} {
468491
current_module_dependencies.reserve(al, 4);
469492
}
@@ -2771,8 +2794,10 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
27712794

27722795
SymbolTableVisitor(Allocator &al, SymbolTable *symbol_table,
27732796
diag::Diagnostics &diagnostics, bool main_module,
2774-
std::map<int, ASR::symbol_t*> &ast_overload, std::string parent_dir)
2775-
: CommonVisitor(al, symbol_table, diagnostics, main_module, ast_overload, parent_dir), is_derived_type{false} {}
2797+
std::map<int, ASR::symbol_t*> &ast_overload, std::string parent_dir,
2798+
std::string import_path)
2799+
: CommonVisitor(al, symbol_table, diagnostics, main_module, ast_overload,
2800+
parent_dir, import_path), is_derived_type{false} {}
27762801

27772802

27782803
ASR::symbol_t* resolve_symbol(const Location &loc, const std::string &sub_name) {
@@ -3090,6 +3115,13 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
30903115
}
30913116
for (auto &mod_sym : mods) {
30923117
bool ltypes, enum_py;
3118+
if (!std::filesystem::exists(std::filesystem::path(paths[0]+'/'+mod_sym+".py"))
3119+
&& import_path != "") {
3120+
paths = {import_path + '/' + mod_sym};
3121+
if(std::filesystem::is_directory(std::filesystem::path(paths[0]))) {
3122+
mod_sym = "__init__";
3123+
}
3124+
}
30933125
t = (ASR::symbol_t*)(load_module(al, st,
30943126
mod_sym, x.base.base.loc, false, paths, ltypes, enum_py,
30953127
[&](const std::string &msg, const Location &loc) { throw SemanticError(msg, loc); }
@@ -3191,9 +3223,11 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
31913223

31923224
Result<ASR::asr_t*> symbol_table_visitor(Allocator &al, const AST::Module_t &ast,
31933225
diag::Diagnostics &diagnostics, bool main_module,
3194-
std::map<int, ASR::symbol_t*> &ast_overload, std::string parent_dir)
3226+
std::map<int, ASR::symbol_t*> &ast_overload, std::string parent_dir,
3227+
std::string import_path)
31953228
{
3196-
SymbolTableVisitor v(al, nullptr, diagnostics, main_module, ast_overload, parent_dir);
3229+
SymbolTableVisitor v(al, nullptr, diagnostics, main_module, ast_overload,
3230+
parent_dir, import_path);
31973231
try {
31983232
v.visit_Module(ast);
31993233
} catch (const SemanticError &e) {
@@ -3219,8 +3253,8 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
32193253

32203254
BodyVisitor(Allocator &al, ASR::asr_t *unit, diag::Diagnostics &diagnostics,
32213255
bool main_module, std::map<int, ASR::symbol_t*> &ast_overload)
3222-
: CommonVisitor(al, nullptr, diagnostics, main_module, ast_overload, ""), asr{unit},
3223-
gotoids{0}
3256+
: CommonVisitor(al, nullptr, diagnostics, main_module, ast_overload, "", ""),
3257+
asr{unit}, gotoids{0}
32243258
{}
32253259

32263260
// Transforms statements to a list of ASR statements
@@ -5277,15 +5311,16 @@ std::string get_parent_dir(const std::string &path) {
52775311

52785312
Result<ASR::TranslationUnit_t*> python_ast_to_asr(Allocator &al,
52795313
AST::ast_t &ast, diag::Diagnostics &diagnostics, bool main_module,
5280-
bool disable_main, bool symtab_only, std::string file_path)
5314+
bool disable_main, bool symtab_only, std::string file_path,
5315+
std::string import_path)
52815316
{
52825317
std::map<int, ASR::symbol_t*> ast_overload;
52835318
std::string parent_dir = get_parent_dir(file_path);
52845319
AST::Module_t *ast_m = AST::down_cast2<AST::Module_t>(&ast);
52855320

52865321
ASR::asr_t *unit;
52875322
auto res = symbol_table_visitor(al, *ast_m, diagnostics, main_module,
5288-
ast_overload, parent_dir);
5323+
ast_overload, parent_dir, import_path);
52895324
if (res.ok) {
52905325
unit = res.result;
52915326
} else {

src/lpython/semantics/python_ast_to_asr.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ namespace LFortran::LPython {
1010
std::string pickle_tree_python(AST::ast_t &ast, bool colors=true);
1111
Result<ASR::TranslationUnit_t*> python_ast_to_asr(Allocator &al,
1212
LPython::AST::ast_t &ast, diag::Diagnostics &diagnostics,
13-
bool main_module, bool disable_main, bool symtab_only, std::string file_path);
13+
bool main_module, bool disable_main, bool symtab_only, std::string file_path,
14+
std::string import_path);
1415

1516
int save_pyc_files(const LFortran::ASR::TranslationUnit_t &u,
1617
std::string infile);

0 commit comments

Comments
 (0)