From fe3847d69c0876e5ce5c26871afd7cd03f320272 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Sun, 16 Jul 2023 21:31:51 +0800 Subject: [PATCH] :sparkles: add experimental namespace table --- src/main.cpp | 20 +++- src/nasal_codegen.cpp | 8 +- src/nasal_codegen.h | 13 ++- src/nasal_err.cpp | 3 +- src/nasal_gc.cpp | 19 +++- src/nasal_gc.h | 11 +-- src/nasal_vm.cpp | 207 ++++++++++++++++++++++-------------------- src/symbol_finder.cpp | 16 +++- src/symbol_finder.h | 10 +- test/globals_test.nas | 3 +- 10 files changed, 185 insertions(+), 125 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 7d9b8fa..62920f8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,9 +23,11 @@ const u32 VM_TIME = 1<<3; const u32 VM_EXEC = 1<<4; const u32 VM_DETAIL = 1<<5; const u32 VM_DEBUG = 1<<6; +const u32 VM_SYMINFO = 1<<7; std::ostream& help(std::ostream& out) { out + << "\n" << " ,--#-,\n" << "<3 / \\____\\ <3\n" << " |_|__A_|\n" @@ -41,6 +43,7 @@ std::ostream& help(std::ostream& out) { << " -a, --ast | view ast after link/optimize process.\n" << " --raw-ast | view ast without after-processing.\n" << " -c, --code | view generated bytecode.\n" + << " -s, --symbol | show analysed symbol info.\n" << " -e, --exec | execute directly.\n" << " -t, --time | show execute time.\n" << " -d, --detail | get detail info.\n" @@ -48,12 +51,14 @@ std::ostream& help(std::ostream& out) { << "file:\n" << " | execute file.\n" << "argv:\n" - << " | cmd arguments used in program.\n"; + << " | cmd arguments used in program.\n" + << "\n"; return out; } std::ostream& logo(std::ostream& out) { out + << "\n" << " __ _\n" << " /\\ \\ \\__ _ ___ __ _| |\n" << " / \\/ / _` / __|/ _` | |\n" @@ -65,7 +70,8 @@ std::ostream& logo(std::ostream& out) { << "repo : https://github.com/ValKmjolnir/Nasal-Interpreter\n" << "repo : https://gitee.com/valkmjolnir/Nasal-Interpreter\n" << "wiki : https://wiki.flightgear.org/Nasal_scripting_language\n" - << "input to get help .\n"; + << "\n" + << "input to get help .\n\n"; return out; } @@ -133,6 +139,14 @@ void execute( if (cmd&VM_CODE) { gen.print(std::cout); } + if (cmd&VM_SYMINFO) { + for(const auto& domain : gen.get_experimental_namespace()) { + std::cout << domain.first << ":\n"; + for(const auto& i : domain.second) { + std::cout << " [" << domain.first << "]@" << i << "\n"; + } + } + } // run auto start = clk::now(); @@ -178,6 +192,8 @@ i32 main(i32 argc, const char* argv[]) { {"-a", VM_AST}, {"--code", VM_CODE}, {"-c", VM_CODE}, + {"--symbol", VM_SYMINFO}, + {"-s", VM_SYMINFO}, {"--exec", VM_EXEC}, {"-e", VM_EXEC}, {"--time", VM_TIME|VM_EXEC}, diff --git a/src/nasal_codegen.cpp b/src/nasal_codegen.cpp index 730b705..a98d433 100644 --- a/src/nasal_codegen.cpp +++ b/src/nasal_codegen.cpp @@ -47,7 +47,13 @@ void codegen::regist_str(const std::string& str) { void codegen::find_symbol(code_block* node) { auto finder = std::unique_ptr(new symbol_finder); for(const auto& i : finder->do_find(node)) { - add_symbol(i); + if (!experimental_namespace.count(i.file)) { + experimental_namespace[i.file] = {}; + } + if (local.empty() && !experimental_namespace.at(i.file).count(i.name)) { + experimental_namespace.at(i.file).insert(i.name); + } + add_symbol(i.name); } } diff --git a/src/nasal_codegen.h b/src/nasal_codegen.h index 706d0c2..ba13c4f 100644 --- a/src/nasal_codegen.h +++ b/src/nasal_codegen.h @@ -13,6 +13,7 @@ #include #include #include +#include #ifdef _MSC_VER #pragma warning (disable:4244) @@ -36,6 +37,7 @@ private: // symbol table // global : max STACK_DEPTH-1 values std::unordered_map global; + std::unordered_map> experimental_namespace; // local : max 32768 upvalues 65536 values // but in fact local scope also has less than STACK_DEPTH value std::list> local; @@ -94,10 +96,13 @@ private: void ret_gen(return_expr*); public: - const std::vector& strs() const {return const_string_table;} - const std::vector& nums() const {return const_number_table;} - const std::vector& codes() const {return code;} - const std::unordered_map& globals() const {return global;} + const auto& strs() const {return const_string_table;} + const auto& nums() const {return const_number_table;} + const auto& codes() const {return code;} + const auto& globals() const {return global;} + const auto& get_experimental_namespace() const { + return experimental_namespace; + } public: codegen(error& e): fileindex(0), err(e), file(nullptr) {} diff --git a/src/nasal_err.cpp b/src/nasal_err.cpp index 7152c55..02cd20f 100644 --- a/src/nasal_err.cpp +++ b/src/nasal_err.cpp @@ -56,7 +56,8 @@ std::ostream& white(std::ostream& s) { std::ostream& reset(std::ostream& s) { #ifdef _WIN32 - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), reset_ter_color.scr.wAttributes); + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), + reset_ter_color.scr.wAttributes); #else s << "\033[0m"; #endif diff --git a/src/nasal_gc.cpp b/src/nasal_gc.cpp index d828442..6498ee3 100644 --- a/src/nasal_gc.cpp +++ b/src/nasal_gc.cpp @@ -137,6 +137,12 @@ void nas_ghost::clear() { ptr = nullptr; } +std::ostream& operator<<(std::ostream& out, const nas_ghost& ghost) { + out << ""; + return out; +} + void nas_co::clear() { for(u32 i = 0; i"; + return out; +} + var nas_map::get_val(const std::string& key) { if (mapper.count(key)) { return *mapper.at(key); @@ -251,7 +262,7 @@ std::ostream& operator<<(std::ostream& out, var& ref) { case vm_hash: out << ref.hash(); break; case vm_func: out << "func(..) {..}"; break; case vm_obj: out << ref.obj(); break; - case vm_co: out << ""; break; + case vm_co: out << ref.co(); break; case vm_map: out << ref.map(); break; } return out; @@ -356,8 +367,8 @@ void gc::do_mark_sweep() { void gc::mark() { std::vector bfs; - mark_context(bfs); - if (memory.size()>1048576 && bfs.size()>4) { + mark_context_root(bfs); + if (memory.size()>8192 && bfs.size()>4) { usize size = bfs.size(); std::thread t0(&gc::concurrent_mark, this, std::ref(bfs), 0, size/4); std::thread t1(&gc::concurrent_mark, this, std::ref(bfs), size/4, size/2); @@ -402,7 +413,7 @@ void gc::concurrent_mark(std::vector& vec, usize begin, usize end) { } } -void gc::mark_context(std::vector& bfs_queue) { +void gc::mark_context_root(std::vector& bfs_queue) { // scan now running context, this context maybe related to coroutine or main for(var* i = rctx->stack; i<=rctx->top; ++i) { diff --git a/src/nasal_gc.h b/src/nasal_gc.h index 191ac8f..ec4f2ed 100644 --- a/src/nasal_gc.h +++ b/src/nasal_gc.h @@ -101,7 +101,6 @@ public: bool operator!=(const var& nr) const { return type!=nr.type || val.gcobj!=nr.val.gcobj; } - friend std::ostream& operator<<(std::ostream&, var&); // number and string can be translated to each other f64 tonum(); @@ -267,12 +266,6 @@ public: void clear(); public: - friend std::ostream& operator<<(std::ostream& out, nas_ghost& ghost) { - out << "get_ghost_name(ghost.type); - out << " at 0x" << std::hex << (u64)ghost.ptr << std::dec << ">"; - return out; - } - const std::string& get_ghost_name() const { return ghost_type_table->get_ghost_name(type); } @@ -334,6 +327,8 @@ struct nas_val { std::ostream& operator<<(std::ostream&, nas_vec&); std::ostream& operator<<(std::ostream&, nas_hash&); std::ostream& operator<<(std::ostream&, nas_map&); +std::ostream& operator<<(std::ostream&, const nas_ghost&); +std::ostream& operator<<(std::ostream&, const nas_co&); std::ostream& operator<<(std::ostream&, var&); const var zero = var::num(0); @@ -386,7 +381,7 @@ private: void do_mark_sweep(); void mark(); void concurrent_mark(std::vector&, usize, usize); - void mark_context(std::vector&); + void mark_context_root(std::vector&); void mark_var(std::vector&, var&); void mark_vec(std::vector&, nas_vec&); void mark_hash(std::vector&, nas_hash&); diff --git a/src/nasal_vm.cpp b/src/nasal_vm.cpp index 11057ee..dcf00ee 100644 --- a/src/nasal_vm.cpp +++ b/src/nasal_vm.cpp @@ -47,108 +47,117 @@ void vm::init( void vm::valinfo(var& val) { const nas_val* p = val.val.gcobj; switch(val.type) { - case vm_none: std::clog<<"| null |";break; - case vm_ret: std::clog<<"| pc | 0x"< "< entry:0x"< ["< ["< {"< obj:0x"<<(u64)val.obj().ptr - < coroutine";break; - default: std::clog<<"| err | <0x"< unknown object";break; + case vm_none: std::clog << "| null |"; break; + case vm_ret: std::clog << "| pc | 0x" << std::hex + << val.ret() << std::dec; break; + case vm_addr: std::clog << "| addr | 0x" << std::hex + << (u64)val.addr() << std::dec; break; + case vm_cnt: std::clog << "| cnt | " << val.cnt(); break; + case vm_nil: std::clog << "| nil |"; break; + case vm_num: std::clog << "| num | " << val.num(); break; + case vm_str: std::clog << "| str | <0x" << std::hex << (u64)p + << "> " << rawstr(val.str(), 16) + << std::dec; break; + case vm_func: std::clog << "| func | <0x" << std::hex << (u64)p + << "> entry:0x" << val.func().entry + << std::dec; break; + case vm_upval:std::clog << "| upval| <0x" << std::hex << (u64)p + << std::dec << "> [" << val.upval().size + << " val]"; break; + case vm_vec: std::clog << "| vec | <0x" << std::hex << (u64)p + << std::dec << "> [" << val.vec().size() + << " val]"; break; + case vm_hash: std::clog << "| hash | <0x" << std::hex << (u64)p + << std::dec << "> {" << val.hash().size() + << " val}"; break; + case vm_obj: std::clog << "| obj | <0x" << std::hex << (u64)p + << "> obj:0x" << (u64)val.obj().ptr + << std::dec; break; + case vm_co: std::clog << "| co | <0x" << std::hex << (u64)p + << std::dec << "> coroutine"; break; + case vm_map: std::clog << "| nmspc| <0x" << std::hex << (u64)p + << std::dec << "> namespace [" + << val.map().mapper.size() << " val]"; break; + default: std::clog << "| err | <0x" << std::hex << (u64)p + << std::dec << "> unknown object"; break; } - std::clog<<"\n"; + std::clog << "\n"; } void vm::traceback() { /* bytecode[0].num is the global size */ - var* bottom=ngc.rctx->stack==stack?stack+bytecode[0].num:ngc.rctx->stack; - var* ctx_top=ngc.rctx->stack==stack?ctx.top:ngc.rctx->top; + var* bottom = ngc.rctx->stack==stack? stack+bytecode[0].num:ngc.rctx->stack; + var* ctx_top = ngc.rctx->stack==stack? ctx.top:ngc.rctx->top; std::stack ret; - for(var* i=bottom;i<=ctx_top;++i) { + for(var* i = bottom; i<=ctx_top; ++i) { if (i->type==vm_ret && i->ret()!=0) { ret.push(i->ret()); } } ret.push(ctx.pc); // store the position program crashed - std::clog<<"trace back ("<<(ngc.rctx->stack==stack?"main":"coroutine")<<")\n"; + std::clog << "trace back (" + << (ngc.rctx->stack==stack? "main":"coroutine") + << ")\n"; codestream::set(cnum, cstr, files); - for(u32 p=0,same=0,prev=0xffffffff;!ret.empty();prev=p,ret.pop()) { - if ((p=ret.top())==prev) { + for(u32 p = 0, same = 0, prev = 0xffffffff; !ret.empty(); prev = p, ret.pop()) { + if ((p = ret.top())==prev) { ++same; continue; } if (same) { - std::clog - <<" 0x"<stack==stack?bytecode[0].num:0; - var* t=ctx.top; - var* bottom=ngc.rctx->stack+gsize; - std::clog<<"stack (0x"<, limit "<=bottom;++i,--t) { - std::clog<<" 0x"<stack)<stack==stack? bytecode[0].num:0; + var* t = ctx.top; + var* bottom = ngc.rctx->stack+gsize; + std::clog << "stack (0x" << std::hex << (u64)bottom << std::dec; + std::clog << " <+" << gsize << ">, limit " << limit << ", total "; + std::clog << (t=bottom; ++i, --t) { + std::clog << " 0x" << std::hex + << std::setw(6) << std::setfill('0') + << (u64)(t-ngc.rctx->stack) << std::dec + << " "; valinfo(t[0]); } } void vm::reginfo() { - std::clog<<"registers ("<<(ngc.cort?"coroutine":"main")<<")\n"<)\n"<)\n" << std::dec; + for(u32 i = 0; istack)<<">)\n"<stack) + << ">)\n" << std::dec; + for(u32 i = 0; i upval["< upval[" << i << "]:\n"; + auto& uv = upval[i].upval(); + for(u32 j = 0; jstack==stack) { // in main context, exit directly + if (ngc.rctx->stack==stack) { + // in main context, exit directly std::exit(1); } else { // in coroutine, shut down the coroutine and return to main context - ctx.pc=0; // mark coroutine 'dead' - ngc.ctxreserve(); - ctx.top[0]=nil; + ctx.pc = 0; // mark coroutine 'dead' + ngc.ctxreserve(); // switch context to main + ctx.top[0] = nil; // generate return value 'nil' } } @@ -217,9 +228,8 @@ void vm::run( const codegen& gen, const linker& linker, const std::vector& argv, - const bool detail -) { - verbose=detail; + const bool detail) { + verbose = detail; init(gen.strs(), gen.nums(), gen.codes(), @@ -227,7 +237,8 @@ void vm::run( linker.filelist(), argv); #ifndef _MSC_VER - const void* oprs[]={ + // using labels as values/computed goto + const void* oprs[] = { &&vmexit, &&intg, &&intl, &&loadg, &&loadl, &&loadu, &&pnum, &&pnil, &&pstr, &&newv, &&newh, &&newf, @@ -252,7 +263,7 @@ void vm::run( &&mcallv, &&mcallh, &&ret }; std::vector code; - for(auto& i:gen.codes()) { + for(auto& i : gen.codes()) { code.push_back(oprs[i.op]); imm.push_back(i.num); } @@ -260,7 +271,7 @@ void vm::run( goto *code[ctx.pc]; #else typedef void (vm::*nafunc)(); - const nafunc oprs[]={ + const nafunc oprs[] = { nullptr, &vm::o_intg, &vm::o_intl, &vm::o_loadg, &vm::o_loadl, &vm::o_loadu, @@ -307,7 +318,7 @@ void vm::run( &vm::o_ret }; std::vector code; - for(auto& i:gen.codes()) { + for(auto& i : gen.codes()) { code.push_back(oprs[i.op]); imm.push_back(i.num); } diff --git a/src/symbol_finder.cpp b/src/symbol_finder.cpp index 275dcfc..58a84fe 100644 --- a/src/symbol_finder.cpp +++ b/src/symbol_finder.cpp @@ -2,10 +2,16 @@ bool symbol_finder::visit_definition_expr(definition_expr* node) { if (node->get_variable_name()) { - symbols.push_back(node->get_variable_name()->get_name()); + symbols.push_back({ + node->get_variable_name()->get_name(), + node->get_variable_name()->get_location().file + }); } else { for(auto i : node->get_variables()->get_variables()) { - symbols.push_back(i->get_name()); + symbols.push_back({ + i->get_name(), + i->get_location().file + }); } } if (node->get_tuple()) { @@ -22,12 +28,14 @@ bool symbol_finder::visit_function(function* node) { bool symbol_finder::visit_iter_expr(iter_expr* node) { if (node->get_name()) { - symbols.push_back(node->get_name()->get_name()); + symbols.push_back({ + node->get_name()->get_name(), + node->get_name()->get_location().file}); } return true; } -const std::vector& symbol_finder::do_find(code_block* root) { +const std::vector& symbol_finder::do_find(code_block* root) { symbols.clear(); root->accept(this); return symbols; diff --git a/src/symbol_finder.h b/src/symbol_finder.h index 33410d3..a0eb852 100644 --- a/src/symbol_finder.h +++ b/src/symbol_finder.h @@ -8,12 +8,18 @@ #include class symbol_finder:public ast_visitor { +public: + struct symbol_info { + std::string name; + std::string file; + }; + private: - std::vector symbols; + std::vector symbols; public: bool visit_definition_expr(definition_expr*) override; bool visit_function(function*) override; bool visit_iter_expr(iter_expr*) override; - const std::vector& do_find(code_block*); + const std::vector& do_find(code_block*); }; \ No newline at end of file diff --git a/test/globals_test.nas b/test/globals_test.nas index 3016cda..ea5010f 100644 --- a/test/globals_test.nas +++ b/test/globals_test.nas @@ -34,4 +34,5 @@ b(1, 2, 3, 4); # 1 [2 3 4] # command line arguments println(arg); -println(globals.arg); \ No newline at end of file +println(globals.arg); +println(typeof(globals)); \ No newline at end of file