✨ add experimental namespace table
This commit is contained in:
parent
eee30b7d8e
commit
fe3847d69c
20
src/main.cpp
20
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"
|
||||
<< " <filename> | execute file.\n"
|
||||
<< "argv:\n"
|
||||
<< " <args> | cmd arguments used in program.\n";
|
||||
<< " <args> | 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 <nasal -h> to get help .\n";
|
||||
<< "\n"
|
||||
<< "input <nasal -h> 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},
|
||||
|
|
|
@ -47,7 +47,13 @@ void codegen::regist_str(const std::string& str) {
|
|||
void codegen::find_symbol(code_block* node) {
|
||||
auto finder = std::unique_ptr<symbol_finder>(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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <list>
|
||||
#include <stack>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable:4244)
|
||||
|
@ -36,6 +37,7 @@ private:
|
|||
// symbol table
|
||||
// global : max STACK_DEPTH-1 values
|
||||
std::unordered_map<std::string, i32> global;
|
||||
std::unordered_map<std::string, std::unordered_set<std::string>> experimental_namespace;
|
||||
// local : max 32768 upvalues 65536 values
|
||||
// but in fact local scope also has less than STACK_DEPTH value
|
||||
std::list<std::unordered_map<std::string, i32>> local;
|
||||
|
@ -94,10 +96,13 @@ private:
|
|||
void ret_gen(return_expr*);
|
||||
|
||||
public:
|
||||
const std::vector<std::string>& strs() const {return const_string_table;}
|
||||
const std::vector<f64>& nums() const {return const_number_table;}
|
||||
const std::vector<opcode>& codes() const {return code;}
|
||||
const std::unordered_map<std::string, i32>& 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) {}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -137,6 +137,12 @@ void nas_ghost::clear() {
|
|||
ptr = nullptr;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const nas_ghost& ghost) {
|
||||
out << "<object " << ghost.get_ghost_name();
|
||||
out << " at 0x" << std::hex << (u64)ghost.ptr << std::dec << ">";
|
||||
return out;
|
||||
}
|
||||
|
||||
void nas_co::clear() {
|
||||
for(u32 i = 0; i<STACK_DEPTH; ++i) {
|
||||
stack[i] = var::nil();
|
||||
|
@ -153,6 +159,11 @@ void nas_co::clear() {
|
|||
status = coroutine_status::suspended;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const nas_co& co) {
|
||||
out << "<coroutine at 0x" << std::hex << u64(&co) << std::dec << ">";
|
||||
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 << "<coroutine>"; 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<var> 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<var>& vec, usize begin, usize end) {
|
|||
}
|
||||
}
|
||||
|
||||
void gc::mark_context(std::vector<var>& bfs_queue) {
|
||||
void gc::mark_context_root(std::vector<var>& bfs_queue) {
|
||||
|
||||
// scan now running context, this context maybe related to coroutine or main
|
||||
for(var* i = rctx->stack; i<=rctx->top; ++i) {
|
||||
|
|
|
@ -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 << "<object " << ghost.ghost_type_table->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<var>&, usize, usize);
|
||||
void mark_context(std::vector<var>&);
|
||||
void mark_context_root(std::vector<var>&);
|
||||
void mark_var(std::vector<var>&, var&);
|
||||
void mark_vec(std::vector<var>&, nas_vec&);
|
||||
void mark_hash(std::vector<var>&, nas_hash&);
|
||||
|
|
207
src/nasal_vm.cpp
207
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"<<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;
|
||||
default: std::clog<<"| err | <0x"<<std::hex<<(u64)p
|
||||
<<std::dec<<"> 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<u32> 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"<<std::hex<<std::setw(6)<<std::setfill('0')
|
||||
<<prev<<std::dec<<" "<<same<<" same call(s)\n";
|
||||
std::clog << " 0x" << std::hex
|
||||
<< std::setw(6) << std::setfill('0')
|
||||
<< prev << std::dec << " "
|
||||
<< same << " same call(s)\n";
|
||||
}
|
||||
same=0;
|
||||
std::clog<<" "<<codestream(bytecode[p],p)<<"\n";
|
||||
same = 0;
|
||||
std::clog << " " << codestream(bytecode[p], p) << "\n";
|
||||
}
|
||||
// the first called place has no same calls
|
||||
}
|
||||
|
||||
void vm::stackinfo(const u32 limit=10) {
|
||||
void vm::stackinfo(const u32 limit = 10) {
|
||||
/* bytecode[0].num is the global size */
|
||||
const u32 gsize=ngc.rctx->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
|
||||
<<" <+"<<gsize<<">, limit "<<limit<<", total "
|
||||
<<(t<bottom? 0:(i64)(t-bottom+1))<<")\n";
|
||||
for(u32 i=0;i<limit && t>=bottom;++i,--t) {
|
||||
std::clog<<" 0x"<<std::hex
|
||||
<<std::setw(6)<<std::setfill('0')
|
||||
<<(u64)(t-ngc.rctx->stack)<<std::dec
|
||||
<<" ";
|
||||
const u32 gsize = ngc.rctx->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? 0:(i64)(t-bottom+1)) << ")\n";
|
||||
for(u32 i = 0; i<limit && 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"<<std::hex
|
||||
<<" [pc ] | pc | 0x"<<ctx.pc<<"\n"
|
||||
<<" [global] | addr | 0x"<<(u64)stack<<"\n"
|
||||
<<" [local ] | addr | 0x"<<(u64)ctx.localr<<"\n"
|
||||
<<" [memr ] | addr | 0x"<<(u64)ctx.memr<<"\n"
|
||||
<<" [canary] | addr | 0x"<<(u64)ctx.canary<<"\n"
|
||||
<<" [top ] | addr | 0x"<<(u64)ctx.top<<"\n"
|
||||
<<std::dec;
|
||||
std::clog<<" [funcr ] ";valinfo(ctx.funcr);
|
||||
std::clog<<" [upval ] ";valinfo(ctx.upvalr);
|
||||
std::clog << "registers (" << (ngc.cort? "coroutine":"main")
|
||||
<< ")\n" << std::hex
|
||||
<< " [pc ] | pc | 0x" << ctx.pc << "\n"
|
||||
<< " [global] | addr | 0x" << (u64)stack << "\n"
|
||||
<< " [local ] | addr | 0x" << (u64)ctx.localr << "\n"
|
||||
<< " [memr ] | addr | 0x" << (u64)ctx.memr << "\n"
|
||||
<< " [canary] | addr | 0x" << (u64)ctx.canary << "\n"
|
||||
<< " [top ] | addr | 0x" << (u64)ctx.top << "\n"
|
||||
<< std::dec;
|
||||
std::clog << " [funcr ] "; valinfo(ctx.funcr);
|
||||
std::clog << " [upval ] "; valinfo(ctx.upvalr);
|
||||
}
|
||||
|
||||
void vm::gstate() {
|
||||
if (!bytecode[0].num || stack[0].type==vm_none) { // bytecode[0].op is op_intg
|
||||
// bytecode[0].op is op_intg
|
||||
if (!bytecode[0].num || stack[0].type==vm_none) {
|
||||
return;
|
||||
}
|
||||
std::clog<<"global (0x"<<std::hex<<(u64)stack<<" <+0>)\n"<<std::dec;
|
||||
for(u32 i=0;i<bytecode[0].num;++i) {
|
||||
std::clog<<" 0x"<<std::hex<<std::setw(6)
|
||||
<<std::setfill('0')<<i<<std::dec
|
||||
<<" ";
|
||||
std::clog << "global (0x" << std::hex
|
||||
<< (u64)stack << " <+0>)\n" << std::dec;
|
||||
for(u32 i = 0; i<bytecode[0].num; ++i) {
|
||||
std::clog << " 0x" << std::hex << std::setw(6)
|
||||
<< std::setfill('0') << i << std::dec
|
||||
<< " ";
|
||||
valinfo(stack[i]);
|
||||
}
|
||||
}
|
||||
|
@ -157,13 +166,14 @@ void vm::lstate() {
|
|||
if (!ctx.localr || !ctx.funcr.func().lsize) {
|
||||
return;
|
||||
}
|
||||
const u32 lsize=ctx.funcr.func().lsize;
|
||||
std::clog<<"local (0x"<<std::hex<<(u64)ctx.localr
|
||||
<<" <+"<<(u64)(ctx.localr-ngc.rctx->stack)<<">)\n"<<std::dec;
|
||||
for(u32 i=0;i<lsize;++i) {
|
||||
std::clog<<" 0x"<<std::hex<<std::setw(6)
|
||||
<<std::setfill('0')<<i<<std::dec
|
||||
<<" ";
|
||||
const u32 lsize = ctx.funcr.func().lsize;
|
||||
std::clog << "local (0x" << std::hex << (u64)ctx.localr
|
||||
<< " <+" << (u64)(ctx.localr-ngc.rctx->stack)
|
||||
<< ">)\n" << std::dec;
|
||||
for(u32 i = 0; i<lsize; ++i) {
|
||||
std::clog << " 0x" << std::hex << std::setw(6)
|
||||
<< std::setfill('0') << i << std::dec
|
||||
<< " ";
|
||||
valinfo(ctx.localr[i]);
|
||||
}
|
||||
}
|
||||
|
@ -172,15 +182,15 @@ void vm::ustate() {
|
|||
if (ctx.funcr.type==vm_nil || ctx.funcr.func().upval.empty()) {
|
||||
return;
|
||||
}
|
||||
std::clog<<"upvalue\n";
|
||||
auto& upval=ctx.funcr.func().upval;
|
||||
for(u32 i=0;i<upval.size();++i) {
|
||||
std::clog<<" -> upval["<<i<<"]:\n";
|
||||
auto& uv=upval[i].upval();
|
||||
for(u32 j=0;j<uv.size;++j) {
|
||||
std::clog<<" 0x"<<std::hex<<std::setw(6)
|
||||
<<std::setfill('0')<<j<<std::dec
|
||||
<<" ";
|
||||
std::clog << "upvalue\n";
|
||||
auto& upval = ctx.funcr.func().upval;
|
||||
for(u32 i = 0; i<upval.size(); ++i) {
|
||||
std::clog << " -> upval[" << i << "]:\n";
|
||||
auto& uv = upval[i].upval();
|
||||
for(u32 j = 0; j<uv.size; ++j) {
|
||||
std::clog << " 0x" << std::hex << std::setw(6)
|
||||
<< std::setfill('0') << j << std::dec
|
||||
<< " ";
|
||||
valinfo(uv[j]);
|
||||
}
|
||||
}
|
||||
|
@ -194,7 +204,7 @@ void vm::detail() {
|
|||
}
|
||||
|
||||
void vm::die(const std::string& str) {
|
||||
std::cerr<<"[vm] error: "<<str<<"\n";
|
||||
std::cerr << "[vm] error: " << str << "\n";
|
||||
traceback();
|
||||
stackinfo();
|
||||
|
||||
|
@ -203,13 +213,14 @@ void vm::die(const std::string& str) {
|
|||
detail();
|
||||
}
|
||||
|
||||
if (ngc.rctx->stack==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<std::string>& 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<const void*> 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<nafunc> code;
|
||||
for(auto& i:gen.codes()) {
|
||||
for(auto& i : gen.codes()) {
|
||||
code.push_back(oprs[i.op]);
|
||||
imm.push_back(i.num);
|
||||
}
|
||||
|
|
|
@ -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<std::string>& symbol_finder::do_find(code_block* root) {
|
||||
const std::vector<symbol_finder::symbol_info>& symbol_finder::do_find(code_block* root) {
|
||||
symbols.clear();
|
||||
root->accept(this);
|
||||
return symbols;
|
||||
|
|
|
@ -8,12 +8,18 @@
|
|||
#include <vector>
|
||||
|
||||
class symbol_finder:public ast_visitor {
|
||||
public:
|
||||
struct symbol_info {
|
||||
std::string name;
|
||||
std::string file;
|
||||
};
|
||||
|
||||
private:
|
||||
std::vector<std::string> symbols;
|
||||
std::vector<symbol_info> symbols;
|
||||
|
||||
public:
|
||||
bool visit_definition_expr(definition_expr*) override;
|
||||
bool visit_function(function*) override;
|
||||
bool visit_iter_expr(iter_expr*) override;
|
||||
const std::vector<std::string>& do_find(code_block*);
|
||||
const std::vector<symbol_finder::symbol_info>& do_find(code_block*);
|
||||
};
|
|
@ -35,3 +35,4 @@ b(1, 2, 3, 4); # 1 [2 3 4]
|
|||
# command line arguments
|
||||
println(arg);
|
||||
println(globals.arg);
|
||||
println(typeof(globals));
|
Loading…
Reference in New Issue