⚡ 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;
|
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) {
|
void linker::link(code_block* new_tree_root, code_block* old_tree_root) {
|
||||||
// add children of add_root to the back of root
|
// add children of add_root to the back of root
|
||||||
for(auto& i : old_tree_root->get_expressions()) {
|
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
|
// avoid infinite loading loop
|
||||||
filename = find_file(filename, node->get_location());
|
filename = find_file(filename, node->get_location());
|
||||||
if (!filename.length() || exist(filename)) {
|
if (!filename.length()) {
|
||||||
return new code_block({0, 0, 0, 0, filename});
|
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...
|
// start importing...
|
||||||
if (lex.scan(filename).geterr()) {
|
if (lex.scan(filename).geterr()) {
|
||||||
err.err("link", "error occurred when analysing <" + filename + ">");
|
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);
|
auto tmp = par.swap(nullptr);
|
||||||
|
|
||||||
// check if tmp has 'import'
|
// 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() {
|
code_block* linker::import_nasal_lib() {
|
||||||
|
@ -186,7 +232,7 @@ code_block* linker::import_nasal_lib() {
|
||||||
}
|
}
|
||||||
lib_path = filename;
|
lib_path = filename;
|
||||||
|
|
||||||
// avoid infinite loading loop
|
// avoid infinite loading library
|
||||||
if (exist(filename)) {
|
if (exist(filename)) {
|
||||||
return new code_block({0, 0, 0, 0, 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);
|
auto tmp = par.swap(nullptr);
|
||||||
|
|
||||||
// check if tmp has 'import'
|
// 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) {
|
std::string linker::generate_module_name(const std::string& filename) {
|
||||||
|
@ -294,6 +340,7 @@ const error& linker::link(
|
||||||
// initializing
|
// initializing
|
||||||
this_file = self;
|
this_file = self;
|
||||||
files = {self};
|
files = {self};
|
||||||
|
module_load_stack = {self};
|
||||||
// scan root and import files
|
// scan root and import files
|
||||||
// then generate a new ast and return to import_ast
|
// then generate a new ast and return to import_ast
|
||||||
// the main file's index is 0
|
// the main file's index is 0
|
||||||
|
|
|
@ -28,10 +28,14 @@ private:
|
||||||
std::string lib_path;
|
std::string lib_path;
|
||||||
error err;
|
error err;
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
|
std::vector<std::string> module_load_stack;
|
||||||
std::vector<std::string> envpath;
|
std::vector<std::string> envpath;
|
||||||
|
|
||||||
bool import_check(expr*);
|
bool import_check(expr*);
|
||||||
bool exist(const std::string&);
|
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*);
|
void link(code_block*, code_block*);
|
||||||
std::string get_path(call_expr*);
|
std::string get_path(call_expr*);
|
||||||
std::string find_file(const std::string&, const span&);
|
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