diff --git a/README.md b/README.md index 85e7854..b8c2ccc 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ You could add your own built-in functions to change this interpreter to a useful Better choose the latest update of the interpreter. -MUST USE -O2 ! pragma gcc optimize(2) seems useless when using g++ +MUST USE -O2/-O3 if want to optimize the interpreter! pragma gcc optimize(2) seems useless when using g++ > g++ -std=c++11 -O2 main.cpp -o nasal.exe diff --git a/nasal_gc.h b/nasal_gc.h index aa5ab2f..870483c 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -234,7 +234,7 @@ std::string nasal_val::to_string() struct nasal_gc { -#define STACK_MAX_DEPTH (65536<<1) +#define STACK_MAX_DEPTH (65536) 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 diff --git a/nasal_lexer.h b/nasal_lexer.h index eb48f47..24391ec 100644 --- a/nasal_lexer.h +++ b/nasal_lexer.h @@ -104,7 +104,7 @@ private: std::vector res; std::vector token_list; int get_tok_type(std::string&); - void die(std::string,int); + void die(const char*); std::string id_gen(); std::string num_gen(); std::string str_gen(); @@ -147,13 +147,13 @@ int nasal_lexer::get_tok_type(std::string& tk_str) return tok_null; } -void nasal_lexer::die(std::string error_info,int line) +void nasal_lexer::die(const char* error_info) { ++error; std::cout<<">> [lexer] line "< [0~9][0~9]*(.[0~9]*)(e|E(+|-)0|[1~9][0~9]*) + std::string token_str=""; while(ptr=res_size) - { - line_code+=token_str; - die("incorrect number.",line); - return "0"; - } while(ptr=res_size) - { - line_code+=token_str; - die("incorrect number.",line); - return "0"; - } if(ptr=res_size) - { - line_code+=token_str; - die("incorrect number.",line); - return "0"; - } while(ptr=res_size) - die("get EOF when generating string.",line); - if(str_begin=='`' && token_str.length()>1) - die("\'`\' is used for string that includes one character.",line); + die("get EOF when generating string."); + if(str_begin=='`' && token_str.length()!=1) + die("\'`\' is used for string that includes one character."); return token_str; } @@ -334,24 +307,21 @@ void nasal_lexer::scanner() else if(IS_DIGIT(res[ptr])) { token_str=num_gen(); - token new_token(line,tok_num,token_str); - token_list.push_back(new_token); + token_list.push_back({line,tok_num,token_str}); } else if(IS_STRING(res[ptr])) { token_str=str_gen(); - token new_token(line,tok_str,token_str); - token_list.push_back(new_token); + token_list.push_back({line,tok_str,token_str}); } else if(IS_SINGLE_OPERATOR(res[ptr])) { - token_str=""; - token_str+=res[ptr]; + token_str=res[ptr]; line_code+=res[ptr]; - token new_token(line,get_tok_type(token_str),token_str); - if(!new_token.type) - die("incorrect operator.",line); - token_list.push_back(new_token); + int type=get_tok_type(token_str); + if(!type) + die("incorrect operator."); + token_list.push_back({line,type,token_str}); ++ptr; } else if(res[ptr]=='.') @@ -367,8 +337,7 @@ void nasal_lexer::scanner() ++ptr; } line_code+=token_str; - token new_token(line,get_tok_type(token_str),token_str); - token_list.push_back(new_token); + token_list.push_back({line,get_tok_type(token_str),token_str}); } else if(IS_CALC_OPERATOR(res[ptr])) { @@ -377,19 +346,17 @@ void nasal_lexer::scanner() if(ptr err_lines; - err_lines.push_back(error_token[0].line); - for(auto& tok:error_token) - if(err_lines.back()!=tok.line) - err_lines.push_back(tok.line); ++error; - std::cout<<">> [parse] error tokens in line"; - for(auto& line:err_lines) - std::cout<<' '<> [parse] line"; + int err_line=0; + for(auto& tok:error_token) + if(err_line!=tok.line) + { + std::cout<<' '<> [parse] line "<=tok_for)// token_table begins at tok_for - s=token_table[type-tok_for].str; switch(type) { case tok_num:die(error_line,"expected number"); break; case tok_str:die(error_line,"expected string"); break; case tok_id: die(error_line,"expected identifier");break; - default: die(error_line,"expected \'"+s+"\'"); break; + default: die(error_line,"expected \'"+std::string(token_table[type-tok_for].str)+"\'"); break; } return; } @@ -628,7 +625,7 @@ nasal_ast nasal_parse::scalar() if(tok_list[ptr].type==tok_nil) {node=nil_gen(); match(tok_nil);} else if(tok_list[ptr].type==tok_num){node=num_gen(); match(tok_num);} else if(tok_list[ptr].type==tok_str){node=str_gen(); match(tok_str);} - else if(tok_list[ptr].type==tok_id) {node= id_gen(); match(tok_id );} + else if(tok_list[ptr].type==tok_id) {node=id_gen(); match(tok_id); } else if(tok_list[ptr].type==tok_func) { if(tok_list[ptr+1].type==tok_id) diff --git a/nasal_vm.h b/nasal_vm.h index 02fc863..c7c5221 100644 --- a/nasal_vm.h +++ b/nasal_vm.h @@ -7,12 +7,14 @@ private: /* reference from nasal_gc */ nasal_val**& stack_top;// stack top /* values of nasal_vm */ - int pc; // program counter + uint32_t 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::vector + exec_code;//function pointer + std::vector imm; // immediate number nasal_val** mem_addr; // used for mem_call nasal_gc gc; // garbage collector @@ -98,7 +100,76 @@ void nasal_vm::init( gc.gc_init(nums,strs); gc.val_stack[STACK_MAX_DEPTH-1]=nullptr; str_table=strs; // get constant strings & symbols - exec_code=exec; // get bytecodes + void (nasal_vm::*opr_table[])()= + { + &nasal_vm::opr_nop, + &nasal_vm::opr_intg, + &nasal_vm::opr_intl, + &nasal_vm::opr_offset, + &nasal_vm::opr_loadg, + &nasal_vm::opr_loadl, + &nasal_vm::opr_pnum, + &nasal_vm::opr_pone, + &nasal_vm::opr_pzero, + &nasal_vm::opr_pnil, + &nasal_vm::opr_pstr, + &nasal_vm::opr_newv, + &nasal_vm::opr_newh, + &nasal_vm::opr_newf, + &nasal_vm::opr_happ, + &nasal_vm::opr_para, + &nasal_vm::opr_defpara, + &nasal_vm::opr_dynpara, + &nasal_vm::opr_unot, + &nasal_vm::opr_usub, + &nasal_vm::opr_add, + &nasal_vm::opr_sub, + &nasal_vm::opr_mul, + &nasal_vm::opr_div, + &nasal_vm::opr_lnk, + &nasal_vm::opr_addeq, + &nasal_vm::opr_subeq, + &nasal_vm::opr_muleq, + &nasal_vm::opr_diveq, + &nasal_vm::opr_lnkeq, + &nasal_vm::opr_meq, + &nasal_vm::opr_eq, + &nasal_vm::opr_neq, + &nasal_vm::opr_less, + &nasal_vm::opr_leq, + &nasal_vm::opr_grt, + &nasal_vm::opr_geq, + &nasal_vm::opr_pop, + &nasal_vm::opr_jmp, + &nasal_vm::opr_jt, + &nasal_vm::opr_jf, + &nasal_vm::opr_counter, + &nasal_vm::opr_cntpop, + &nasal_vm::opr_findex, + &nasal_vm::opr_feach, + &nasal_vm::opr_callg, + &nasal_vm::opr_calll, + &nasal_vm::opr_callv, + &nasal_vm::opr_callvi, + &nasal_vm::opr_callh, + &nasal_vm::opr_callfv, + &nasal_vm::opr_callfh, + &nasal_vm::opr_callb, + &nasal_vm::opr_slcbegin, + &nasal_vm::opr_slcend, + &nasal_vm::opr_slc, + &nasal_vm::opr_slc2, + &nasal_vm::opr_mcallg, + &nasal_vm::opr_mcalll, + &nasal_vm::opr_mcallv, + &nasal_vm::opr_mcallh, + &nasal_vm::opr_ret + }; + for(auto& i:exec) + { + exec_code.push_back(opr_table[i.op]); + imm.push_back(i.num); + } loop_mark=true; // set loop mark to true return; } @@ -140,32 +211,32 @@ void nasal_vm::opr_nop() } void nasal_vm::opr_intg() { - gc.global.resize(exec_code[pc].num,gc.nil_addr); + gc.global.resize(imm[pc],gc.nil_addr); return; } void nasal_vm::opr_intl() { - stack_top[0]->ptr.func->closure.resize(exec_code[pc].num,gc.nil_addr); + stack_top[0]->ptr.func->closure.resize(imm[pc],gc.nil_addr); return; } void nasal_vm::opr_offset() { - stack_top[0]->ptr.func->offset=exec_code[pc].num; + stack_top[0]->ptr.func->offset=imm[pc]; return; } void nasal_vm::opr_loadg() { - gc.global[exec_code[pc].num]=*stack_top--; + gc.global[imm[pc]]=(stack_top--)[0]; return; } void nasal_vm::opr_loadl() { - gc.local.back()[exec_code[pc].num]=*stack_top--; + gc.local.back()[imm[pc]]=(stack_top--)[0]; return; } void nasal_vm::opr_pnum() { - (++stack_top)[0]=gc.num_addrs[exec_code[pc].num]; + (++stack_top)[0]=gc.num_addrs[imm[pc]]; return; } void nasal_vm::opr_pone() @@ -185,19 +256,19 @@ void nasal_vm::opr_pnil() } void nasal_vm::opr_pstr() { - (++stack_top)[0]=gc.str_addrs[exec_code[pc].num]; + (++stack_top)[0]=gc.str_addrs[imm[pc]]; return; } void nasal_vm::opr_newv() { nasal_val* vec_addr=gc.gc_alloc(vm_vec); - nasal_val** begin=stack_top-exec_code[pc].num+1; - auto& vec=vec_addr->ptr.vec->elems;// stack_top-exec_code[pc].num stores the vector - vec.resize(exec_code[pc].num); - for(int i=0;iptr.vec->elems;// stack_top-imm[pc] stores the vector + vec.resize(imm[pc]); + for(int i=0;iptr.func->entry=exec_code[pc].num; + val->ptr.func->entry=imm[pc]; if(gc.local.empty()) val->ptr.func->closure.push_back(gc.nil_addr);// me else @@ -219,14 +290,14 @@ void nasal_vm::opr_newf() void nasal_vm::opr_happ() { nasal_val* val=stack_top[0]; - (--stack_top)[0]->ptr.hash->elems[str_table[exec_code[pc].num]]=val; + (--stack_top)[0]->ptr.hash->elems[str_table[imm[pc]]]=val; return; } void nasal_vm::opr_para() { nasal_func* func=stack_top[0]->ptr.func; int size=func->key_table.size(); - func->key_table[str_table[exec_code[pc].num]]=size; + func->key_table[str_table[imm[pc]]]=size; func->default_para.push_back(nullptr); return; } @@ -235,13 +306,13 @@ void nasal_vm::opr_defpara() nasal_val* def_val=stack_top[0]; nasal_func* func=(--stack_top)[0]->ptr.func; int size=func->key_table.size(); - func->key_table[str_table[exec_code[pc].num]]=size; + func->key_table[str_table[imm[pc]]]=size; func->default_para.push_back(def_val); return; } void nasal_vm::opr_dynpara() { - stack_top[0]->ptr.func->dynpara=exec_code[pc].num; + stack_top[0]->ptr.func->dynpara=imm[pc]; return; } void nasal_vm::opr_unot() @@ -380,42 +451,26 @@ void nasal_vm::opr_neq() } void nasal_vm::opr_less() { - nasal_val* val2=stack_top[0]; - nasal_val* val1=(--stack_top)[0]; - if(val1->type==vm_str && val2->type==vm_str) - stack_top[0]=(*val1->ptr.str<*val2->ptr.str)?gc.one_addr:gc.zero_addr; - else - stack_top[0]=(val1->to_number()to_number())?gc.one_addr:gc.zero_addr; + --stack_top; + stack_top[0]=(stack_top[0]->to_number()to_number())?gc.one_addr:gc.zero_addr; return; } void nasal_vm::opr_leq() { - nasal_val* val2=stack_top[0]; - nasal_val* val1=(--stack_top)[0]; - if(val1->type==vm_str && val2->type==vm_str) - stack_top[0]=(*val1->ptr.str<=*val2->ptr.str)?gc.one_addr:gc.zero_addr; - else - stack_top[0]=(val1->to_number()<=val2->to_number())?gc.one_addr:gc.zero_addr; + --stack_top; + stack_top[0]=(stack_top[0]->to_number()<=stack_top[1]->to_number())?gc.one_addr:gc.zero_addr; return; } void nasal_vm::opr_grt() { - nasal_val* val2=stack_top[0]; - nasal_val* val1=(--stack_top)[0]; - if(val1->type==vm_str && val2->type==vm_str) - stack_top[0]=(*val1->ptr.str>*val2->ptr.str)?gc.one_addr:gc.zero_addr; - else - stack_top[0]=(val1->to_number()>val2->to_number())?gc.one_addr:gc.zero_addr; + --stack_top; + stack_top[0]=(stack_top[0]->to_number()>stack_top[1]->to_number())?gc.one_addr:gc.zero_addr; return; } void nasal_vm::opr_geq() { - nasal_val* val2=stack_top[0]; - nasal_val* val1=(--stack_top)[0]; - if(val1->type==vm_str && val2->type==vm_str) - stack_top[0]=(*val1->ptr.str>=*val2->ptr.str)?gc.one_addr:gc.zero_addr; - else - stack_top[0]=(val1->to_number()>=val2->to_number())?gc.one_addr:gc.zero_addr; + --stack_top; + stack_top[0]=(stack_top[0]->to_number()>=stack_top[1]->to_number())?gc.one_addr:gc.zero_addr; return; } void nasal_vm::opr_pop() @@ -425,19 +480,19 @@ void nasal_vm::opr_pop() } void nasal_vm::opr_jmp() { - pc=exec_code[pc].num-1; + pc=imm[pc]-1; return; } void nasal_vm::opr_jt() { if(condition(stack_top[0])) - pc=exec_code[pc].num-1; + pc=imm[pc]-1; return; } void nasal_vm::opr_jf() { if(!condition(stack_top[0])) - pc=exec_code[pc].num-1; + pc=imm[pc]-1; --stack_top; return; } @@ -457,12 +512,11 @@ void nasal_vm::opr_findex() { if(++counter.top()>=stack_top[0]->ptr.vec->elems.size()) { - pc=exec_code[pc].num-1; + pc=imm[pc]-1; return; } - nasal_val* res=gc.gc_alloc(vm_num); - res->ptr.num=counter.top(); - (++stack_top)[0]=res; + (++stack_top)[0]=gc.gc_alloc(vm_num); + stack_top[0]->ptr.num=counter.top(); return; } void nasal_vm::opr_feach() @@ -470,7 +524,7 @@ void nasal_vm::opr_feach() std::vector& ref=stack_top[0]->ptr.vec->elems; if(++counter.top()>=ref.size()) { - pc=exec_code[pc].num-1; + pc=imm[pc]-1; return; } (++stack_top)[0]=ref[counter.top()]; @@ -478,12 +532,12 @@ void nasal_vm::opr_feach() } void nasal_vm::opr_callg() { - (++stack_top)[0]=gc.global[exec_code[pc].num]; + (++stack_top)[0]=gc.global[imm[pc]]; return; } void nasal_vm::opr_calll() { - (++stack_top)[0]=gc.local.back()[exec_code[pc].num]; + (++stack_top)[0]=gc.local.back()[imm[pc]]; return; } void nasal_vm::opr_callv() @@ -493,10 +547,9 @@ void nasal_vm::opr_callv() 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:"+val->to_string()); - stack_top[0]=res; + stack_top[0]=vec_addr->ptr.vec->get_val(val->to_number()); + if(!stack_top[0]) + die("callv: index out of range:"+num2str(val->to_number())); } else if(type==vm_hash) { @@ -505,15 +558,14 @@ void nasal_vm::opr_callv() die("callv: must use string as the key"); return; } - nasal_val* res=vec_addr->ptr.hash->get_val(*val->ptr.str); - if(!res) + stack_top[0]=vec_addr->ptr.hash->get_val(*val->ptr.str); + if(!stack_top[0]) { die("callv: cannot find member \""+*val->ptr.str+"\" of this hash"); return; } - if(res->type==vm_func) - res->ptr.func->closure[0]=val;// me - stack_top[0]=res; + if(stack_top[0]->type==vm_func) + stack_top[0]->ptr.func->closure[0]=val;// me } else if(type==vm_str) { @@ -522,12 +574,11 @@ void nasal_vm::opr_callv() int str_size=str.length(); if(num<-str_size || num>=str_size) { - die("callv: index out of range:"+val->to_string()); + die("callv: index out of range:"+num2str(val->to_number())); return; } - nasal_val* res=gc.gc_alloc(vm_num); - res->ptr.num=(str[num>=0? num:num+str_size]); - stack_top[0]=res; + stack_top[0]=gc.gc_alloc(vm_num); + stack_top[0]->ptr.num=(str[num>=0? num:num+str_size]); } else die("callv: must call a vector/hash/string"); @@ -542,10 +593,9 @@ void nasal_vm::opr_callvi() return; } // 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:"+num2str(exec_code[pc].num)); - (++stack_top)[0]=res; + (++stack_top)[0]=val->ptr.vec->get_val(imm[pc]); + if(!stack_top[0]) + die("callvi: index out of range:"+num2str(imm[pc])); return; } void nasal_vm::opr_callh() @@ -556,23 +606,22 @@ void nasal_vm::opr_callh() die("callh: must call a hash"); return; } - nasal_val* res=val->ptr.hash->get_val(str_table[exec_code[pc].num]); - if(!res) + stack_top[0]=val->ptr.hash->get_val(str_table[imm[pc]]); + if(!stack_top[0]) { - die("callh: hash member \""+str_table[exec_code[pc].num]+"\" does not exist"); + die("callh: member \""+str_table[imm[pc]]+"\" does not exist"); return; } - if(res->type==vm_func) - res->ptr.func->closure[0]=val;// me - stack_top[0]=res; + if(stack_top[0]->type==vm_func) + stack_top[0]->ptr.func->closure[0]=val;// me return; } void nasal_vm::opr_callfv() { // get parameter list and function value - int args_size=exec_code[pc].num; + int args_size=imm[pc]; nasal_val** vec=stack_top-args_size+1; - nasal_val* func_addr=*(vec-1); + nasal_val* func_addr=vec[-1]; if(func_addr->type!=vm_func) { die("callfv: must call a function"); @@ -584,10 +633,9 @@ void nasal_vm::opr_callfv() // load parameters auto& ref_default=ref_func.default_para; auto& ref_closure=gc.local.back(); - auto& ref_keys=ref_func.key_table; int offset=ref_func.offset; - int para_size=ref_keys.size(); + int para_size=ref_func.key_table.size(); // load arguments if(args_sizepara_size,for 0 to args_size will cause corruption for(int i=0;i=args_size)?ref_default[i]:vec[i]; + ref_closure[i+offset]=(i=para_size if(ref_func.dynpara>=0) { @@ -615,7 +663,7 @@ void nasal_vm::opr_callfv() void nasal_vm::opr_callfh() { // get parameter list and function value - std::unordered_map& ref_hash=(*stack_top)->ptr.hash->elems; + auto& ref_hash=stack_top[0]->ptr.hash->elems; nasal_val* func_addr=stack_top[-1]; if(func_addr->type!=vm_func) { @@ -628,7 +676,6 @@ void nasal_vm::opr_callfh() // load parameters auto& ref_default=ref_func.default_para; auto& ref_closure=gc.local.back(); - auto& ref_keys=ref_func.key_table; if(ref_func.dynpara>=0) { @@ -636,7 +683,7 @@ void nasal_vm::opr_callfh() return; } int offset=ref_func.offset; - for(auto& i:ref_keys) + for(auto& i:ref_func.key_table) { if(ref_hash.count(i.first)) ref_closure[i.second+offset]=ref_hash[i.first]; @@ -656,9 +703,7 @@ void nasal_vm::opr_callfh() } void nasal_vm::opr_callb() { - nasal_val* res=(*builtin_func[exec_code[pc].num].func)(gc.local.back(),gc); - (++stack_top)[0]=res; - loop_mark=res; + loop_mark=(++stack_top)[0]=(*builtin_func[imm[pc]].func)(gc.local.back(),gc); return; } void nasal_vm::opr_slcbegin() @@ -676,24 +721,17 @@ void nasal_vm::opr_slcend() } void nasal_vm::opr_slc() { - nasal_val* val=*stack_top--; - int num; - switch(val->type) - { - case vm_num:num=(int)val->ptr.num;break; - case vm_str:num=(int)str2num(val->ptr.str->c_str());break; - default:die("slc: error value type");break; - } - nasal_val* res=stack_top[0]->ptr.vec->get_val(num); + nasal_val* val=(stack_top--)[0]; + nasal_val* res=stack_top[0]->ptr.vec->get_val(val->to_number()); if(!res) - die("slc: index out of range:"+num2str(num)); + die("slc: index out of range:"+num2str(val->to_number())); gc.slice_stack.back()->ptr.vec->elems.push_back(res); return; } void nasal_vm::opr_slc2() { - nasal_val* val2=*stack_top--; - nasal_val* val1=*stack_top--; + nasal_val* val2=(stack_top--)[0]; + nasal_val* val1=(stack_top--)[0]; std::vector& ref=stack_top[0]->ptr.vec->elems; std::vector& aim=gc.slice_stack.back()->ptr.vec->elems; @@ -732,13 +770,13 @@ void nasal_vm::opr_slc2() } void nasal_vm::opr_mcallg() { - mem_addr=&gc.global[exec_code[pc].num]; + mem_addr=&gc.global[imm[pc]]; (++stack_top)[0]=mem_addr[0]; return; } void nasal_vm::opr_mcalll() { - mem_addr=&gc.local.back()[exec_code[pc].num]; + mem_addr=&gc.local.back()[imm[pc]]; (++stack_top)[0]=mem_addr[0]; return; } @@ -749,16 +787,9 @@ void nasal_vm::opr_mcallv() int type=vec_addr->type; if(type==vm_vec) { - int num; - switch(val->type) - { - case vm_num:num=(int)val->ptr.num;break; - case vm_str:num=(int)str2num(val->ptr.str->c_str());break; - default:die("mcallv: error value type");break; - } - mem_addr=vec_addr->ptr.vec->get_mem(num); + mem_addr=vec_addr->ptr.vec->get_mem(val->to_number()); if(!mem_addr) - die("mcallv: index out of range:"+num2str(num)); + die("mcallv: index out of range:"+num2str(val->to_number())); } else if(type==vm_hash) { @@ -789,7 +820,7 @@ void nasal_vm::opr_mcallh() return; } nasal_hash& ref=*hash_addr->ptr.hash; - std::string& str=str_table[exec_code[pc].num]; + std::string& str=str_table[imm[pc]]; mem_addr=ref.get_mem(str); if(!mem_addr) // create a new key { @@ -800,89 +831,20 @@ void nasal_vm::opr_mcallh() } void nasal_vm::opr_ret() { - gc.local.pop_back(); - pc=ret.top(); - ret.pop(); - nasal_val* ret_val=stack_top[0]; - (--stack_top)[0]->ptr.func->closure[0]=gc.nil_addr;// set me to nil - stack_top[0]=ret_val; + 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[0]=stack_top[1];// rewrite nasal_func with returned value return; } void nasal_vm::run() { - void (nasal_vm::*opr_table[])()= - { - &nasal_vm::opr_nop, - &nasal_vm::opr_intg, - &nasal_vm::opr_intl, - &nasal_vm::opr_offset, - &nasal_vm::opr_loadg, - &nasal_vm::opr_loadl, - &nasal_vm::opr_pnum, - &nasal_vm::opr_pone, - &nasal_vm::opr_pzero, - &nasal_vm::opr_pnil, - &nasal_vm::opr_pstr, - &nasal_vm::opr_newv, - &nasal_vm::opr_newh, - &nasal_vm::opr_newf, - &nasal_vm::opr_happ, - &nasal_vm::opr_para, - &nasal_vm::opr_defpara, - &nasal_vm::opr_dynpara, - &nasal_vm::opr_unot, - &nasal_vm::opr_usub, - &nasal_vm::opr_add, - &nasal_vm::opr_sub, - &nasal_vm::opr_mul, - &nasal_vm::opr_div, - &nasal_vm::opr_lnk, - &nasal_vm::opr_addeq, - &nasal_vm::opr_subeq, - &nasal_vm::opr_muleq, - &nasal_vm::opr_diveq, - &nasal_vm::opr_lnkeq, - &nasal_vm::opr_meq, - &nasal_vm::opr_eq, - &nasal_vm::opr_neq, - &nasal_vm::opr_less, - &nasal_vm::opr_leq, - &nasal_vm::opr_grt, - &nasal_vm::opr_geq, - &nasal_vm::opr_pop, - &nasal_vm::opr_jmp, - &nasal_vm::opr_jt, - &nasal_vm::opr_jf, - &nasal_vm::opr_counter, - &nasal_vm::opr_cntpop, - &nasal_vm::opr_findex, - &nasal_vm::opr_feach, - &nasal_vm::opr_callg, - &nasal_vm::opr_calll, - &nasal_vm::opr_callv, - &nasal_vm::opr_callvi, - &nasal_vm::opr_callh, - &nasal_vm::opr_callfv, - &nasal_vm::opr_callfh, - &nasal_vm::opr_callb, - &nasal_vm::opr_slcbegin, - &nasal_vm::opr_slcend, - &nasal_vm::opr_slc, - &nasal_vm::opr_slc2, - &nasal_vm::opr_mcallg, - &nasal_vm::opr_mcalll, - &nasal_vm::opr_mcallv, - &nasal_vm::opr_mcallh, - &nasal_vm::opr_ret - }; clock_t begin_time=clock(); - // main loop for(pc=0;loop_mark&&!gc.val_stack[STACK_MAX_DEPTH-1];++pc) - (this->*opr_table[exec_code[pc].op])(); - float total_time=((double)(clock()-begin_time))/CLOCKS_PER_SEC; + (this->*exec_code[pc])(); if(gc.val_stack[STACK_MAX_DEPTH-1]) die("stack overflow"); - std::cout<<">> [vm] process exited after "<> [vm] process exited after "<<((double)(clock()-begin_time))/CLOCKS_PER_SEC<<"s.\n"; return; } #endif \ No newline at end of file diff --git a/test/bp.nas b/test/bp.nas index 9e03fb8..f2bbbae 100644 --- a/test/bp.nas +++ b/test/bp.nas @@ -123,9 +123,7 @@ var backward=func(x) return; } -var cnt=0; -var show=0; -var error=100; +var (cnt,error)=(0,100); while(error>0.0005) { error=0; @@ -136,12 +134,6 @@ while(error>0.0005) backward(i); } cnt+=1; - show+=1; - if(show==350) - { - show=0; - print('epoch ',cnt,':',error,'\r'); - } } print('finished after ',cnt,' epoch.\n'); foreach(var v;training_set) diff --git a/test/mandelbrot.nas b/test/mandelbrot.nas index 08e031b..3f2eaf0 100644 --- a/test/mandelbrot.nas +++ b/test/mandelbrot.nas @@ -1,31 +1,27 @@ import("lib.nas"); -var yMin=-0.2; -var yMax=0.2; -var xMin=-1.5; -var xMax=-1.0; +var (yMin,yMax,xMin,xMax,line)=(-0.2,0.2,-1.5,-1.0,""); +var (yDel,xDel)=(yMax-yMin,xMax-xMin); for(var yPixel=0;yPixel<24;yPixel+=1) { - var y=(yPixel/24)*(yMax-yMin)+yMin; + var y=(yPixel/24)*yDel+yMin; for(var xPixel=0;xPixel<80;xPixel+=1) { - var x=(xPixel/80)*(xMax-xMin)+xMin; + var x=(xPixel/80)*xDel+xMin; var pixel=" "; - var x0=x; - var y0=y; + var (x0,y0)=(x,y); for(var iter=0;iter<80;iter+=1) { var x1=(x0*x0)-(y0*y0)+x; var y1=2*x0*y0+y; - x0=x1; - y0=y1; - var d=(x0*x0)+(y0*y0); - if(d>4) + (x0,y0)=(x1,y1); + if((x0*x0)+(y0*y0)>4) { - pixel=chr(" .:;+=xX$&"[int(iter/8)]); + pixel=chr(" .:;+=xX$&"[iter/8]); break; } } - print(pixel); + line~=pixel; } - print('\n'); -} \ No newline at end of file + line~='\n'; +} +print(line); \ No newline at end of file diff --git a/test/pi.nas b/test/pi.nas index abd945c..0622050 100644 --- a/test/pi.nas +++ b/test/pi.nas @@ -1,10 +1,9 @@ import("lib.nas"); -var t=1; -var res=0; +var (t,res)=(1,0); for(var m=1;m<4e6;m+=2) { res+=t*1/m; - t*=-1; + t=-t; } println(res*4); \ No newline at end of file