diff --git a/nasal_codegen.h b/nasal_codegen.h index 7f8b49b..9b20f2f 100644 --- a/nasal_codegen.h +++ b/nasal_codegen.h @@ -168,10 +168,10 @@ struct struct opcode { - uint16_t op; - uint16_t fidx; - uint32_t num; - uint32_t line; + uint16_t op; // opcode + uint16_t fidx;// source code file index + uint32_t num; // imm num + uint32_t line;// line of source code opcode(uint8_t _op=op_nop,uint16_t _fidx=0,uint32_t _num=0,uint32_t _line=0) { op=_op; @@ -448,6 +448,15 @@ void nasal_codegen::func_gen(const nasal_ast& ast) gen(op_dynpara,string_table[str],tmp.get_line()); } } + // default dynamic parameter name is arg. + // if there are too many arguments,unused arguments will be collected to a nasal_vec + // if(!ast.get_children().size() || ast.get_children().back().get_type()!=ast_dynamic_id) + // { + // const std::string str="arg"; + // regist_string(str); + // add_sym(str); + // gen(op_dynpara,string_table[str],ast.get_line()); + // } exec_code[newfunc_label].num=exec_code.size()+1; int jmp_ptr=exec_code.size(); gen(op_jmp,0,0); diff --git a/nasal_gc.h b/nasal_gc.h index 05067bf..9358925 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -9,6 +9,7 @@ enum nasal_type vm_func, vm_vec, vm_hash, + vm_obj, vm_type_size }; @@ -18,10 +19,11 @@ const int increment[vm_type_size]= { 0, // vm_nil,in fact it is not in use 65536,// vm_num - 512, // vm_str - 64, // vm_func - 2048, // vm_vec - 512 // vm_hash + 2048, // vm_str + 512, // vm_func + 8192, // vm_vec + 512, // vm_hash + 0 // vm_obj }; // declaration of nasal_val @@ -29,11 +31,23 @@ struct nasal_val; // define nasal_ref => nasal_val* typedef nasal_val* nasal_ref; +#ifdef __NASAL_REF__ +struct nasal_ref +{ + uint8_t type; + union + { + double num; + nasal_val* gcobj; + }value; +}; +#endif + struct nasal_vec// 24 bytes { std::vector elems; - void print(); + void print(); nasal_ref get_val(int); nasal_ref* get_mem(int); }; @@ -42,7 +56,7 @@ struct nasal_hash// 56 bytes { std::unordered_map elems; - void print(); + void print(); nasal_ref get_val(std::string&); nasal_ref* get_mem(std::string&); }; @@ -74,6 +88,7 @@ struct nasal_val// 16 bytes nasal_vec* vec; nasal_hash* hash; nasal_func* func; + void* obj; }ptr; nasal_val(int); @@ -100,8 +115,7 @@ nasal_ref* nasal_vec::get_mem(int index) void nasal_vec::print() { static int depth=0; - ++depth; - if(depth>1024) + if(++depth>32) { std::cout<<"[..]"; --depth; @@ -173,8 +187,7 @@ nasal_ref* nasal_hash::get_mem(std::string& key) void nasal_hash::print() { static int depth=0; - ++depth; - if(depth>1024) + if(++depth>32) { std::cout<<"{..}"; --depth; diff --git a/nasal_vm.h b/nasal_vm.h index 1f4b3e6..fe60333 100644 --- a/nasal_vm.h +++ b/nasal_vm.h @@ -869,8 +869,12 @@ inline void nasal_vm::opr_ret() uint32_t offset=func->offset; nasal_ref cls=cls_stk.top();cls_stk.pop(); // same closure detected,update the last local scope instead of the closure + // because when calling a function,local scope get a copy of the func's closure,not the reference if(!cls_stk.empty() && cls_stk.top()==cls) { + // this condition in fact is that two called function are using the same closure + // if this copy of closure is changed, the closure will be updated at the same time + // also the copy of closure that still in using will alse be updated auto& vec=gc.local.back()->ptr.vec->elems; auto& func_vec=func->closure->ptr.vec->elems; gc.local.pop_back(); @@ -879,6 +883,7 @@ inline void nasal_vm::opr_ret() } else { + // two closures are not the same, update the func's closure and drop gc.local.back() auto& vec=func->closure->ptr.vec->elems; for(uint32_t i=0;iptr.vec->elems[i]; @@ -894,7 +899,7 @@ inline void nasal_vm::opr_ret() void nasal_vm::run(std::vector& exec,bool op_cnt) { uint64_t count[op_ret+1]={0}; - void* opr_table[]= + const void* opr_table[]= { &&nop, &&intg, &&intl, &&offset, &&loadg, &&loadl, &&pnum, &&pone, @@ -918,7 +923,7 @@ void nasal_vm::run(std::vector& exec,bool op_cnt) }; bytecode=exec; - std::vector code; + std::vector code; for(auto& i:exec) { code.push_back(opr_table[i.op]); diff --git a/test/class.nas b/test/class.nas index 0aa677c..3b50297 100644 --- a/test/class.nas +++ b/test/class.nas @@ -21,4 +21,48 @@ println(s.get_age(),' ',s.get_name()); s.set_age(20); s.set_name('Sidi Liang'); s.print_info(); -println(s.get_age(),' ',s.get_name()); \ No newline at end of file +println(s.get_age(),' ',s.get_name()); +# flightgear nasal-console cannot use this kind of object initializing +var m=func(){ + var (_1,_2)=(0,1); + return { + a:func(){ + print(_1,' ',_2,'\n'); + }, + b:func(x){ + _1=x; + }, + c:func(x){ + _2=x; + }, + d:func(x){ + return func{ + print(_1,' ',_2,' ',x,'\n'); + }; + }, + g:func(x){ + var y=x; + return func{ + print(_1,' ',_2,' ',x,' ',y,'\n'); + } + }, + h:func(){ + return func(x){ + _1=x; + } + } + }; +}(); + +m.a(); # 0 1 +m.b(2048); +m.c(1024); +var a=m.d(-1); +var b=m.g(1); +a(); # 2048 1024 -1 +b(); # 2048 1024 1 1 + +m.h()(2147483647); +m.a(); +# flightgear-nasal-console: 2147483647 1024 +# nasal-interpreter 2048 1024 \ No newline at end of file