@@ -254,7 +254,7 @@ ASR::TranslationUnit_t* compile_module_till_asr(Allocator& al,
254
254
LFortran::LocationManager lm;
255
255
lm.in_filename = infile;
256
256
Result<ASR::TranslationUnit_t*> r2 = python_ast_to_asr (al, *ast,
257
- diagnostics, false , true , false , infile);
257
+ diagnostics, false , true , false , infile, " " );
258
258
// TODO: Uncomment once a check is added for ensuring
259
259
// that module.py file hasn't changed between
260
260
// builds.
@@ -315,6 +315,7 @@ ASR::Module_t* load_module(Allocator &al, SymbolTable *symtab,
315
315
bool compile_module = true ;
316
316
ASR::TranslationUnit_t* mod1 = nullptr ;
317
317
std::string input;
318
+ std::string module_dir_name = " " ;
318
319
bool found = set_module_path (infile0c, rl_path, infile,
319
320
path_used, input, ltypes, enum_py);
320
321
if ( !found ) {
@@ -332,7 +333,8 @@ ASR::Module_t* load_module(Allocator &al, SymbolTable *symtab,
332
333
return nullptr ;
333
334
}
334
335
if (!found) {
335
- err (" Could not find the module '" + infile0 + " '" , loc);
336
+ err (" Could not find the module '" + infile0 + " '. If an import path "
337
+ " is available, please use the `-I` option to specify it" , loc);
336
338
}
337
339
if (ltypes) return nullptr ;
338
340
@@ -342,7 +344,15 @@ ASR::Module_t* load_module(Allocator &al, SymbolTable *symtab,
342
344
343
345
// insert into `symtab`
344
346
std::vector<std::pair<std::string, ASR::Module_t*>> children_modules;
345
- ASRUtils::extract_module_python (*mod1, children_modules, module_name);
347
+ if (module_name == " __init__" ) {
348
+ // remove `__init__.py`
349
+ module_dir_name = infile.substr (0 , infile.find_last_of (' /' ));
350
+ // assign module directory name
351
+ module_dir_name = module_dir_name.substr (module_dir_name.find_last_of (' /' ) + 1 );
352
+ ASRUtils::extract_module_python (*mod1, children_modules, module_dir_name);
353
+ } else {
354
+ ASRUtils::extract_module_python (*mod1, children_modules, module_name);
355
+ }
346
356
ASR::Module_t* mod2 = nullptr ;
347
357
for ( auto & a: children_modules ) {
348
358
std::string a_name = a.first ;
@@ -351,6 +361,10 @@ ASR::Module_t* load_module(Allocator &al, SymbolTable *symtab,
351
361
a_mod->m_name = s2c (al, module_name);
352
362
a_mod->m_intrinsic = intrinsic;
353
363
mod2 = a_mod;
364
+ } else if (a_name == module_dir_name) {
365
+ a_mod->m_name = s2c (al, module_dir_name);
366
+ a_mod->m_intrinsic = intrinsic;
367
+ mod2 = a_mod;
354
368
}
355
369
symtab->add_symbol (a_name, (ASR::symbol_t *)a_mod);
356
370
a_mod->m_symtab ->parent = symtab;
@@ -436,9 +450,18 @@ ASR::symbol_t* import_from_module(Allocator &al, ASR::Module_t *m, SymbolTable *
436
450
ASR::accessType::Public
437
451
);
438
452
return ASR::down_cast<ASR::symbol_t >(v);
453
+ } else if (ASR::is_a<ASR::ExternalSymbol_t>(*t)) {
454
+ ASR::ExternalSymbol_t *es = ASR::down_cast<ASR::ExternalSymbol_t>(t);
455
+ SymbolTable *symtab = current_scope;
456
+ while (symtab->parent != nullptr ) symtab = symtab->parent ;
457
+ ASR::symbol_t *sym = symtab->get_symbol (es->m_module_name );
458
+ ASR::Module_t *m = ASR::down_cast<ASR::Module_t>(sym);
459
+
460
+ return import_from_module (al, m, symtab, es->m_name ,
461
+ cur_sym_name, new_sym_name, loc);
439
462
} else {
440
- throw SemanticError (" Only Subroutines, Functions and Variables are currently supported in 'import' " ,
441
- loc);
463
+ throw SemanticError (" Only Subroutines, Functions, Variables and "
464
+ " ExternalSymbol are currently supported in 'import' " , loc);
442
465
}
443
466
LFORTRAN_ASSERT (false );
444
467
return nullptr ;
@@ -475,6 +498,7 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
475
498
IntrinsicNodeHandler intrinsic_node_handler;
476
499
std::map<int , ASR::symbol_t *> &ast_overload;
477
500
std::string parent_dir;
501
+ std::string import_path;
478
502
Vec<ASR::stmt_t *> *current_body;
479
503
ASR::ttype_t * ann_assign_target_type;
480
504
@@ -485,9 +509,10 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
485
509
486
510
CommonVisitor (Allocator &al, SymbolTable *symbol_table,
487
511
diag::Diagnostics &diagnostics, bool main_module,
488
- std::map<int , ASR::symbol_t *> &ast_overload, std::string parent_dir)
512
+ std::map<int , ASR::symbol_t *> &ast_overload, std::string parent_dir,
513
+ std::string import_path)
489
514
: diag{diagnostics}, al{al}, current_scope{symbol_table}, main_module{main_module},
490
- ast_overload{ast_overload}, parent_dir{parent_dir},
515
+ ast_overload{ast_overload}, parent_dir{parent_dir}, import_path{import_path},
491
516
current_body{nullptr }, ann_assign_target_type{nullptr } {
492
517
current_module_dependencies.reserve (al, 4 );
493
518
}
@@ -2912,8 +2937,10 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
2912
2937
2913
2938
SymbolTableVisitor (Allocator &al, SymbolTable *symbol_table,
2914
2939
diag::Diagnostics &diagnostics, bool main_module,
2915
- std::map<int , ASR::symbol_t *> &ast_overload, std::string parent_dir)
2916
- : CommonVisitor(al, symbol_table, diagnostics, main_module, ast_overload, parent_dir), is_derived_type{false } {}
2940
+ std::map<int , ASR::symbol_t *> &ast_overload, std::string parent_dir,
2941
+ std::string import_path)
2942
+ : CommonVisitor(al, symbol_table, diagnostics, main_module, ast_overload,
2943
+ parent_dir, import_path), is_derived_type{false } {}
2917
2944
2918
2945
2919
2946
ASR::symbol_t * resolve_symbol (const Location &loc, const std::string &sub_name) {
@@ -3206,6 +3233,24 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
3206
3233
st = st->parent ;
3207
3234
}
3208
3235
bool ltypes, enum_py;
3236
+ if (msym != " ltypes" ) {
3237
+ if (import_path != " " &&
3238
+ !path_exits (paths[0 ] + ' /' + msym + " .py" )) {
3239
+ paths = {import_path};
3240
+ if (parent_dir != " " ) paths[0 ] += ' /' + parent_dir;
3241
+ if (is_directory (paths[0 ])) {
3242
+ paths[0 ] += ' /' + msym;
3243
+ msym = " __init__" ;
3244
+ }
3245
+ } else if (is_directory (msym)) {
3246
+ paths = {rl_path, msym};
3247
+ msym = " __init__" ;
3248
+ } else if (paths[1 ] != " "
3249
+ && is_directory (paths[1 ] + ' /' + msym)) {
3250
+ paths[1 ] += ' /' + msym;
3251
+ msym = " __init__" ;
3252
+ }
3253
+ }
3209
3254
t = (ASR::symbol_t *)(load_module (al, st,
3210
3255
msym, x.base .base .loc , false , paths, ltypes, enum_py,
3211
3256
[&](const std::string &msg, const Location &loc) { throw SemanticError (msg, loc); }
@@ -3251,6 +3296,24 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
3251
3296
}
3252
3297
for (auto &mod_sym : mods) {
3253
3298
bool ltypes, enum_py;
3299
+ if (mod_sym != " ltypes" ) {
3300
+ if (import_path != " " &&
3301
+ !path_exits (paths[0 ] + ' /' + mod_sym + " .py" )) {
3302
+ paths = {import_path};
3303
+ if (parent_dir != " " ) paths[0 ] += ' /' + parent_dir;
3304
+ if (is_directory (paths[0 ])) {
3305
+ paths[0 ] += ' /' + mod_sym;
3306
+ mod_sym = " __init__" ;
3307
+ }
3308
+ } else if (is_directory (mod_sym)) {
3309
+ paths = {rl_path, mod_sym};
3310
+ mod_sym = " __init__" ;
3311
+ } else if (paths[1 ] != " "
3312
+ && is_directory (paths[1 ] + ' /' + mod_sym)) {
3313
+ paths[1 ] += ' /' + mod_sym;
3314
+ mod_sym = " __init__" ;
3315
+ }
3316
+ }
3254
3317
t = (ASR::symbol_t *)(load_module (al, st,
3255
3318
mod_sym, x.base .base .loc , false , paths, ltypes, enum_py,
3256
3319
[&](const std::string &msg, const Location &loc) { throw SemanticError (msg, loc); }
@@ -3355,9 +3418,11 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
3355
3418
3356
3419
Result<ASR::asr_t *> symbol_table_visitor (Allocator &al, const AST::Module_t &ast,
3357
3420
diag::Diagnostics &diagnostics, bool main_module,
3358
- std::map<int , ASR::symbol_t *> &ast_overload, std::string parent_dir)
3421
+ std::map<int , ASR::symbol_t *> &ast_overload, std::string parent_dir,
3422
+ std::string import_path)
3359
3423
{
3360
- SymbolTableVisitor v (al, nullptr , diagnostics, main_module, ast_overload, parent_dir);
3424
+ SymbolTableVisitor v (al, nullptr , diagnostics, main_module, ast_overload,
3425
+ parent_dir, import_path);
3361
3426
try {
3362
3427
v.visit_Module (ast);
3363
3428
} catch (const SemanticError &e) {
@@ -3383,8 +3448,8 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
3383
3448
3384
3449
BodyVisitor (Allocator &al, ASR::asr_t *unit, diag::Diagnostics &diagnostics,
3385
3450
bool main_module, std::map<int , ASR::symbol_t *> &ast_overload)
3386
- : CommonVisitor(al, nullptr , diagnostics, main_module, ast_overload, " " ), asr{unit} ,
3387
- gotoids{0 }
3451
+ : CommonVisitor(al, nullptr , diagnostics, main_module, ast_overload, " " , " " ) ,
3452
+ asr{unit}, gotoids{0 }
3388
3453
{}
3389
3454
3390
3455
// Transforms statements to a list of ASR statements
@@ -5524,15 +5589,16 @@ std::string get_parent_dir(const std::string &path) {
5524
5589
5525
5590
Result<ASR::TranslationUnit_t*> python_ast_to_asr (Allocator &al,
5526
5591
AST::ast_t &ast, diag::Diagnostics &diagnostics, bool main_module,
5527
- bool disable_main, bool symtab_only, std::string file_path)
5592
+ bool disable_main, bool symtab_only, std::string file_path,
5593
+ std::string import_path)
5528
5594
{
5529
5595
std::map<int , ASR::symbol_t *> ast_overload;
5530
5596
std::string parent_dir = get_parent_dir (file_path);
5531
5597
AST::Module_t *ast_m = AST::down_cast2<AST::Module_t>(&ast);
5532
5598
5533
5599
ASR::asr_t *unit;
5534
5600
auto res = symbol_table_visitor (al, *ast_m, diagnostics, main_module,
5535
- ast_overload, parent_dir);
5601
+ ast_overload, parent_dir, import_path );
5536
5602
if (res.ok ) {
5537
5603
unit = res.result ;
5538
5604
} else {
0 commit comments