⚡ add check for self-imported module
This commit is contained in:
parent
569d423772
commit
fe65085a7a
|
@ -135,6 +135,43 @@ bool linker::exist(const std::string& file) {
|
|||
return false;
|
||||
}
|
||||
|
||||
u16 linker::find(const std::string& file) {
|
||||
for(usize i = 0; i<files.size(); ++i) {
|
||||
if (files[i]==file) {
|
||||
return static_cast<u16>(i);
|
||||
}
|
||||
}
|
||||
std::cerr << "unreachable: using this method incorrectly\n";
|
||||
std::exit(-1);
|
||||
return UINT16_MAX;
|
||||
}
|
||||
|
||||
bool linker::check_self_import(const std::string& file) {
|
||||
for(const auto& i : module_load_stack) {
|
||||
if (file==i) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string linker::generate_self_import_path() {
|
||||
std::string res = "";
|
||||
usize size = module_load_stack.size();
|
||||
if (!size) {
|
||||
return res;
|
||||
}
|
||||
usize count = 0;
|
||||
for(const auto& i : module_load_stack) {
|
||||
res += "<" + i + ">";
|
||||
if (count!=size-1) {
|
||||
res += " -> ";
|
||||
}
|
||||
++count;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void linker::link(code_block* new_tree_root, code_block* old_tree_root) {
|
||||
// add children of add_root to the back of root
|
||||
for(auto& i : old_tree_root->get_expressions()) {
|
||||
|
@ -160,10 +197,17 @@ code_block* linker::import_regular_file(call_expr* node) {
|
|||
|
||||
// avoid infinite loading loop
|
||||
filename = find_file(filename, node->get_location());
|
||||
if (!filename.length() || exist(filename)) {
|
||||
if (!filename.length()) {
|
||||
return new code_block({0, 0, 0, 0, filename});
|
||||
}
|
||||
if (check_self_import(filename)) {
|
||||
err.err("link", "self-referenced module <" + filename + ">\n" +
|
||||
" reference path: " + generate_self_import_path());
|
||||
return new code_block({0, 0, 0, 0, filename});
|
||||
}
|
||||
exist(filename);
|
||||
|
||||
module_load_stack.push_back(filename);
|
||||
// start importing...
|
||||
if (lex.scan(filename).geterr()) {
|
||||
err.err("link", "error occurred when analysing <" + filename + ">");
|
||||
|
@ -174,7 +218,9 @@ code_block* linker::import_regular_file(call_expr* node) {
|
|||
auto tmp = par.swap(nullptr);
|
||||
|
||||
// check if tmp has 'import'
|
||||
return load(tmp, files.size()-1);
|
||||
auto res = load(tmp, find(filename));
|
||||
module_load_stack.pop_back();
|
||||
return res;
|
||||
}
|
||||
|
||||
code_block* linker::import_nasal_lib() {
|
||||
|
@ -186,7 +232,7 @@ code_block* linker::import_nasal_lib() {
|
|||
}
|
||||
lib_path = filename;
|
||||
|
||||
// avoid infinite loading loop
|
||||
// avoid infinite loading library
|
||||
if (exist(filename)) {
|
||||
return new code_block({0, 0, 0, 0, filename});
|
||||
}
|
||||
|
@ -201,7 +247,7 @@ code_block* linker::import_nasal_lib() {
|
|||
auto tmp = par.swap(nullptr);
|
||||
|
||||
// check if tmp has 'import'
|
||||
return load(tmp, files.size()-1);
|
||||
return load(tmp, find(filename));
|
||||
}
|
||||
|
||||
std::string linker::generate_module_name(const std::string& filename) {
|
||||
|
@ -294,6 +340,7 @@ const error& linker::link(
|
|||
// initializing
|
||||
this_file = self;
|
||||
files = {self};
|
||||
module_load_stack = {self};
|
||||
// scan root and import files
|
||||
// then generate a new ast and return to import_ast
|
||||
// the main file's index is 0
|
||||
|
|
|
@ -28,10 +28,14 @@ private:
|
|||
std::string lib_path;
|
||||
error err;
|
||||
std::vector<std::string> files;
|
||||
std::vector<std::string> module_load_stack;
|
||||
std::vector<std::string> envpath;
|
||||
|
||||
bool import_check(expr*);
|
||||
bool exist(const std::string&);
|
||||
u16 find(const std::string&);
|
||||
bool check_self_import(const std::string&);
|
||||
std::string generate_self_import_path();
|
||||
void link(code_block*, code_block*);
|
||||
std::string get_path(call_expr*);
|
||||
std::string find_file(const std::string&, const span&);
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# this will cause error
|
||||
# import.b;
|
||||
|
||||
println("init a");
|
||||
var a = "hello";
|
|
@ -0,0 +1,3 @@
|
|||
import.a;
|
||||
|
||||
println("init b");
|
|
@ -0,0 +1,3 @@
|
|||
import.b;
|
||||
|
||||
println("init c");
|
|
@ -0,0 +1,12 @@
|
|||
import.c;
|
||||
import.a;
|
||||
import.b;
|
||||
|
||||
println(a);
|
||||
println(b);
|
||||
println(c);
|
||||
|
||||
|
||||
println(id(a));
|
||||
println(id(b), " ", id(b.a));
|
||||
println(id(c), " ", id(c.b), " ", id(c.b.a));
|
Loading…
Reference in New Issue