diff --git a/nasal_builtin.h b/nasal_builtin.h index 548e420..90d98e8 100644 --- a/nasal_builtin.h +++ b/nasal_builtin.h @@ -10,60 +10,60 @@ builtin function __builtin_std_cout is wrapped up by print */ -std::unordered_map builtin_use_str_table; +std::unordered_map builtin_use_str; // used to find values that builtin function uses -#define in_builtin_find(val_name) \ +#define builtin_find(name) \ (\ local_scope\ ->ptr.scop\ ->get_val\ - (builtin_use_str_table[val_name])\ + (builtin_use_str[name])\ ) // declaration of builtin functions // to add new builtin function,declare it here and write the definition below -nasal_val* builtin_print(nasal_val*); -nasal_val* builtin_append(nasal_val*); -nasal_val* builtin_setsize(nasal_val*); -nasal_val* builtin_system(nasal_val*); -nasal_val* builtin_input(nasal_val*); -nasal_val* builtin_sleep(nasal_val*); -nasal_val* builtin_fin(nasal_val*); -nasal_val* builtin_fout(nasal_val*); -nasal_val* builtin_split(nasal_val*); -nasal_val* builtin_rand(nasal_val*); -nasal_val* builtin_id(nasal_val*); -nasal_val* builtin_int(nasal_val*); -nasal_val* builtin_num(nasal_val*); -nasal_val* builtin_pop(nasal_val*); -nasal_val* builtin_str(nasal_val*); -nasal_val* builtin_size(nasal_val*); -nasal_val* builtin_xor(nasal_val*); -nasal_val* builtin_and(nasal_val*); -nasal_val* builtin_or(nasal_val*); -nasal_val* builtin_nand(nasal_val*); -nasal_val* builtin_not(nasal_val*); -nasal_val* builtin_sin(nasal_val*); -nasal_val* builtin_cos(nasal_val*); -nasal_val* builtin_tan(nasal_val*); -nasal_val* builtin_exp(nasal_val*); -nasal_val* builtin_ln(nasal_val*); -nasal_val* builtin_sqrt(nasal_val*); -nasal_val* builtin_atan2(nasal_val*); -nasal_val* builtin_time(nasal_val*); -nasal_val* builtin_contains(nasal_val*); -nasal_val* builtin_delete(nasal_val*); -nasal_val* builtin_getkeys(nasal_val*); -nasal_val* builtin_import(nasal_val*); -nasal_val* builtin_die(nasal_val*); -nasal_val* builtin_type(nasal_val*); -nasal_val* builtin_substr(nasal_val*); -nasal_val* builtin_streq(nasal_val*); -nasal_val* builtin_left(nasal_val*); -nasal_val* builtin_right(nasal_val*); -nasal_val* builtin_cmp(nasal_val*); -nasal_val* builtin_chr(nasal_val*); +nasal_val* builtin_print(nasal_val*,nasal_gc&); +nasal_val* builtin_append(nasal_val*,nasal_gc&); +nasal_val* builtin_setsize(nasal_val*,nasal_gc&); +nasal_val* builtin_system(nasal_val*,nasal_gc&); +nasal_val* builtin_input(nasal_val*,nasal_gc&); +nasal_val* builtin_sleep(nasal_val*,nasal_gc&); +nasal_val* builtin_fin(nasal_val*,nasal_gc&); +nasal_val* builtin_fout(nasal_val*,nasal_gc&); +nasal_val* builtin_split(nasal_val*,nasal_gc&); +nasal_val* builtin_rand(nasal_val*,nasal_gc&); +nasal_val* builtin_id(nasal_val*,nasal_gc&); +nasal_val* builtin_int(nasal_val*,nasal_gc&); +nasal_val* builtin_num(nasal_val*,nasal_gc&); +nasal_val* builtin_pop(nasal_val*,nasal_gc&); +nasal_val* builtin_str(nasal_val*,nasal_gc&); +nasal_val* builtin_size(nasal_val*,nasal_gc&); +nasal_val* builtin_xor(nasal_val*,nasal_gc&); +nasal_val* builtin_and(nasal_val*,nasal_gc&); +nasal_val* builtin_or(nasal_val*,nasal_gc&); +nasal_val* builtin_nand(nasal_val*,nasal_gc&); +nasal_val* builtin_not(nasal_val*,nasal_gc&); +nasal_val* builtin_sin(nasal_val*,nasal_gc&); +nasal_val* builtin_cos(nasal_val*,nasal_gc&); +nasal_val* builtin_tan(nasal_val*,nasal_gc&); +nasal_val* builtin_exp(nasal_val*,nasal_gc&); +nasal_val* builtin_ln(nasal_val*,nasal_gc&); +nasal_val* builtin_sqrt(nasal_val*,nasal_gc&); +nasal_val* builtin_atan2(nasal_val*,nasal_gc&); +nasal_val* builtin_time(nasal_val*,nasal_gc&); +nasal_val* builtin_contains(nasal_val*,nasal_gc&); +nasal_val* builtin_delete(nasal_val*,nasal_gc&); +nasal_val* builtin_getkeys(nasal_val*,nasal_gc&); +nasal_val* builtin_import(nasal_val*,nasal_gc&); +nasal_val* builtin_die(nasal_val*,nasal_gc&); +nasal_val* builtin_type(nasal_val*,nasal_gc&); +nasal_val* builtin_substr(nasal_val*,nasal_gc&); +nasal_val* builtin_streq(nasal_val*,nasal_gc&); +nasal_val* builtin_left(nasal_val*,nasal_gc&); +nasal_val* builtin_right(nasal_val*,nasal_gc&); +nasal_val* builtin_cmp(nasal_val*,nasal_gc&); +nasal_val* builtin_chr(nasal_val*,nasal_gc&); void builtin_err(std::string func_name,std::string info) { @@ -76,7 +76,7 @@ void builtin_err(std::string func_name,std::string info) struct FUNC_TABLE { std::string name; - nasal_val* (*func)(nasal_val* x); + nasal_val* (*func)(nasal_val* x,nasal_gc&); } builtin_func[]= { {"__builtin_std_cout", builtin_print }, @@ -123,10 +123,10 @@ struct FUNC_TABLE {"", nullptr } }; -nasal_val* builtin_print(nasal_val* local_scope) +nasal_val* builtin_print(nasal_val* local_scope,nasal_gc& gc) { // get arguments - nasal_val* vector_val_addr=in_builtin_find("elements"); + nasal_val* vector_val_addr=builtin_find("elements"); // main process std::vector& ref_vec=vector_val_addr->ptr.vec->elems; int size=ref_vec.size(); @@ -144,12 +144,12 @@ nasal_val* builtin_print(nasal_val* local_scope) } } // generate return value - return nil_addr; + return gc.nil_addr; } -nasal_val* builtin_append(nasal_val* local_scope) +nasal_val* builtin_append(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* vec_addr=in_builtin_find("vector"); - nasal_val* elem_addr=in_builtin_find("elements"); + nasal_val* vec_addr=builtin_find("vector"); + nasal_val* elem_addr=builtin_find("elements"); if(vec_addr->type!=vm_vec) { builtin_err("append","\"vector\" must be vector"); @@ -160,12 +160,12 @@ nasal_val* builtin_append(nasal_val* local_scope) int size=ref_elems.size(); for(int i=0;itype!=vm_vec) { builtin_err("setsize","\"vector\" must be vector"); @@ -189,32 +189,32 @@ nasal_val* builtin_setsize(nasal_val* local_scope) ref_vec.pop_back(); else if(num>vec_size) for(int i=vec_size;itype!=vm_str) { builtin_err("system","\"str\" must be string"); return nullptr; } system(str_addr->ptr.str->data()); - return nil_addr; + return gc.nil_addr; } -nasal_val* builtin_input(nasal_val* local_scope) +nasal_val* builtin_input(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* ret_addr=gc_alloc(vm_str); + nasal_val* ret_addr=gc.gc_alloc(vm_str); std::cin>>*ret_addr->ptr.str; return ret_addr; } -nasal_val* builtin_sleep(nasal_val* local_scope) +nasal_val* builtin_sleep(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* val_addr=in_builtin_find("duration"); + nasal_val* val_addr=builtin_find("duration"); if(val_addr->type!=vm_num) { builtin_err("sleep","\"duration\" must be number"); @@ -222,12 +222,12 @@ nasal_val* builtin_sleep(nasal_val* local_scope) } // sleep in unistd.h will make this progress sleep sleep_time seconds. sleep((unsigned long)val_addr->ptr.num); - return nil_addr; + return gc.nil_addr; } -nasal_val* builtin_fin(nasal_val* local_scope) +nasal_val* builtin_fin(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* val_addr=in_builtin_find("filename"); + nasal_val* val_addr=builtin_find("filename"); if(val_addr->type!=vm_str) { builtin_err("io.fin","\"filename\" must be string"); @@ -235,7 +235,7 @@ nasal_val* builtin_fin(nasal_val* local_scope) } std::string& filename=*val_addr->ptr.str; std::ifstream fin(filename); - nasal_val* ret_addr=gc_alloc(vm_str); + nasal_val* ret_addr=gc.gc_alloc(vm_str); *ret_addr->ptr.str=""; if(!fin.fail()) while(!fin.eof()) @@ -251,10 +251,10 @@ nasal_val* builtin_fin(nasal_val* local_scope) return ret_addr; } -nasal_val* builtin_fout(nasal_val* local_scope) +nasal_val* builtin_fout(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* val_addr=in_builtin_find("filename"); - nasal_val* str_addr=in_builtin_find("str"); + nasal_val* val_addr=builtin_find("filename"); + nasal_val* str_addr=builtin_find("str"); if(val_addr->type!=vm_str) { builtin_err("io.fout","\"filename\" must be string"); @@ -273,13 +273,13 @@ nasal_val* builtin_fout(nasal_val* local_scope) } fout<<*str_addr->ptr.str; fout.close(); - return nil_addr; + return gc.nil_addr; } -nasal_val* builtin_split(nasal_val* local_scope) +nasal_val* builtin_split(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* delimeter_val_addr=in_builtin_find("delimeter"); - nasal_val* string_val_addr=in_builtin_find("string"); + nasal_val* delimeter_val_addr=builtin_find("delimeter"); + nasal_val* string_val_addr=builtin_find("string"); if(delimeter_val_addr->type!=vm_str) { builtin_err("split","\"delimeter\" must be string"); @@ -295,7 +295,7 @@ nasal_val* builtin_split(nasal_val* local_scope) int delimeter_len=delimeter.length(); int source_len=source.length(); - nasal_val* ret_addr=gc_alloc(vm_vec); + nasal_val* ret_addr=gc.gc_alloc(vm_vec); std::vector& ref_vec=ret_addr->ptr.vec->elems; std::string tmp=""; @@ -303,7 +303,7 @@ nasal_val* builtin_split(nasal_val* local_scope) { for(int i=0;iptr.str=source[i]; ref_vec.push_back(str_addr); } @@ -325,7 +325,7 @@ nasal_val* builtin_split(nasal_val* local_scope) { if(tmp.length()) { - nasal_val* str_addr=gc_alloc(vm_str); + nasal_val* str_addr=gc.gc_alloc(vm_str); *str_addr->ptr.str=tmp; ref_vec.push_back(str_addr); tmp=""; @@ -337,16 +337,16 @@ nasal_val* builtin_split(nasal_val* local_scope) } if(tmp.length()) { - nasal_val* str_addr=gc_alloc(vm_str); + nasal_val* str_addr=gc.gc_alloc(vm_str); *str_addr->ptr.str=tmp; ref_vec.push_back(str_addr); tmp=""; } return ret_addr; } -nasal_val* builtin_rand(nasal_val* local_scope) +nasal_val* builtin_rand(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* val_addr=in_builtin_find("seed"); + nasal_val* val_addr=builtin_find("seed"); if(val_addr->type!=vm_num && val_addr->type!=vm_nil) { builtin_err("rand","\"seed\" must be nil or number"); @@ -355,52 +355,52 @@ nasal_val* builtin_rand(nasal_val* local_scope) if(val_addr->type==vm_num) { srand((unsigned int)val_addr->ptr.num); - return nil_addr; + return gc.nil_addr; } double num=0; for(int i=0;i<5;++i) num=(num+rand())*(1.0/(RAND_MAX+1.0)); - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* ret_addr=gc.gc_alloc(vm_num); ret_addr->ptr.num=num; return ret_addr; } -nasal_val* builtin_id(nasal_val* local_scope) +nasal_val* builtin_id(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* val_addr=in_builtin_find("thing"); - nasal_val* ret_addr=gc_alloc(vm_str); + nasal_val* val_addr=builtin_find("thing"); + nasal_val* ret_addr=gc.gc_alloc(vm_str); char buf[32]; sprintf(buf,"0x%p",val_addr); *ret_addr->ptr.str=buf; return ret_addr; } -nasal_val* builtin_int(nasal_val* local_scope) +nasal_val* builtin_int(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* val_addr=in_builtin_find("value"); + nasal_val* val_addr=builtin_find("value"); if(val_addr->type!=vm_num) { builtin_err("int","\"value\" must be number"); return nullptr; } int number=(int)val_addr->ptr.num; - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* ret_addr=gc.gc_alloc(vm_num); ret_addr->ptr.num=(double)number; return ret_addr; } -nasal_val* builtin_num(nasal_val* local_scope) +nasal_val* builtin_num(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* val_addr=in_builtin_find("value"); + nasal_val* val_addr=builtin_find("value"); if(val_addr->type!=vm_str) { builtin_err("num","\"value\" must be string"); return nullptr; } - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* ret_addr=gc.gc_alloc(vm_num); ret_addr->ptr.num=val_addr->to_number(); return ret_addr; } -nasal_val* builtin_pop(nasal_val* local_scope) +nasal_val* builtin_pop(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* val_addr=in_builtin_find("vector"); + nasal_val* val_addr=builtin_find("vector"); if(val_addr->type!=vm_vec) { builtin_err("pop","\"vector\" must be vector"); @@ -412,24 +412,24 @@ nasal_val* builtin_pop(nasal_val* local_scope) val_addr->ptr.vec->elems.pop_back(); return tmp; } - return nil_addr; + return gc.nil_addr; } -nasal_val* builtin_str(nasal_val* local_scope) +nasal_val* builtin_str(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* val_addr=in_builtin_find("number"); + nasal_val* val_addr=builtin_find("number"); if(val_addr->type!=vm_num) { builtin_err("str","\"number\" must be number"); return nullptr; } - nasal_val* ret_addr=gc_alloc(vm_str); + nasal_val* ret_addr=gc.gc_alloc(vm_str); *ret_addr->ptr.str=val_addr->to_string(); return ret_addr; } -nasal_val* builtin_size(nasal_val* local_scope) +nasal_val* builtin_size(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* val_addr=in_builtin_find("object"); - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* val_addr=builtin_find("object"); + nasal_val* ret_addr=gc.gc_alloc(vm_num); switch(val_addr->type) { case vm_nil: ret_addr->ptr.num=0; break; @@ -442,10 +442,10 @@ nasal_val* builtin_size(nasal_val* local_scope) } return ret_addr; } -nasal_val* builtin_xor(nasal_val* local_scope) +nasal_val* builtin_xor(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* a_addr=in_builtin_find("a"); - nasal_val* b_addr=in_builtin_find("b"); + nasal_val* a_addr=builtin_find("a"); + nasal_val* b_addr=builtin_find("b"); if(a_addr->type!=vm_num) { builtin_err("xor","\"a\" must be number"); @@ -458,14 +458,14 @@ nasal_val* builtin_xor(nasal_val* local_scope) } int number_a=(int)a_addr->ptr.num; int number_b=(int)b_addr->ptr.num; - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* ret_addr=gc.gc_alloc(vm_num); ret_addr->ptr.num=(number_a^number_b); return ret_addr; } -nasal_val* builtin_and(nasal_val* local_scope) +nasal_val* builtin_and(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* a_addr=in_builtin_find("a"); - nasal_val* b_addr=in_builtin_find("b"); + nasal_val* a_addr=builtin_find("a"); + nasal_val* b_addr=builtin_find("b"); if(a_addr->type!=vm_num) { builtin_err("and","\"a\" must be number"); @@ -478,14 +478,14 @@ nasal_val* builtin_and(nasal_val* local_scope) } int number_a=(int)a_addr->ptr.num; int number_b=(int)b_addr->ptr.num; - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* ret_addr=gc.gc_alloc(vm_num); ret_addr->ptr.num=(number_a&number_b); return ret_addr; } -nasal_val* builtin_or(nasal_val* local_scope) +nasal_val* builtin_or(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* a_addr=in_builtin_find("a"); - nasal_val* b_addr=in_builtin_find("b"); + nasal_val* a_addr=builtin_find("a"); + nasal_val* b_addr=builtin_find("b"); if(a_addr->type!=vm_num) { builtin_err("or","\"a\" must be number"); @@ -498,14 +498,14 @@ nasal_val* builtin_or(nasal_val* local_scope) } int number_a=(int)a_addr->ptr.num; int number_b=(int)b_addr->ptr.num; - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* ret_addr=gc.gc_alloc(vm_num); ret_addr->ptr.num=(number_a|number_b); return ret_addr; } -nasal_val* builtin_nand(nasal_val* local_scope) +nasal_val* builtin_nand(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* a_addr=in_builtin_find("a"); - nasal_val* b_addr=in_builtin_find("b"); + nasal_val* a_addr=builtin_find("a"); + nasal_val* b_addr=builtin_find("b"); if(a_addr->type!=vm_num) { builtin_err("nand","\"a\" must be number"); @@ -518,99 +518,99 @@ nasal_val* builtin_nand(nasal_val* local_scope) } int number_a=(int)a_addr->ptr.num; int number_b=(int)b_addr->ptr.num; - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* ret_addr=gc.gc_alloc(vm_num); ret_addr->ptr.num=(~(number_a&number_b)); return ret_addr; } -nasal_val* builtin_not(nasal_val* local_scope) +nasal_val* builtin_not(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* a_addr=in_builtin_find("a"); + nasal_val* a_addr=builtin_find("a"); if(a_addr->type!=vm_num) { builtin_err("not","\"a\" must be number"); return nullptr; } int number=(int)a_addr->ptr.num; - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* ret_addr=gc.gc_alloc(vm_num); ret_addr->ptr.num=(~number); return ret_addr; } -nasal_val* builtin_sin(nasal_val* local_scope) +nasal_val* builtin_sin(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* val_addr=in_builtin_find("x"); + nasal_val* val_addr=builtin_find("x"); if(val_addr->type!=vm_num) { builtin_err("sin","\"x\" must be number"); return nullptr; } - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* ret_addr=gc.gc_alloc(vm_num); ret_addr->ptr.num=sin(val_addr->ptr.num); return ret_addr; } -nasal_val* builtin_cos(nasal_val* local_scope) +nasal_val* builtin_cos(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* val_addr=in_builtin_find("x"); + nasal_val* val_addr=builtin_find("x"); if(val_addr->type!=vm_num) { builtin_err("cos","\"x\" must be number"); return nullptr; } - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* ret_addr=gc.gc_alloc(vm_num); ret_addr->ptr.num=cos(val_addr->ptr.num); return ret_addr; } -nasal_val* builtin_tan(nasal_val* local_scope) +nasal_val* builtin_tan(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* val_addr=in_builtin_find("x"); + nasal_val* val_addr=builtin_find("x"); if(val_addr->type!=vm_num) { builtin_err("tan","\"x\" must be number"); return nullptr; } - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* ret_addr=gc.gc_alloc(vm_num); ret_addr->ptr.num=tan(val_addr->ptr.num); return ret_addr; } -nasal_val* builtin_exp(nasal_val* local_scope) +nasal_val* builtin_exp(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* val_addr=in_builtin_find("x"); + nasal_val* val_addr=builtin_find("x"); if(val_addr->type!=vm_num) { builtin_err("exp","\"x\" must be number"); return nullptr; } - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* ret_addr=gc.gc_alloc(vm_num); ret_addr->ptr.num=exp(val_addr->ptr.num); return ret_addr; } -nasal_val* builtin_ln(nasal_val* local_scope) +nasal_val* builtin_ln(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* val_addr=in_builtin_find("x"); + nasal_val* val_addr=builtin_find("x"); if(val_addr->type!=vm_num) { builtin_err("ln","\"x\" must be number"); return nullptr; } - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* ret_addr=gc.gc_alloc(vm_num); ret_addr->ptr.num=(log(val_addr->ptr.num)/log(2.7182818284590452354)); return ret_addr; } -nasal_val* builtin_sqrt(nasal_val* local_scope) +nasal_val* builtin_sqrt(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* val_addr=in_builtin_find("x"); + nasal_val* val_addr=builtin_find("x"); if(val_addr->type!=vm_num) { builtin_err("sqrt","\"x\" must be number"); return nullptr; } - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* ret_addr=gc.gc_alloc(vm_num); ret_addr->ptr.num=sqrt(val_addr->ptr.num); return ret_addr; } -nasal_val* builtin_atan2(nasal_val* local_scope) +nasal_val* builtin_atan2(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* x_val_addr=in_builtin_find("x"); - nasal_val* y_val_addr=in_builtin_find("y"); + nasal_val* x_val_addr=builtin_find("x"); + nasal_val* y_val_addr=builtin_find("y"); if(x_val_addr->type!=vm_num) { builtin_err("atan2","\"x\" must be number"); @@ -621,27 +621,27 @@ nasal_val* builtin_atan2(nasal_val* local_scope) builtin_err("atan2","\"y\" must be number"); return nullptr; } - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* ret_addr=gc.gc_alloc(vm_num); ret_addr->ptr.num=atan2(y_val_addr->ptr.num,x_val_addr->ptr.num); return ret_addr; } -nasal_val* builtin_time(nasal_val* local_scope) +nasal_val* builtin_time(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* val_addr=in_builtin_find("begin_time"); + nasal_val* val_addr=builtin_find("begin_time"); if(val_addr->type!=vm_num) { builtin_err("time","\"begin_time\" must be number"); return nullptr; } time_t begin_time=(time_t)val_addr->ptr.num; - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* ret_addr=gc.gc_alloc(vm_num); ret_addr->ptr.num=time(&begin_time); return ret_addr; } -nasal_val* builtin_contains(nasal_val* local_scope) +nasal_val* builtin_contains(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* hash_addr=in_builtin_find("hash"); - nasal_val* key_addr=in_builtin_find("key"); + nasal_val* hash_addr=builtin_find("hash"); + nasal_val* key_addr=builtin_find("key"); if(hash_addr->type!=vm_hash) { builtin_err("contains","\"hash\" must be hash"); @@ -652,14 +652,14 @@ nasal_val* builtin_contains(nasal_val* local_scope) builtin_err("contains","\"key\" must be string"); return nullptr; } - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* ret_addr=gc.gc_alloc(vm_num); ret_addr->ptr.num=hash_addr->ptr.hash->check_contain(*key_addr->ptr.str); return ret_addr; } -nasal_val* builtin_delete(nasal_val* local_scope) +nasal_val* builtin_delete(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* hash_addr=in_builtin_find("hash"); - nasal_val* key_addr=in_builtin_find("key"); + nasal_val* hash_addr=builtin_find("hash"); + nasal_val* key_addr=builtin_find("key"); if(hash_addr->type!=vm_hash) { builtin_err("delete","\"hash\" must be hash"); @@ -672,37 +672,37 @@ nasal_val* builtin_delete(nasal_val* local_scope) } if(hash_addr->ptr.hash->elems.count(*key_addr->ptr.str)) hash_addr->ptr.hash->elems.erase(*key_addr->ptr.str); - return nil_addr; + return gc.nil_addr; } -nasal_val* builtin_getkeys(nasal_val* local_scope) +nasal_val* builtin_getkeys(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* hash_addr=in_builtin_find("hash"); + nasal_val* hash_addr=builtin_find("hash"); if(hash_addr->type!=vm_hash) { builtin_err("keys","\"hash\" must be hash"); return nullptr; } - nasal_val* ret_addr=gc_alloc(vm_vec); + nasal_val* ret_addr=gc.gc_alloc(vm_vec); std::vector& ref_vec=ret_addr->ptr.vec->elems; std::unordered_map& ref_hash=hash_addr->ptr.hash->elems; for(auto iter=ref_hash.begin();iter!=ref_hash.end();++iter) { - nasal_val* str_addr=gc_alloc(vm_str); + nasal_val* str_addr=gc.gc_alloc(vm_str); *str_addr->ptr.str=iter->first; ref_vec.push_back(str_addr); } return ret_addr; } -nasal_val* builtin_import(nasal_val* local_scope) +nasal_val* builtin_import(nasal_val* local_scope,nasal_gc& gc) { // this function is used in preprocessing. // this function will return nothing when running. builtin_err("import","cannot use import when running"); return nullptr; } -nasal_val* builtin_die(nasal_val* local_scope) +nasal_val* builtin_die(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* str_addr=in_builtin_find("str"); + nasal_val* str_addr=builtin_find("str"); if(str_addr->type!=vm_str) { builtin_err("die","\"str\" must be string"); @@ -711,10 +711,10 @@ nasal_val* builtin_die(nasal_val* local_scope) std::cout<<">> [vm] error: "<ptr.str<<'\n'; return nullptr; } -nasal_val* builtin_type(nasal_val* local_scope) +nasal_val* builtin_type(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* val_addr=in_builtin_find("object"); - nasal_val* ret_addr=gc_alloc(vm_str); + nasal_val* val_addr=builtin_find("object"); + nasal_val* ret_addr=gc.gc_alloc(vm_str); switch(val_addr->type) { case vm_nil: *ret_addr->ptr.str="nil"; break; @@ -726,11 +726,11 @@ nasal_val* builtin_type(nasal_val* local_scope) } return ret_addr; } -nasal_val* builtin_substr(nasal_val* local_scope) +nasal_val* builtin_substr(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* str_addr=in_builtin_find("str"); - nasal_val* beg_addr=in_builtin_find("begin"); - nasal_val* len_addr=in_builtin_find("length"); + nasal_val* str_addr=builtin_find("str"); + nasal_val* beg_addr=builtin_find("begin"); + nasal_val* len_addr=builtin_find("length"); if(str_addr->type!=vm_str) { builtin_err("substr","\"str\" must be string"); @@ -756,22 +756,22 @@ nasal_val* builtin_substr(nasal_val* local_scope) } if(len<0) len=0; - nasal_val* ret_addr=gc_alloc(vm_str); + nasal_val* ret_addr=gc.gc_alloc(vm_str); *ret_addr->ptr.str=str.substr(beg,len); return ret_addr; } -nasal_val* builtin_streq(nasal_val* local_scope) +nasal_val* builtin_streq(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* a_addr=in_builtin_find("a"); - nasal_val* b_addr=in_builtin_find("b"); - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* a_addr=builtin_find("a"); + nasal_val* b_addr=builtin_find("b"); + nasal_val* ret_addr=gc.gc_alloc(vm_num); ret_addr->ptr.num=(a_addr->type!=vm_str || b_addr->type!=vm_str)?0:(*a_addr->ptr.str==*b_addr->ptr.str); return ret_addr; } -nasal_val* builtin_left(nasal_val* local_scope) +nasal_val* builtin_left(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* str_addr=in_builtin_find("string"); - nasal_val* len_addr=in_builtin_find("length"); + nasal_val* str_addr=builtin_find("string"); + nasal_val* len_addr=builtin_find("length"); if(str_addr->type!=vm_str) { builtin_err("left","\"string\" must be string"); @@ -786,14 +786,14 @@ nasal_val* builtin_left(nasal_val* local_scope) int len=(int)len_addr->ptr.num; if(len<0) len=0; - nasal_val* ret_addr=gc_alloc(vm_str); + nasal_val* ret_addr=gc.gc_alloc(vm_str); *ret_addr->ptr.str=str.substr(0, len); return ret_addr; } -nasal_val* builtin_right(nasal_val* local_scope) +nasal_val* builtin_right(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* str_addr=in_builtin_find("string"); - nasal_val* len_addr=in_builtin_find("length"); + nasal_val* str_addr=builtin_find("string"); + nasal_val* len_addr=builtin_find("length"); if(str_addr->type!=vm_str) { builtin_err("right","\"string\" must be string"); @@ -811,14 +811,14 @@ nasal_val* builtin_right(nasal_val* local_scope) len=srclen; if(len<0) len=0; - nasal_val* ret_addr=gc_alloc(vm_str); + nasal_val* ret_addr=gc.gc_alloc(vm_str); *ret_addr->ptr.str=str.substr(srclen-len, srclen); return ret_addr; } -nasal_val* builtin_cmp(nasal_val* local_scope) +nasal_val* builtin_cmp(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* a_addr=in_builtin_find("a"); - nasal_val* b_addr=in_builtin_find("b"); + nasal_val* a_addr=builtin_find("a"); + nasal_val* b_addr=builtin_find("b"); if(a_addr->type!=vm_str) { builtin_err("cmp","\"a\" must be string"); @@ -829,19 +829,19 @@ nasal_val* builtin_cmp(nasal_val* local_scope) builtin_err("cmp","\"b\" must be string"); return nullptr; } - nasal_val* ret_addr=gc_alloc(vm_num); + nasal_val* ret_addr=gc.gc_alloc(vm_num); ret_addr->ptr.num=strcmp(a_addr->ptr.str->data(),b_addr->ptr.str->data()); return ret_addr; } -nasal_val* builtin_chr(nasal_val* local_scope) +nasal_val* builtin_chr(nasal_val* local_scope,nasal_gc& gc) { - nasal_val* code_addr=in_builtin_find("code"); + nasal_val* code_addr=builtin_find("code"); if(code_addr->type!=vm_num) { builtin_err("chr","\"code\" must be number"); return nullptr; } - nasal_val* ret_addr=gc_alloc(vm_str); + nasal_val* ret_addr=gc.gc_alloc(vm_str); *ret_addr->ptr.str=(char)code_addr->ptr.num; return ret_addr; } diff --git a/nasal_codegen.h b/nasal_codegen.h index 2cf5863..0404243 100644 --- a/nasal_codegen.h +++ b/nasal_codegen.h @@ -48,6 +48,8 @@ enum op_code op_findex, // index counter on the top of forindex_stack plus 1 op_feach, // index counter on the top of forindex_stack plus 1 and get the value in vector op_call, // call identifier + op_callg, + op_calll, op_callv, // call vec[index] op_callvi, // call vec[immediate] (used in multi-assign/multi-define) op_callh, // call hash.label @@ -58,6 +60,8 @@ enum op_code op_slc, // slice like vec[1] op_slc2, // slice like vec[nil:10] op_mcall, // get memory of identifier + op_mcallg, + op_mcalll, op_mcallv, // get memory of vec[index] op_mcallh, // get memory of hash.label op_ret // return @@ -114,6 +118,8 @@ struct {op_findex, "findx "}, {op_feach, "feach "}, {op_call, "call "}, + {op_callg, "callg "}, + {op_calll, "calll "}, {op_callv, "callv "}, {op_callvi, "callvi"}, {op_callh, "callh "}, @@ -124,6 +130,8 @@ struct {op_slc, "slc "}, {op_slc2, "slc2 "}, {op_mcall, "mcall "}, + {op_mcallg, "mcallg"}, + {op_mcalll, "mcalll"}, {op_mcallv, "mcallv"}, {op_mcallh, "mcallh"}, {op_ret, "ret "}, @@ -154,16 +162,20 @@ private: int error; int in_forindex; int in_foreach; - std::unordered_map number_table; - std::unordered_map string_table; - std::vector num_res_table; - std::vector str_res_table; - std::vector exec_code; - std::list > continue_ptr; - std::list > break_ptr; + std::unordered_map number_table; + std::unordered_map string_table; + std::vector num_res_table; + std::vector str_res_table; + std::vector exec_code; + std::list > continue_ptr; + std::list > break_ptr; + std::vector global; + std::list > local; void regist_number(double); - void regist_string(std::string); + void regist_string(std::string&); + void add_sym(std::string&); + bool find_sym(std::string&); void gen(unsigned char,unsigned int); void pop_gen(); void nil_gen(); @@ -224,7 +236,7 @@ void nasal_codegen::regist_number(double num) return; } -void nasal_codegen::regist_string(std::string str) +void nasal_codegen::regist_string(std::string& str) { int size=string_table.size(); if(string_table.find(str)==string_table.end()) @@ -232,6 +244,21 @@ void nasal_codegen::regist_string(std::string str) return; } +void nasal_codegen::add_sym(std::string&) +{ + if(local.empty()) + ; + else + ; + return; +} + +bool nasal_codegen::find_sym(std::string&) +{ + + return false; +} + void nasal_codegen::gen(unsigned char op,unsigned int index) { opcode opr(op,index); @@ -334,7 +361,11 @@ void nasal_codegen::func_gen(nasal_ast& ast) int ptr=exec_code.size(); gen(op_jmp,0); nasal_ast& block=ast.get_children()[1]; + + std::vector new_scope; + local.push_front(new_scope); block_gen(block); + local.pop_front(); if(!block.get_children().size() || block.get_children().back().get_type()!=ast_return) { nil_gen(); diff --git a/nasal_gc.h b/nasal_gc.h index 74f6f3d..6f8c5bc 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -18,25 +18,6 @@ struct nasal_func; struct nasal_scop; struct nasal_val; -nasal_val* zero_addr; // reserved address of nasal_val,type vm_num, 0 -nasal_val* one_addr; // reserved address of nasal_val,type vm_num, 1 -nasal_val* nil_addr; // reserved address of nasal_val,type vm_nil -nasal_val* global; // global scope address,type vm_scop -nasal_val** val_stack; // main stack -nasal_val** stack_top; // stack top -std::vector num_addrs; // reserved address for const vm_num -std::vector local; // local scope for function block -std::vector slice_stack; // slice stack for vec[val,val,val:val] -std::vector memory; // gc memory -std::queue free_list; // gc free list - -/* gc functions */ -void mark(); -void sweep(); -void gc_init(); -void gc_clear(); -nasal_val* gc_alloc(int); - struct nasal_vec { std::vector elems; @@ -183,9 +164,9 @@ nasal_val** nasal_hash::get_mem(std::string& key) int size=vec_ref.size(); for(int i=0;itype==vm_hash) - mem_addr=tmp_val_addr->ptr.hash->get_mem(key); + nasal_val* tmp=vec_ref[i]; + if(tmp->type==vm_hash) + mem_addr=tmp->ptr.hash->get_mem(key); if(mem_addr) return mem_addr; } @@ -345,16 +326,37 @@ std::string nasal_val::to_string() return ""; } -void mark() +struct nasal_gc +{ +#define STACK_MAX_DEPTH (65536<<4) + nasal_val* zero_addr; // reserved address of nasal_val,type vm_num, 0 + nasal_val* one_addr; // reserved address of nasal_val,type vm_num, 1 + nasal_val* nil_addr; // reserved address of nasal_val,type vm_nil + nasal_val* global; // global scope address,type vm_scop + nasal_val** val_stack; // main stack + nasal_val** stack_top; // stack top + std::vector num_addrs; // reserved address for const vm_num + std::vector local; // local scope for function block + std::vector slice_stack; // slice stack for vec[val,val,val:val] + std::vector memory; // gc memory + std::queue free_list; // gc free list + void mark(); + void sweep(); + void gc_init(std::vector&); + void gc_clear(); + nasal_val* gc_alloc(int); +}; + +/* gc functions */ +void nasal_gc::mark() { - int size; std::queue bfs; bfs.push(zero_addr); bfs.push(one_addr); bfs.push(nil_addr); bfs.push(global); - size=num_addrs.size(); + int size=num_addrs.size(); for(int i=0;i& nums) { for(int i=0;i<65536;++i) { @@ -428,9 +430,35 @@ void gc_init() memory.push_back(tmp); free_list.push(tmp); } + val_stack=new nasal_val*[STACK_MAX_DEPTH]; // init runtime stack + stack_top=val_stack; // set stack_top to val_stack + + zero_addr=new nasal_val(vm_num); // init constant 0 + zero_addr->ptr.num=0; + memory.push_back(zero_addr); + + one_addr=new nasal_val(vm_num); // init constant 1 + one_addr->ptr.num=1; + memory.push_back(one_addr); + + nil_addr=new nasal_val(vm_nil); // init nil + memory.push_back(nil_addr); + + *val_stack=nil_addr; // the first space will not store any values,but gc checks + + global=new nasal_val(vm_scop); // init global symbol table + memory.push_back(global); + + num_addrs.clear(); // init constant numbers + for(int i=0;iptr.num=nums[i]; + num_addrs.push_back(tmp); + } return; } -void gc_clear() +void nasal_gc::gc_clear() { int size=memory.size(); for(int i=0;i str_table; // symbols used in process - bool loop_mark; // when mark is false,break the main loop - int pc; // program counter - int me_index; // this is the index of "me" in str_table - std::vector exec_code; // byte codes store here - std::stack addr_stack; // stack for mem_call - std::stack call_stack; // ptr stack stores address for function to return - std::stack counter; // iterator stack for forindex/foreach + /* reference from nasal_gc */ + nasal_val**& stack_top; // stack top + /* values of nasal_vm */ + int pc; // program counter + int me; // this is the index of "me" in str_table + 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 void die(std::string); - bool check_condition(nasal_val*); + bool condition(nasal_val*); void opr_nop(); void opr_load(); void opr_loadg(); @@ -61,6 +64,8 @@ private: void opr_findex(); void opr_feach(); void opr_call(); + void opr_callg(); + void opr_calll(); void opr_callv(); void opr_callvi(); void opr_callh(); @@ -71,10 +76,13 @@ private: void opr_slc(); void opr_slc2(); void opr_mcall(); + void opr_mcallg(); + void opr_mcalll(); void opr_mcallv(); void opr_mcallh(); void opr_ret(); public: + nasal_vm(); void init( std::vector&, std::vector&, @@ -83,63 +91,36 @@ public: void run(); }; +nasal_vm::nasal_vm():stack_top(gc.stack_top) +{ + return; +} + void nasal_vm::init( std::vector& strs, - std::vector& nums, - std::vector& exec) + std::vector& nums, + std::vector& exec) { - gc_init(); + gc.gc_init(nums); str_table=strs; // get constant strings & symbols exec_code=exec; // get bytecodes - val_stack=new nasal_val*[STACK_MAX_DEPTH]; // init runtime stack - stack_top=val_stack; // set stack_top to val_stack - - zero_addr=new nasal_val(vm_num); // init constant 0 - zero_addr->ptr.num=0; - memory.push_back(zero_addr); - - one_addr=new nasal_val(vm_num); // init constant 1 - one_addr->ptr.num=1; - memory.push_back(one_addr); - - nil_addr=new nasal_val(vm_nil); // init nil - memory.push_back(nil_addr); - - *val_stack=nil_addr; // the first space will not store any values,but gc checks - - num_addrs.clear(); // init constant numbers - for(int i=0;iptr.num=nums[i]; - num_addrs.push_back(tmp); - } - - builtin_use_str_table.clear(); // create map that builtin functions use + builtin_use_str.clear(); // create map that builtin functions use for(int i=0;itype; if(type==vm_num) @@ -175,65 +156,64 @@ void nasal_vm::opr_nop() void nasal_vm::opr_load() { nasal_val* val=*stack_top--; - (local.empty()?global:local.back())->ptr.scop->elems[exec_code[pc].num]=val; + (gc.local.empty()?gc.global:gc.local.back())->ptr.scop->elems[exec_code[pc].num]=val; return; } void nasal_vm::opr_loadg() { - global->ptr.scop->elems[exec_code[pc].num]=*stack_top--; + gc.global->ptr.scop->elems[exec_code[pc].num]=*stack_top--; return; } void nasal_vm::opr_loadl() { - local.back()->ptr.scop->elems[exec_code[pc].num]=*stack_top--; + gc.local.back()->ptr.scop->elems[exec_code[pc].num]=*stack_top--; return; } void nasal_vm::opr_pnum() { - nasal_val* val=num_addrs[exec_code[pc].num]; - *(++stack_top)=val; + *(++stack_top)=gc.num_addrs[exec_code[pc].num]; return; } void nasal_vm::opr_pone() { - *(++stack_top)=one_addr; + *(++stack_top)=gc.one_addr; return; } void nasal_vm::opr_pzero() { - *(++stack_top)=zero_addr; + *(++stack_top)=gc.zero_addr; return; } void nasal_vm::opr_pnil() { - *(++stack_top)=nil_addr; + *(++stack_top)=gc.nil_addr; return; } void nasal_vm::opr_pstr() { - nasal_val* val=gc_alloc(vm_str); + nasal_val* val=gc.gc_alloc(vm_str); *val->ptr.str=str_table[exec_code[pc].num]; *(++stack_top)=val; return; } void nasal_vm::opr_newv() { - nasal_val* vec=gc_alloc(vm_vec); + nasal_val* vec=gc.gc_alloc(vm_vec); *(++stack_top)=vec; return; } void nasal_vm::opr_newh() { - nasal_val* hash=gc_alloc(vm_hash); + nasal_val* hash=gc.gc_alloc(vm_hash); *(++stack_top)=hash; return; } void nasal_vm::opr_newf() { - nasal_val* val=gc_alloc(vm_func); + nasal_val* val=gc.gc_alloc(vm_func); val->ptr.func->entry=exec_code[pc].num; - if(!local.empty()) - val->ptr.func->closure=local.back()->ptr.scop->elems; + if(!gc.local.empty()) + val->ptr.func->closure=gc.local.back()->ptr.scop->elems; *(++stack_top)=val; return; } @@ -273,16 +253,16 @@ void nasal_vm::opr_unot() nasal_val* new_val=nullptr; int type=val->type; if(type==vm_nil) - new_val=one_addr; + new_val=gc.one_addr; else if(type==vm_num) - new_val=val->ptr.num?zero_addr:one_addr; + new_val=val->ptr.num?gc.zero_addr:gc.one_addr; else if(type==vm_str) { double number=trans_string_to_number(*val->ptr.str); if(std::isnan(number)) - new_val=val->ptr.str->length()?zero_addr:one_addr; + new_val=val->ptr.str->length()?gc.zero_addr:gc.one_addr; else - new_val=number?zero_addr:one_addr; + new_val=number?gc.zero_addr:gc.one_addr; } else die("unot: incorrect value type"); @@ -292,14 +272,14 @@ void nasal_vm::opr_unot() void nasal_vm::opr_usub() { nasal_val* val=*stack_top; - nasal_val* new_val=gc_alloc(vm_num); + nasal_val* new_val=gc.gc_alloc(vm_num); new_val->ptr.num=-val->to_number(); *stack_top=new_val; return; } void nasal_vm::opr_add() { - nasal_val* new_val=gc_alloc(vm_num); + nasal_val* new_val=gc.gc_alloc(vm_num); nasal_val* val2=*stack_top--; nasal_val* val1=*stack_top; new_val->ptr.num=val1->to_number()+val2->to_number(); @@ -308,7 +288,7 @@ void nasal_vm::opr_add() } void nasal_vm::opr_sub() { - nasal_val* new_val=gc_alloc(vm_num); + nasal_val* new_val=gc.gc_alloc(vm_num); nasal_val* val2=*stack_top--; nasal_val* val1=*stack_top; new_val->ptr.num=val1->to_number()-val2->to_number(); @@ -317,7 +297,7 @@ void nasal_vm::opr_sub() } void nasal_vm::opr_mul() { - nasal_val* new_val=gc_alloc(vm_num); + nasal_val* new_val=gc.gc_alloc(vm_num); nasal_val* val2=*stack_top--; nasal_val* val1=*stack_top; new_val->ptr.num=val1->to_number()*val2->to_number(); @@ -326,7 +306,7 @@ void nasal_vm::opr_mul() } void nasal_vm::opr_div() { - nasal_val* new_val=gc_alloc(vm_num); + nasal_val* new_val=gc.gc_alloc(vm_num); nasal_val* val2=*stack_top--; nasal_val* val1=*stack_top; new_val->ptr.num=val1->to_number()/val2->to_number(); @@ -335,7 +315,7 @@ void nasal_vm::opr_div() } void nasal_vm::opr_lnk() { - nasal_val* new_val=gc_alloc(vm_str); + nasal_val* new_val=gc.gc_alloc(vm_str); nasal_val* val2=*stack_top--; nasal_val* val1=*stack_top; *new_val->ptr.str=val1->to_string()+val2->to_string(); @@ -348,7 +328,7 @@ void nasal_vm::opr_addeq() addr_stack.pop(); nasal_val* val2=*stack_top; nasal_val* val1=*mem_addr; - nasal_val* new_val=gc_alloc(vm_num); + nasal_val* new_val=gc.gc_alloc(vm_num); new_val->ptr.num=val1->to_number()+val2->to_number(); *stack_top=new_val; *mem_addr=new_val; @@ -360,7 +340,7 @@ void nasal_vm::opr_subeq() addr_stack.pop(); nasal_val* val2=*stack_top; nasal_val* val1=*mem_addr; - nasal_val* new_val=gc_alloc(vm_num); + nasal_val* new_val=gc.gc_alloc(vm_num); new_val->ptr.num=val1->to_number()-val2->to_number(); *stack_top=new_val; *mem_addr=new_val; @@ -372,7 +352,7 @@ void nasal_vm::opr_muleq() addr_stack.pop(); nasal_val* val2=*stack_top; nasal_val* val1=*mem_addr; - nasal_val* new_val=gc_alloc(vm_num); + nasal_val* new_val=gc.gc_alloc(vm_num); new_val->ptr.num=val1->to_number()*val2->to_number(); *stack_top=new_val; *mem_addr=new_val; @@ -384,7 +364,7 @@ void nasal_vm::opr_diveq() addr_stack.pop(); nasal_val* val2=*stack_top; nasal_val* val1=*mem_addr; - nasal_val* new_val=gc_alloc(vm_num); + nasal_val* new_val=gc.gc_alloc(vm_num); new_val->ptr.num=val1->to_number()/val2->to_number(); *stack_top=new_val; *mem_addr=new_val; @@ -396,7 +376,7 @@ void nasal_vm::opr_lnkeq() addr_stack.pop(); nasal_val* val2=*stack_top; nasal_val* val1=*mem_addr; - nasal_val* new_val=gc_alloc(vm_str); + nasal_val* new_val=gc.gc_alloc(vm_str); *new_val->ptr.str=val1->to_string()+val2->to_string(); *stack_top=new_val; *mem_addr=new_val; @@ -412,13 +392,13 @@ void nasal_vm::opr_meq() } void nasal_vm::opr_eq() { - nasal_val* new_val=gc_alloc(vm_num); + nasal_val* new_val=gc.gc_alloc(vm_num); nasal_val* val2=*stack_top--; nasal_val* val1=*stack_top; int a_type=val1->type; int b_type=val2->type; if(a_type==vm_nil && b_type==vm_nil) - *stack_top=one_addr; + *stack_top=gc.one_addr; else if(a_type==vm_str && b_type==vm_str) { new_val->ptr.num=(*val1->ptr.str==*val2->ptr.str); @@ -438,13 +418,13 @@ void nasal_vm::opr_eq() } void nasal_vm::opr_neq() { - nasal_val* new_val=gc_alloc(vm_num); + nasal_val* new_val=gc.gc_alloc(vm_num); nasal_val* val2=*stack_top--; nasal_val* val1=*stack_top; int a_type=val1->type; int b_type=val2->type; if(a_type==vm_nil && b_type==vm_nil) - *stack_top=zero_addr; + *stack_top=gc.zero_addr; else if(a_type==vm_str && b_type==vm_str) { new_val->ptr.num=(*val1->ptr.str!=*val2->ptr.str); @@ -464,7 +444,7 @@ void nasal_vm::opr_neq() } void nasal_vm::opr_less() { - nasal_val* new_val=gc_alloc(vm_num); + nasal_val* new_val=gc.gc_alloc(vm_num); nasal_val* val2=*stack_top--; nasal_val* val1=*stack_top; int a_type=val1->type; @@ -478,7 +458,7 @@ void nasal_vm::opr_less() } void nasal_vm::opr_leq() { - nasal_val* new_val=gc_alloc(vm_num); + nasal_val* new_val=gc.gc_alloc(vm_num); nasal_val* val2=*stack_top--; nasal_val* val1=*stack_top; int a_type=val1->type; @@ -492,7 +472,7 @@ void nasal_vm::opr_leq() } void nasal_vm::opr_grt() { - nasal_val* new_val=gc_alloc(vm_num); + nasal_val* new_val=gc.gc_alloc(vm_num); nasal_val* val2=*stack_top--; nasal_val* val1=*stack_top; int a_type=val1->type; @@ -506,7 +486,7 @@ void nasal_vm::opr_grt() } void nasal_vm::opr_geq() { - nasal_val* new_val=gc_alloc(vm_num); + nasal_val* new_val=gc.gc_alloc(vm_num); nasal_val* val2=*stack_top--; nasal_val* val1=*stack_top; int a_type=val1->type; @@ -530,13 +510,13 @@ void nasal_vm::opr_jmp() } void nasal_vm::opr_jt() { - if(check_condition(*stack_top)) + if(condition(*stack_top)) pc=exec_code[pc].num-1; return; } void nasal_vm::opr_jf() { - if(!check_condition(*stack_top)) + if(!condition(*stack_top)) pc=exec_code[pc].num-1; --stack_top; return; @@ -563,7 +543,7 @@ void nasal_vm::opr_findex() pc=exec_code[pc].num-1; return; } - nasal_val* res=gc_alloc(vm_num); + nasal_val* res=gc.gc_alloc(vm_num); res->ptr.num=counter.top(); *(++stack_top)=res; return; @@ -585,14 +565,14 @@ void nasal_vm::opr_call() { nasal_val* val=nullptr; int name_index=exec_code[pc].num; - if(!local.empty()) - val=local.back()->ptr.scop->get_val(name_index); + if(!gc.local.empty()) + val=gc.local.back()->ptr.scop->get_val(name_index); if(val) { *(++stack_top)=val; return; } - val=global->ptr.scop->get_val(name_index); + val=gc.global->ptr.scop->get_val(name_index); if(val) { *(++stack_top)=val; @@ -601,6 +581,16 @@ void nasal_vm::opr_call() die("call: cannot find symbol named \""+str_table[name_index]+"\""); return; } +void nasal_vm::opr_callg() +{ + *(++stack_top)=gc.global->ptr.scop->elems[exec_code[pc].num]; + return; +} +void nasal_vm::opr_calll() +{ + *(++stack_top)=gc.local.back()->ptr.scop->elems[exec_code[pc].num]; + return; +} void nasal_vm::opr_callv() { nasal_val* val=*stack_top--; @@ -632,7 +622,7 @@ void nasal_vm::opr_callv() return; } if(res->type==vm_func) - res->ptr.func->closure[me_index]=val; + res->ptr.func->closure[me]=val; *stack_top=res; } else if(type==vm_str) @@ -645,7 +635,7 @@ void nasal_vm::opr_callv() die("callv: index out of range"); return; } - nasal_val* res=gc_alloc(vm_num); + nasal_val* res=gc.gc_alloc(vm_num); res->ptr.num=(str[num>=0? num:num+str_size]); *stack_top=res; } @@ -686,7 +676,7 @@ void nasal_vm::opr_callh() return; } if(res->type==vm_func) - res->ptr.func->closure[me_index]=val; + res->ptr.func->closure[me]=val; *stack_top=res; return; } @@ -701,8 +691,8 @@ void nasal_vm::opr_callf() return; } // push new local scope - nasal_val* closure=gc_alloc(vm_scop); - local.push_back(closure); + nasal_val* closure=gc.gc_alloc(vm_scop); + gc.local.push_back(closure); // load parameters nasal_func& ref_func=*func_addr->ptr.func; std::vector& ref_para=ref_func.para; @@ -731,7 +721,7 @@ void nasal_vm::opr_callf() } if(ref_func.dynpara>=0) { - nasal_val* vec_addr=gc_alloc(vm_vec); + nasal_val* vec_addr=gc.gc_alloc(vm_vec); for(int i=para_size;iptr.vec->elems.push_back(ref_vec[i]); ref_closure[ref_func.dynpara]=vec_addr; @@ -760,28 +750,28 @@ void nasal_vm::opr_callf() } } --stack_top; - call_stack.push(pc); + ret.push(pc); pc=ref_func.entry-1; return; } void nasal_vm::opr_callb() { - nasal_val* res=(*builtin_func[exec_code[pc].num].func)(local.back()); + nasal_val* res=(*builtin_func[exec_code[pc].num].func)(gc.local.back(),gc); *(++stack_top)=res; loop_mark=res; return; } void nasal_vm::opr_slcbegin() { - slice_stack.push_back(gc_alloc(vm_vec)); + gc.slice_stack.push_back(gc.gc_alloc(vm_vec)); if((*stack_top)->type!=vm_vec) die("slcbegin: must slice a vector"); return; } void nasal_vm::opr_slcend() { - *stack_top=slice_stack.back(); - slice_stack.pop_back(); + *stack_top=gc.slice_stack.back(); + gc.slice_stack.pop_back(); return; } void nasal_vm::opr_slc() @@ -796,7 +786,7 @@ void nasal_vm::opr_slc() } nasal_val* res=(*stack_top)->ptr.vec->get_val((int)num); if(res) - slice_stack.back()->ptr.vec->elems.push_back(res); + gc.slice_stack.back()->ptr.vec->elems.push_back(res); else die("slc: index out of range"); return; @@ -806,7 +796,7 @@ void nasal_vm::opr_slc2() nasal_val* val2=*stack_top--; nasal_val* val1=*stack_top--; std::vector& ref=(*stack_top)->ptr.vec->elems; - std::vector& aim=slice_stack.back()->ptr.vec->elems; + std::vector& aim=gc.slice_stack.back()->ptr.vec->elems; int type1=val1->type,type2=val2->type; int num1=val1->to_number(); @@ -833,24 +823,21 @@ void nasal_vm::opr_slc2() return; } for(int i=num1;i<=num2;++i) - { - nasal_val* tmp=ref[i]; - aim.push_back(tmp); - } + aim.push_back(ref[i]); return; } void nasal_vm::opr_mcall() { nasal_val** mem_addr=nullptr; int name_index=exec_code[pc].num; - if(!local.empty()) - mem_addr=local.back()->ptr.scop->get_mem(name_index); + if(!gc.local.empty()) + mem_addr=gc.local.back()->ptr.scop->get_mem(name_index); if(mem_addr) { addr_stack.push(mem_addr); return; } - mem_addr=global->ptr.scop->get_mem(name_index); + mem_addr=gc.global->ptr.scop->get_mem(name_index); if(mem_addr) { addr_stack.push(mem_addr); @@ -859,6 +846,16 @@ void nasal_vm::opr_mcall() die("mcall: cannot find symbol named \""+str_table[name_index]+"\""); return; } +void nasal_vm::opr_mcallg() +{ + addr_stack.push(&gc.global->ptr.scop->elems[exec_code[pc].num]); + return; +} +void nasal_vm::opr_mcalll() +{ + addr_stack.push(&gc.local.back()->ptr.scop->elems[exec_code[pc].num]); + return; +} void nasal_vm::opr_mcallv() { nasal_val* val=*stack_top--; @@ -890,11 +887,11 @@ void nasal_vm::opr_mcallv() return; } nasal_hash& ref=*(*vec_addr)->ptr.hash; - std::string str=*val->ptr.str; + std::string& str=*val->ptr.str; nasal_val** res=ref.get_mem(str); if(!res) { - ref.elems[str]=nil_addr; + ref.elems[str]=gc.nil_addr; res=ref.get_mem(str); } addr_stack.push(res); @@ -921,7 +918,7 @@ void nasal_vm::opr_mcallh() mem_addr=ref.get_mem(str); if(!mem_addr) // create a new key { - ref.elems[str]=nil_addr; + ref.elems[str]=gc.nil_addr; mem_addr=ref.get_mem(str); } addr_stack.push(mem_addr); @@ -929,9 +926,9 @@ void nasal_vm::opr_mcallh() } void nasal_vm::opr_ret() { - local.pop_back(); - pc=call_stack.top(); - call_stack.pop(); + gc.local.pop_back(); + pc=ret.top(); + ret.pop(); nasal_val* ret_val=*stack_top--; *stack_top=ret_val; return; @@ -985,6 +982,8 @@ void nasal_vm::run() &nasal_vm::opr_findex, &nasal_vm::opr_feach, &nasal_vm::opr_call, + &nasal_vm::opr_callg, + &nasal_vm::opr_calll, &nasal_vm::opr_callv, &nasal_vm::opr_callvi, &nasal_vm::opr_callh, @@ -995,6 +994,8 @@ void nasal_vm::run() &nasal_vm::opr_slc, &nasal_vm::opr_slc2, &nasal_vm::opr_mcall, + &nasal_vm::opr_mcallg, + &nasal_vm::opr_mcalll, &nasal_vm::opr_mcallv, &nasal_vm::opr_mcallh, &nasal_vm::opr_ret @@ -1003,7 +1004,6 @@ void nasal_vm::run() // main loop for(pc=0;loop_mark;++pc) (this->*opr_table[exec_code[pc].op])(); - float total_time=((double)(clock()-begin_time))/CLOCKS_PER_SEC; std::cout<<">> [vm] process exited after "<0.001) } cnt+=1; show+=1; - if(show==150) + if(show==200) { show=0; print('epoch ',cnt,':',error,'\r'); diff --git a/test/pi.nas b/test/pi.nas new file mode 100644 index 0000000..9e81f2e --- /dev/null +++ b/test/pi.nas @@ -0,0 +1,10 @@ +import("lib.nas"); + +var t=1; +var res=0; +for(var m=1;m<1e6;m+=2) +{ + res+=t*1/m; + t*=-1; +} +println(res*4); \ No newline at end of file