diff --git a/nasal_gc.h b/nasal_gc.h index 489d4da..aa5ab2f 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -60,8 +60,8 @@ struct nasal_func// 120 bytes struct nasal_val// 16 bytes { #define GC_UNCOLLECTED 0 -#define GC_FOUND 1 -#define GC_COLLECTED 2 +#define GC_COLLECTED 1 +#define GC_FOUND 2 uint8_t mark; uint16_t type; union @@ -84,23 +84,15 @@ nasal_val* nasal_vec::get_val(int index) { int vec_size=elems.size(); if(index<-vec_size || index>=vec_size) - { - std::cout<<">> [gc] nasal_vec::get_val: index out of range: "<=0]]; + return elems[index>=0?index:index+vec_size]; } nasal_val** nasal_vec::get_mem(int index) { int vec_size=elems.size(); if(index<-vec_size || index>=vec_size) - { - std::cout<<">> [gc] nasal_vec::get_mem: index out of range: "<=0]]; + return &elems[index>=0?index:index+vec_size]; } void nasal_vec::print() { @@ -280,7 +272,7 @@ void nasal_gc::mark() { nasal_val* tmp=bfs.front(); bfs.pop(); - if(!tmp || tmp->mark) continue; + if(tmp->mark) continue; tmp->mark=GC_FOUND; if(tmp->type==vm_vec) for(auto i:tmp->ptr.vec->elems) @@ -293,7 +285,8 @@ void nasal_gc::mark() for(auto i:tmp->ptr.func->closure) bfs.push(i); for(auto i:tmp->ptr.func->default_para) - bfs.push(i); + if(i) + bfs.push(i); } } return; diff --git a/nasal_parse.h b/nasal_parse.h index bcb6fab..0ee3c4c 100644 --- a/nasal_parse.h +++ b/nasal_parse.h @@ -265,17 +265,17 @@ void nasal_parse::check_memory_reachable(nasal_ast& node) if(node.get_type()==ast_call) { if(node.get_children()[0].get_type()!=ast_id) - die(node.get_line(),"cannot get the memory of a temporary data"); + die(node.get_line(),"cannot get memory of temp data"); for(auto& tmp:node.get_children()) { if(tmp.get_type()==ast_callf) - die(tmp.get_line(),"cannot get the memory of function-returned value"); + die(tmp.get_line(),"cannot get memory of func-returned value"); if(tmp.get_type()==ast_callv && (tmp.get_children().size()>1 || tmp.get_children()[0].get_type()==ast_subvec)) - die(tmp.get_line(),"cannot get the memory in temporary sliced vector"); - } + die(tmp.get_line(),"cannot get memory of temp sliced vector"); + } } else if(node.get_type()!=ast_id) - die(node.get_line(),"cannot use calculation as the memory of scalar"); + die(node.get_line(),"cannot get memory of temp data"); return; } nasal_ast nasal_parse::null_node_gen() @@ -458,7 +458,7 @@ nasal_ast nasal_parse::expr() if(tok_type==tok_ret && !in_function) die(error_line,"use return in the function"); switch(tok_type) - { + { case tok_nil: case tok_num: case tok_str: diff --git a/nasal_vm.h b/nasal_vm.h index 606ef2c..fa0564e 100644 --- a/nasal_vm.h +++ b/nasal_vm.h @@ -5,16 +5,16 @@ class nasal_vm { private: /* reference from nasal_gc */ - nasal_val**& stack_top; // stack top + nasal_val**& stack_top; // stack top /* values of nasal_vm */ - int pc; // program counter - bool loop_mark; // when mark is false,break the main loop - std::stack ret; // ptr stack stores address for function to return - std::stack counter; // iterator stack for forindex/foreach - std::vector str_table; // symbols used in process - std::vector exec_code; // byte codes store here - std::stack addr_stack; // stack for mem_call - nasal_gc gc; // garbage collector + int pc; // program counter + bool loop_mark; // when mark is false,break the main loop + std::stack ret; // ptr stack stores address for function to return + std::stack counter; // iterator stack for forindex/foreach + std::vector str_table; // symbols used in process + std::vector exec_code; // byte codes store here + std::stack addr_stack;// used for mem_call + nasal_gc gc; // garbage collector void die(std::string); bool condition(nasal_val*); @@ -105,8 +105,6 @@ void nasal_vm::init( void nasal_vm::clear() { gc.gc_clear(); - while(!addr_stack.empty()) - addr_stack.pop(); while(!ret.empty()) ret.pop(); while(!counter.empty()) @@ -123,16 +121,15 @@ void nasal_vm::die(std::string str) } bool nasal_vm::condition(nasal_val* val_addr) { - int type=val_addr->type; - if(type==vm_num) + if(val_addr->type==vm_num) return val_addr->ptr.num; - else if(type==vm_str) + else if(val_addr->type==vm_str) { std::string& str=*val_addr->ptr.str; - double number=str2num(str.c_str()); - if(std::isnan(number)) + double num=str2num(str.c_str()); + if(std::isnan(num)) return str.empty(); - return number; + return num; } return false; } @@ -257,11 +254,11 @@ void nasal_vm::opr_unot() stack_top[0]=val->ptr.num?gc.zero_addr:gc.one_addr; else if(type==vm_str) { - double number=str2num(val->ptr.str->c_str()); - if(std::isnan(number)) + double num=str2num(val->ptr.str->c_str()); + if(std::isnan(num)) stack_top[0]=val->ptr.str->empty()?gc.one_addr:gc.zero_addr; else - stack_top[0]=number?gc.zero_addr:gc.one_addr; + stack_top[0]=num?gc.zero_addr:gc.one_addr; } else die("unot: incorrect value type"); @@ -311,8 +308,7 @@ void nasal_vm::opr_lnk() } void nasal_vm::opr_addeq() { - nasal_val** mem_addr=addr_stack.top(); - addr_stack.pop(); + nasal_val** mem_addr=addr_stack.top();addr_stack.pop(); nasal_val* new_val=gc.gc_alloc(vm_num); new_val->ptr.num=mem_addr[0]->to_number()+stack_top[0]->to_number(); stack_top[0]=mem_addr[0]=new_val; @@ -320,8 +316,7 @@ void nasal_vm::opr_addeq() } void nasal_vm::opr_subeq() { - nasal_val** mem_addr=addr_stack.top(); - addr_stack.pop(); + nasal_val** mem_addr=addr_stack.top();addr_stack.pop(); nasal_val* new_val=gc.gc_alloc(vm_num); new_val->ptr.num=mem_addr[0]->to_number()-stack_top[0]->to_number(); stack_top[0]=mem_addr[0]=new_val; @@ -329,8 +324,7 @@ void nasal_vm::opr_subeq() } void nasal_vm::opr_muleq() { - nasal_val** mem_addr=addr_stack.top(); - addr_stack.pop(); + nasal_val** mem_addr=addr_stack.top();addr_stack.pop(); nasal_val* new_val=gc.gc_alloc(vm_num); new_val->ptr.num=mem_addr[0]->to_number()*stack_top[0]->to_number(); stack_top[0]=mem_addr[0]=new_val; @@ -338,8 +332,7 @@ void nasal_vm::opr_muleq() } void nasal_vm::opr_diveq() { - nasal_val** mem_addr=addr_stack.top(); - addr_stack.pop(); + nasal_val** mem_addr=addr_stack.top();addr_stack.pop(); nasal_val* new_val=gc.gc_alloc(vm_num); new_val->ptr.num=mem_addr[0]->to_number()/stack_top[0]->to_number(); stack_top[0]=mem_addr[0]=new_val; @@ -347,8 +340,7 @@ void nasal_vm::opr_diveq() } void nasal_vm::opr_lnkeq() { - nasal_val** mem_addr=addr_stack.top(); - addr_stack.pop(); + nasal_val** mem_addr=addr_stack.top();addr_stack.pop(); nasal_val* new_val=gc.gc_alloc(vm_str); *new_val->ptr.str=mem_addr[0]->to_string()+stack_top[0]->to_string(); stack_top[0]=mem_addr[0]=new_val; @@ -502,14 +494,14 @@ void nasal_vm::opr_calll() } void nasal_vm::opr_callv() { - nasal_val* val=*stack_top--; - nasal_val* vec_addr=*stack_top; + nasal_val* val=stack_top[0]; + nasal_val* vec_addr=(--stack_top)[0]; int type=vec_addr->type; if(type==vm_vec) { nasal_val* res=vec_addr->ptr.vec->get_val(val->to_number()); if(!res) - die("callv: index out of range"); + die("callv: index out of range:"+val->to_string()); stack_top[0]=res; } else if(type==vm_hash) @@ -536,7 +528,7 @@ void nasal_vm::opr_callv() int str_size=str.length(); if(num<-str_size || num>=str_size) { - die("callv: index out of range"); + die("callv: index out of range:"+val->to_string()); return; } nasal_val* res=gc.gc_alloc(vm_num); @@ -558,7 +550,7 @@ void nasal_vm::opr_callvi() // cannot use operator[],because this may cause overflow nasal_val* res=val->ptr.vec->get_val(exec_code[pc].num); if(!res) - die("callvi: index out of range"); + die("callvi: index out of range:"+num2str(exec_code[pc].num)); (++stack_top)[0]=res; return; } @@ -700,7 +692,7 @@ void nasal_vm::opr_slc() } nasal_val* res=stack_top[0]->ptr.vec->get_val(num); if(!res) - die("slc: index out of range"); + die("slc: index out of range:"+num2str(num)); gc.slice_stack.back()->ptr.vec->elems.push_back(res); return; } @@ -756,10 +748,9 @@ void nasal_vm::opr_mcalll() } void nasal_vm::opr_mcallv() { - nasal_val* val=*stack_top--; - nasal_val** vec_addr=addr_stack.top(); - addr_stack.pop(); - int type=(*vec_addr)->type; + nasal_val* val=*stack_top--; + nasal_val* vec_addr=*addr_stack.top(); + int type=vec_addr->type; if(type==vm_vec) { int num; @@ -769,10 +760,10 @@ void nasal_vm::opr_mcallv() case vm_str:num=(int)str2num(val->ptr.str->c_str());break; default:die("mcallv: error value type");break; } - nasal_val** res=(*vec_addr)->ptr.vec->get_mem(num); - if(!res) - die("mcallv: index out of range"); - addr_stack.push(res); + nasal_val** mem_addr=vec_addr->ptr.vec->get_mem(num); + if(!mem_addr) + die("mcallv: index out of range:"+num2str(num)); + addr_stack.top()=mem_addr; } else if(type==vm_hash) { @@ -781,39 +772,37 @@ void nasal_vm::opr_mcallv() die("mcallv: must use string as the key"); return; } - nasal_hash& ref=*(*vec_addr)->ptr.hash; + nasal_hash& ref=*vec_addr->ptr.hash; std::string& str=*val->ptr.str; - nasal_val** res=ref.get_mem(str); - if(!res) + nasal_val** mem_addr=ref.get_mem(str); + if(!mem_addr) { ref.elems[str]=gc.nil_addr; - res=ref.get_mem(str); + mem_addr=ref.get_mem(str); } - addr_stack.push(res); + addr_stack.top()=mem_addr; } else - die("mcallv: cannot get memory space in a string"); + die("mcallv: cannot get memory space in other types"); return; } void nasal_vm::opr_mcallh() { - nasal_val** mem_addr=nullptr; - nasal_val** hash_addr=addr_stack.top(); - addr_stack.pop(); - if((*hash_addr)->type!=vm_hash) + nasal_val* hash_addr=*addr_stack.top(); + if(hash_addr->type!=vm_hash) { die("mcallh: must call a hash"); return; } - nasal_hash& ref=*(*hash_addr)->ptr.hash; + nasal_hash& ref=*hash_addr->ptr.hash; std::string& str=str_table[exec_code[pc].num]; - mem_addr=ref.get_mem(str); + nasal_val** mem_addr=ref.get_mem(str); if(!mem_addr) // create a new key { ref.elems[str]=gc.nil_addr; mem_addr=ref.get_mem(str); } - addr_stack.push(mem_addr); + addr_stack.top()=mem_addr; return; } void nasal_vm::opr_ret() @@ -828,7 +817,7 @@ void nasal_vm::opr_ret() } void nasal_vm::run() { - static void (nasal_vm::*opr_table[])()= + void (nasal_vm::*opr_table[])()= { &nasal_vm::opr_nop, &nasal_vm::opr_intg, diff --git a/test/calc.nas b/test/calc.nas index 7214a8d..9eae801 100644 --- a/test/calc.nas +++ b/test/calc.nas @@ -1,30 +1,18 @@ import("lib.nas"); +var filename=["main.cpp","nasal_ast.h","nasal_builtin.h","nasal_codegen.h","nasal_gc.h","nasal_import.h","nasal_lexer.h","nasal_parse.h","nasal_vm.h","nasal.h"]; +var space=[" "," ","",""," "," "," "," "," "," "]; func(){ - var filename=[ - "main.cpp", - "nasal_ast.h", - "nasal_builtin.h", - "nasal_codegen.h", - "nasal_gc.h", - "nasal_import.h", - "nasal_lexer.h", - "nasal_parse.h", - "nasal_vm.h", - "nasal.h" - ]; - var max_size=size('nasal_codegen.h'); - var (cnt,semi)=[0,0]; - foreach(var file;filename) + var (bytes,cnt,semi)=(0,0,0); + forindex(var i;filename) { - var s=io.fin(file); - var name=file; - for(var i=size(name);i