diff --git a/README.md b/README.md index 23f987a..55916cc 100644 --- a/README.md +++ b/README.md @@ -829,7 +829,7 @@ But in this new interpreter, it will get: [codegen] in : error(s) occurred,stop. ``` -This difference is caused by different kinds of ways of lexical analysis. +(outdated)This difference is caused by different kinds of ways of lexical analysis. In most script language interpreters, they use dynamic analysis to check if this symbol is defined yet. However, this kind of analysis is at the cost of lower efficiency. To make sure the interpreter runs at higher efficiency, i choose static analysis to manage the memory space of each symbol. diff --git a/main.cpp b/main.cpp index 4d058fb..48a7128 100644 --- a/main.cpp +++ b/main.cpp @@ -115,7 +115,7 @@ void execute(std::string& file,std::string& command) } int main(int argc,const char* argv[]) { - std::string command,file="null"; + std::string command,file; if(argc==2 && (!strcmp(argv[1],"-v") || !strcmp(argv[1],"--version"))) logo(); else if(argc==2 && (!strcmp(argv[1],"-h") || !strcmp(argv[1],"--help"))) diff --git a/nasal_gc.h b/nasal_gc.h index be7e115..5985372 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -51,7 +51,7 @@ struct nasal_func// 120 bytes uint32_t entry; // pc will set to entry-1 to call this function std::vector default_para;// default value(nasal_val*) std::unordered_map key_table;// parameter name hash - std::vector closure;// closure will be loaded to gc.local.back() as the local scope + nasal_val* closure;// closure will be loaded to gc.local.back() as the local scope nasal_func(); void clear(); @@ -214,7 +214,6 @@ void nasal_func::clear() dynpara=-1; default_para.clear(); key_table.clear(); - closure.clear(); return; } @@ -272,7 +271,7 @@ struct nasal_gc std::vector str_addrs; // reserved address for const vm_str std::vector memory; // gc memory std::queue free_list[vm_type_size]; // gc free list - std::list> local; + std::vector local; void mark(); void sweep(); void gc_init(std::vector&,std::vector&); @@ -285,9 +284,8 @@ struct nasal_gc void nasal_gc::mark() { std::queue bfs; - for(auto& i:local) - for(auto j:i) - bfs.push(j); + for(auto i:local) + bfs.push(i); for(nasal_val** i=val_stack;i<=stack_top;++i) bfs.push(*i); while(!bfs.empty()) @@ -307,8 +305,7 @@ void nasal_gc::mark() bfs.push(i.second); break; case vm_func: - for(auto i:tmp->ptr.func->closure) - bfs.push(i); + bfs.push(tmp->ptr.func->closure); for(auto i:tmp->ptr.func->default_para) if(i) bfs.push(i); diff --git a/nasal_vm.h b/nasal_vm.h index cb4acbe..f168c00 100644 --- a/nasal_vm.h +++ b/nasal_vm.h @@ -245,7 +245,12 @@ inline void nasal_vm::opr_intg() } inline void nasal_vm::opr_intl() { - stack_top[0]->ptr.func->closure.resize(imm[pc],gc.nil_addr); + auto& vec=stack_top[0]->ptr.func->closure->ptr.vec->elems; + // if many functions share the same closure + // resize will break the size of vector and cause exe_bad_access + // so choose the maximum size as the size of this closure + if(vec.size()ptr.vec->elems[imm[pc]]=(stack_top--)[0]; return; } inline void nasal_vm::opr_pnum() @@ -309,8 +314,9 @@ inline void nasal_vm::opr_newf() { (++stack_top)[0]=gc.gc_alloc(vm_func); stack_top[0]->ptr.func->entry=imm[pc]; + stack_top[0]->ptr.func->closure=gc.nil_addr; if(gc.local.empty()) - stack_top[0]->ptr.func->closure.push_back(gc.nil_addr);// me + stack_top[0]->ptr.func->closure=gc.gc_alloc(vm_vec); else stack_top[0]->ptr.func->closure=gc.local.back();// local contains 'me' return; @@ -557,7 +563,7 @@ inline void nasal_vm::opr_callg() } inline void nasal_vm::opr_calll() { - (++stack_top)[0]=gc.local.back()[imm[pc]]; + (++stack_top)[0]=gc.local.back()->ptr.vec->elems[imm[pc]]; return; } inline void nasal_vm::opr_callv() @@ -584,7 +590,7 @@ inline void nasal_vm::opr_callv() return; } if(stack_top[0]->type==vm_func) - stack_top[0]->ptr.func->closure[0]=val;// me + stack_top[0]->ptr.func->closure->ptr.vec->elems[0]=val;// me } else if(vec_addr->type==vm_str) { @@ -632,7 +638,7 @@ inline void nasal_vm::opr_callh() return; } if(stack_top[0]->type==vm_func) - stack_top[0]->ptr.func->closure[0]=val;// me + stack_top[0]->ptr.func->closure->ptr.vec->elems[0]=val;// me return; } inline void nasal_vm::opr_callfv() @@ -648,10 +654,11 @@ inline void nasal_vm::opr_callfv() } // push new local scope auto& ref_func=*func_addr->ptr.func; - gc.local.push_back(ref_func.closure); + gc.local.push_back(gc.gc_alloc(vm_vec)); + gc.local.back()->ptr.vec->elems=ref_func.closure->ptr.vec->elems; // load parameters auto& ref_default=ref_func.default_para; - auto& ref_closure=gc.local.back(); + auto& ref_closure=gc.local.back()->ptr.vec->elems; uint32_t offset=ref_func.offset; uint32_t para_size=ref_func.key_table.size(); @@ -694,10 +701,11 @@ inline void nasal_vm::opr_callfh() } // push new local scope auto& ref_func=*func_addr->ptr.func; - gc.local.push_back(ref_func.closure); + gc.local.push_back(gc.gc_alloc(vm_vec)); + gc.local.back()->ptr.vec->elems=ref_func.closure->ptr.vec->elems; // load parameters auto& ref_default=ref_func.default_para; - auto& ref_closure=gc.local.back(); + auto& ref_closure=gc.local.back()->ptr.vec->elems; if(ref_func.dynpara>=0) { @@ -725,7 +733,7 @@ inline void nasal_vm::opr_callfh() } inline void nasal_vm::opr_callb() { - (++stack_top)[0]=(*builtin_func[imm[pc]].func)(gc.local.back(),gc); + (++stack_top)[0]=(*builtin_func[imm[pc]].func)(gc.local.back()->ptr.vec->elems,gc); if(!stack_top[0]) die("native function error."); return; @@ -796,7 +804,7 @@ inline void nasal_vm::opr_mcallg() } inline void nasal_vm::opr_mcalll() { - mem_addr=&gc.local.back()[imm[pc]]; + mem_addr=&(gc.local.back()->ptr.vec->elems[imm[pc]]); (++stack_top)[0]=mem_addr[0]; return; } @@ -851,9 +859,13 @@ inline void nasal_vm::opr_mcallh() } inline void nasal_vm::opr_ret() { + auto& vec=stack_top[-1]->ptr.func->closure->ptr.vec->elems; + for(uint32_t i=0;iptr.func->offset;++i) + vec[i]=gc.local.back()->ptr.vec->elems[i]; + vec[0]=gc.nil_addr;// set 'me' to nil gc.local.pop_back();// delete local scope pc=ret.top();ret.pop();// fetch pc - (--stack_top)[0]->ptr.func->closure[0]=gc.nil_addr;// set 'me' to nil + --stack_top; stack_top[0]=stack_top[1];// rewrite nasal_func with returned value return; } diff --git a/stl/list.nas b/stl/list.nas index 54dfde1..87945f4 100644 --- a/stl/list.nas +++ b/stl/list.nas @@ -2,65 +2,65 @@ # valkmjolnir 2021/3/31 var list=func() { - var _={begin:nil,end:nil}; + var (begin,end)=(nil,nil); return { push_back:func(elem) { var tmp={elem:elem,prev:nil,next:nil}; - if(_.end!=nil) + if(end!=nil) { - _.end.next=tmp; - tmp.prev=_.end; - _.end=tmp; + end.next=tmp; + tmp.prev=end; + end=tmp; } else - _.begin=_.end=tmp; + begin=end=tmp; return; }, push_front:func(elem) { var tmp={elem:elem,prev:nil,next:nil}; - if(_.begin!=nil) + if(begin!=nil) { - _.begin.prev=tmp; - tmp.next=_.begin; - _.begin=tmp; + begin.prev=tmp; + tmp.next=begin; + begin=tmp; } else - _.begin=_.end=tmp; + begin=end=tmp; return; }, pop_back:func() { - if(_.end!=nil) - _.end=_.end.prev; - if(_.end==nil) - _.begin=nil; + if(end!=nil) + end=end.prev; + if(end==nil) + begin=nil; else - _.end.next=nil; + end.next=nil; return; }, pop_front:func() { - if(_.begin!=nil) - _.begin=_.begin.next; - if(_.begin==nil) - _.end=nil; + if(begin!=nil) + begin=begin.next; + if(begin==nil) + end=nil; else - _.begin.prev=nil; + begin.prev=nil; return; }, front:func() { - if(_.begin!=nil) - return _.begin.elem; + if(begin!=nil) + return begin.elem; return nil; }, back:func() { - if(_.end!=nil) - return _.end.elem; + if(end!=nil) + return end.elem; return nil; }, }; diff --git a/stl/queue.nas b/stl/queue.nas index 009113c..9e5d95d 100644 --- a/stl/queue.nas +++ b/stl/queue.nas @@ -2,7 +2,7 @@ # valkmjolnir 2021/3/31 var queue=func() { - var _={begin:nil,end:nil}; + var (begin,end)=(nil,nil); return { push:func(elem) @@ -12,35 +12,35 @@ var queue=func() elem:elem, next:nil }; - if(_.begin==nil) - _.begin=_.end=new_node; + if(begin==nil) + begin=end=new_node; else { - _.end.next=new_node; - _.end=new_node; + end.next=new_node; + end=new_node; } return; }, pop:func() { - if(_.begin!=nil) - _.begin=_.begin.next; - if(_.begin==nil) - _.end=nil; + if(begin!=nil) + begin=begin.next; + if(begin==nil) + end=nil; }, front:func() { - if(_.begin!=nil) - return _.begin.elem; + if(begin!=nil) + return begin.elem; return nil; }, clear:func() { - _.begin=_.end=nil; + begin=end=nil; }, empty:func() { - return _.begin==nil; + return begin==nil; } }; } diff --git a/stl/stack.nas b/stl/stack.nas index 856470c..6e185ef 100644 --- a/stl/stack.nas +++ b/stl/stack.nas @@ -2,35 +2,35 @@ # valkmjolnir 2021/3/31 var stack=func() { - var _={next:nil}; + var next=nil; return { push:func(elem) { - _.next={elem:elem,next:_.next}; + next={elem:elem,next:next}; return; }, pop:func() { - var tmp=_.next; + var tmp=next; if(tmp!=nil) - _.next=tmp.next; + next=tmp.next; return; }, top:func() { - var tmp=_.next; + var tmp=next; if(tmp!=nil) return tmp.elem; return nil; }, clear:func() { - _.next=nil; + next=nil; }, empty:func() { - return _.next==nil; + return next==nil; } }; } diff --git a/test/bfs.nas b/test/bfs.nas index 84ea906..ebc79cc 100644 --- a/test/bfs.nas +++ b/test/bfs.nas @@ -3,6 +3,7 @@ import("stl/queue.nas"); rand(time(0)); +var pixel=[' ','#','.','*']; var map=[]; for(var i=0;i<10;i+=1) { @@ -17,7 +18,7 @@ var prt=func() for(var i=0;i<10;i+=1) { for(var j=0;j<10;j+=1) - s~=map[i][j]; + s~=pixel[map[i][j]]; s~='\n'; } s~='----------\n'; @@ -29,7 +30,7 @@ var bfs=func(begin,end) var move=[[1,0],[0,1],[-1,0],[0,-1]]; var que=queue(); que.push(begin); - map[begin[0]][begin[1]]=3; + map[begin[0]][begin[1]]=2; while(!que.empty()) { var vertex=que.front(); @@ -40,13 +41,14 @@ var bfs=func(begin,end) var y=vertex[1]+i[1]; if(x==end[0] and y==end[1]) { - map[x][y]='*'; + map[x][y]=3; + prt(); return; } if(0<=x and x<10 and 0<=y and y<10 and map[x][y]==0) { que.push([x,y]); - map[x][y]=3; + map[x][y]=2; } } prt(); diff --git a/test/class.nas b/test/class.nas index 2f024c9..0aa677c 100644 --- a/test/class.nas +++ b/test/class.nas @@ -2,16 +2,13 @@ import("lib.nas"); var student=func(name,age) { - var val={ - name:name, - age:age - }; + var (n,a)=(name,age); return { - print_info:func(){println(val.name,' ',val.age);}, - set_age: func(age){val.age=age;}, - get_age: func(){return val.age;}, - set_name: func(name){val.name=name;}, - get_name: func(){return val.name;} + print_info:func println(n,' ',a), + set_age: func(age) a=age, + get_age: func return a, + set_name: func(name) n=name, + get_name: func return n }; } var s=student('valk',24); diff --git a/test/ycombinator.nas b/test/ycombinator.nas index e1ab01f..698263e 100644 --- a/test/ycombinator.nas +++ b/test/ycombinator.nas @@ -14,5 +14,5 @@ var fib=func(f){ } ); -for(var i=1;i<=20;i+=1) +for(var i=1;i<31;i+=1) println(fib(i)); \ No newline at end of file