diff --git a/nasal_codegen.h b/nasal_codegen.h index 8337aa8..ffa4ebd 100644 --- a/nasal_codegen.h +++ b/nasal_codegen.h @@ -50,6 +50,10 @@ enum op_code op_leq, // <= op_grt, // > op_geq, // >= + op_lessc, // < const + op_leqc, // <= const + op_grtc, // > const + op_geqc, // >= const op_pop, // pop a value from stack op_jmp, // jump with no condition op_jt, // used in operator and/or,jmp when condition is true and DO NOT POP @@ -130,6 +134,10 @@ struct {op_leq, "leq "}, {op_grt, "grt "}, {op_geq, "geq "}, + {op_lessc, "lessc "}, + {op_leqc, "leqc "}, + {op_grtc, "grtc "}, + {op_geqc, "geqc "}, {op_pop, "pop "}, {op_jmp, "jmp "}, {op_jt, "jt "}, @@ -161,8 +169,8 @@ struct struct opcode { uint8_t op; - int32_t num; - opcode(uint8_t _op=op_nop,int32_t _num=0) + uint32_t num; + opcode(uint8_t _op=op_nop,uint32_t _num=0) { op=_op; num=_num; @@ -198,7 +206,7 @@ private: void add_sym(std::string&); int local_find(std::string&); int global_find(std::string&); - void gen(uint8_t,int32_t); + void gen(uint8_t,uint32_t); void num_gen(nasal_ast&); void str_gen(nasal_ast&); void vec_gen(nasal_ast&); @@ -303,7 +311,7 @@ int nasal_codegen::global_find(std::string& name) return -1; } -void nasal_codegen::gen(uint8_t op,int32_t num) +void nasal_codegen::gen(uint8_t op,uint32_t num) { exec_code.push_back({op,num}); return; @@ -987,11 +995,24 @@ void nasal_codegen::calc_gen(nasal_ast& ast) } break; // ast_cmpeq(27)~ast_geq(32) op_eq(29)~op_geq(34) - case ast_cmpeq:case ast_neq:case ast_less:case ast_leq:case ast_grt:case ast_geq: + case ast_cmpeq:case ast_neq: calc_gen(ast.get_children()[0]); calc_gen(ast.get_children()[1]); gen(ast.get_type()-ast_cmpeq+op_eq,0); break; + case ast_less:case ast_leq:case ast_grt:case ast_geq: + calc_gen(ast.get_children()[0]); + if(ast.get_children()[1].get_type()!=ast_num) + { + calc_gen(ast.get_children()[1]); + gen(ast.get_type()-ast_less+op_less,0); + } + else + { + regist_number(ast.get_children()[1].get_num()); + gen(ast.get_type()-ast_less+op_lessc,number_table[ast.get_children()[1].get_num()]); + } + break; case ast_trino:trino_gen(ast);break; case ast_neg: calc_gen(ast.get_children()[0]); @@ -1186,6 +1207,7 @@ void nasal_codegen::print_op(int index) { case op_addc:case op_subc:case op_mulc:case op_divc: case op_addeqc:case op_subeqc:case op_muleqc:case op_diveqc: + case op_lessc:case op_leqc:case op_grtc:case op_geqc: case op_pnum:printf(" (%lf)\n",num_res_table[exec_code[index].num]);break; case op_callb:printf(" (%s)\n",builtin_func[exec_code[index].num].name);break; case op_happ: diff --git a/nasal_gc.h b/nasal_gc.h index 36e33d7..8370cc9 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) +#define STACK_MAX_DEPTH (4096) 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 @@ -271,19 +271,23 @@ void nasal_gc::mark() bfs.pop(); if(tmp->mark) continue; tmp->mark=GC_FOUND; - if(tmp->type==vm_vec) - for(auto i:tmp->ptr.vec->elems) - bfs.push(i); - else if(tmp->type==vm_hash) - for(auto& i:tmp->ptr.hash->elems) - bfs.push(i.second); - else if(tmp->type==vm_func) + switch(tmp->type) { - for(auto i:tmp->ptr.func->closure) - bfs.push(i); - for(auto i:tmp->ptr.func->default_para) - if(i) + case vm_vec: + for(auto i:tmp->ptr.vec->elems) bfs.push(i); + break; + case vm_hash: + for(auto& i:tmp->ptr.hash->elems) + bfs.push(i.second); + break; + case vm_func: + for(auto i:tmp->ptr.func->closure) + bfs.push(i); + for(auto i:tmp->ptr.func->default_para) + if(i) + bfs.push(i); + break; } } return; diff --git a/nasal_vm.h b/nasal_vm.h index 406b6fc..0826608 100644 --- a/nasal_vm.h +++ b/nasal_vm.h @@ -11,7 +11,7 @@ private: 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 imm; // immediate number + std::vector imm; // immediate number nasal_val** mem_addr; // used for mem_call nasal_gc gc; // garbage collector @@ -63,6 +63,10 @@ private: void opr_leq(); void opr_grt(); void opr_geq(); + void opr_lessc(); + void opr_leqc(); + void opr_grtc(); + void opr_geqc(); void opr_pop(); void opr_jmp(); void opr_jt(); @@ -474,6 +478,26 @@ inline void nasal_vm::opr_geq() stack_top[0]=(stack_top[0]->to_number()>=stack_top[1]->to_number())?gc.one_addr:gc.zero_addr; return; } +inline void nasal_vm::opr_lessc() +{ + stack_top[0]=(stack_top[0]->to_number()ptr.num)?gc.one_addr:gc.zero_addr; + return; +} +inline void nasal_vm::opr_leqc() +{ + stack_top[0]=(stack_top[0]->to_number()<=gc.num_addrs[imm[pc]]->ptr.num)?gc.one_addr:gc.zero_addr; + return; +} +inline void nasal_vm::opr_grtc() +{ + stack_top[0]=(stack_top[0]->to_number()>gc.num_addrs[imm[pc]]->ptr.num)?gc.one_addr:gc.zero_addr; + return; +} +inline void nasal_vm::opr_geqc() +{ + stack_top[0]=(stack_top[0]->to_number()>=gc.num_addrs[imm[pc]]->ptr.num)?gc.one_addr:gc.zero_addr; + return; +} inline void nasal_vm::opr_pop() { --stack_top; @@ -841,7 +865,7 @@ inline void nasal_vm::opr_ret() } void nasal_vm::run(std::vector& exec) { - int count[72]={0}; + // int count[op_ret]={0}; void* opr_table[]= { &&nop, &&intg, &&intl, &&offset, @@ -855,7 +879,8 @@ void nasal_vm::run(std::vector& exec) &&muleq, &&diveq, &&lnkeq, &&addeqc, &&subeqc, &&muleqc, &&diveqc, &&lnkeqc, &&meq, &&eq, &&neq, &&less, - &&leq, &&grt, &&geq, &&pop, + &&leq, &&grt, &&geq, &&lessc, + &&leqc, &&grtc, &&geqc, &&pop, &&jmp, &&jt, &&jf, &&counter, &&cntpop, &&findex, &&feach, &&callg, &&calll, &&callv, &&callvi, &&callh, @@ -939,30 +964,34 @@ less: exec_operand(opr_less ,43); leq: exec_operand(opr_leq ,44); grt: exec_operand(opr_grt ,45); geq: exec_operand(opr_geq ,46); -pop: exec_operand(opr_pop ,47); -jmp: exec_operand(opr_jmp ,48); -jt: exec_operand(opr_jt ,49); -jf: exec_operand(opr_jf ,50); -counter: exec_operand(opr_counter ,51); -cntpop: exec_operand(opr_cntpop ,52); -findex: exec_operand(opr_findex ,53); -feach: exec_operand(opr_feach ,54); -callg: exec_operand(opr_callg ,55); -calll: exec_operand(opr_calll ,56); -callv: exec_operand(opr_callv ,57); -callvi: exec_operand(opr_callvi ,58); -callh: exec_operand(opr_callh ,59); -callfv: exec_operand(opr_callfv ,60); -callfh: exec_operand(opr_callfh ,61); -callb: exec_operand(opr_callb ,62); -slcbegin:exec_operand(opr_slcbegin,63); -slcend: exec_operand(opr_slcend ,64); -slc: exec_operand(opr_slc ,65); -slc2: exec_operand(opr_slc2 ,66); -mcallg: exec_operand(opr_mcallg ,67); -mcalll: exec_operand(opr_mcalll ,68); -mcallv: exec_operand(opr_mcallv ,69); -mcallh: exec_operand(opr_mcallh ,70); -ret: exec_operand(opr_ret ,71); +lessc: exec_operand(opr_lessc ,47); +leqc: exec_operand(opr_leqc ,48); +grtc: exec_operand(opr_grtc ,49); +geqc: exec_operand(opr_geqc ,50); +pop: exec_operand(opr_pop ,51); +jmp: exec_operand(opr_jmp ,52); +jt: exec_operand(opr_jt ,53); +jf: exec_operand(opr_jf ,54); +counter: exec_operand(opr_counter ,55); +cntpop: exec_operand(opr_cntpop ,56); +findex: exec_operand(opr_findex ,57); +feach: exec_operand(opr_feach ,58); +callg: exec_operand(opr_callg ,59); +calll: exec_operand(opr_calll ,60); +callv: exec_operand(opr_callv ,61); +callvi: exec_operand(opr_callvi ,62); +callh: exec_operand(opr_callh ,63); +callfv: exec_operand(opr_callfv ,64); +callfh: exec_operand(opr_callfh ,65); +callb: exec_operand(opr_callb ,66); +slcbegin:exec_operand(opr_slcbegin,67); +slcend: exec_operand(opr_slcend ,68); +slc: exec_operand(opr_slc ,69); +slc2: exec_operand(opr_slc2 ,70); +mcallg: exec_operand(opr_mcallg ,71); +mcalll: exec_operand(opr_mcalll ,72); +mcallv: exec_operand(opr_mcallv ,73); +mcallh: exec_operand(opr_mcallh ,74); +ret: exec_operand(opr_ret ,75); } #endif \ No newline at end of file diff --git a/test/lexer.nas b/test/lexer.nas index eb3872a..94304de 100644 --- a/test/lexer.nas +++ b/test/lexer.nas @@ -2,22 +2,23 @@ import("lib.nas"); var lexer=func(file) { - var _={s:io.fin(file),len:0,ptr:0,token:[]}; - _.len=size(_.s); + var _={ptr:0,token:[]}; + var s=io.fin(file); + var len=size(s); return { jmp_note:func() { - while(_.ptr<_.len and chr(_.s[_.ptr])!='\n') + while(_.ptr=_.len) + if(_.ptr>=len) print("read eof when generating string.\n"); _.ptr+=1; append(_.token,str); }, num_gen:func() { - var number=chr(_.s[_.ptr]); + var number=chr(s[_.ptr]); _.ptr+=1; - if(_.ptr<_.len and chr(_.s[_.ptr])=='x') + if(_.ptr' or c=='<' or c=='!' or c=='=') { var tmp=c; _.ptr+=1; - if(_.ptr<_.len and chr(_.s[_.ptr])=='=') + if(_.ptr0) + elsif(c!=' ' and c!='\t' and c!='\n' and c!='\r' and s[_.ptr]>0) append(_.token,c); _.ptr+=1; return; }, main:func() { - while(_.ptr<_.len) + while(_.ptr