add const compare instructions

This commit is contained in:
ValKmjolnir 2021-07-03 15:22:23 +08:00
parent 0b2fe61e6e
commit 57d6bcdc52
4 changed files with 140 additions and 84 deletions

View File

@ -50,6 +50,10 @@ enum op_code
op_leq, // <= op_leq, // <=
op_grt, // > op_grt, // >
op_geq, // >= op_geq, // >=
op_lessc, // < const
op_leqc, // <= const
op_grtc, // > const
op_geqc, // >= const
op_pop, // pop a value from stack op_pop, // pop a value from stack
op_jmp, // jump with no condition op_jmp, // jump with no condition
op_jt, // used in operator and/or,jmp when condition is true and DO NOT POP 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_leq, "leq "},
{op_grt, "grt "}, {op_grt, "grt "},
{op_geq, "geq "}, {op_geq, "geq "},
{op_lessc, "lessc "},
{op_leqc, "leqc "},
{op_grtc, "grtc "},
{op_geqc, "geqc "},
{op_pop, "pop "}, {op_pop, "pop "},
{op_jmp, "jmp "}, {op_jmp, "jmp "},
{op_jt, "jt "}, {op_jt, "jt "},
@ -161,8 +169,8 @@ struct
struct opcode struct opcode
{ {
uint8_t op; uint8_t op;
int32_t num; uint32_t num;
opcode(uint8_t _op=op_nop,int32_t _num=0) opcode(uint8_t _op=op_nop,uint32_t _num=0)
{ {
op=_op; op=_op;
num=_num; num=_num;
@ -198,7 +206,7 @@ private:
void add_sym(std::string&); void add_sym(std::string&);
int local_find(std::string&); int local_find(std::string&);
int global_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 num_gen(nasal_ast&);
void str_gen(nasal_ast&); void str_gen(nasal_ast&);
void vec_gen(nasal_ast&); void vec_gen(nasal_ast&);
@ -303,7 +311,7 @@ int nasal_codegen::global_find(std::string& name)
return -1; 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}); exec_code.push_back({op,num});
return; return;
@ -987,11 +995,24 @@ void nasal_codegen::calc_gen(nasal_ast& ast)
} }
break; break;
// ast_cmpeq(27)~ast_geq(32) op_eq(29)~op_geq(34) // 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()[0]);
calc_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
gen(ast.get_type()-ast_cmpeq+op_eq,0); gen(ast.get_type()-ast_cmpeq+op_eq,0);
break; 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_trino:trino_gen(ast);break;
case ast_neg: case ast_neg:
calc_gen(ast.get_children()[0]); 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_addc:case op_subc:case op_mulc:case op_divc:
case op_addeqc:case op_subeqc:case op_muleqc:case op_diveqc: 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_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_callb:printf(" (%s)\n",builtin_func[exec_code[index].num].name);break;
case op_happ: case op_happ:

View File

@ -234,7 +234,7 @@ std::string nasal_val::to_string()
struct nasal_gc 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* 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* 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* nil_addr; // reserved address of nasal_val,type vm_nil
@ -271,19 +271,23 @@ void nasal_gc::mark()
bfs.pop(); bfs.pop();
if(tmp->mark) continue; if(tmp->mark) continue;
tmp->mark=GC_FOUND; tmp->mark=GC_FOUND;
if(tmp->type==vm_vec) switch(tmp->type)
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)
{ {
for(auto i:tmp->ptr.func->closure) case vm_vec:
bfs.push(i); for(auto i:tmp->ptr.vec->elems)
for(auto i:tmp->ptr.func->default_para)
if(i)
bfs.push(i); 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; return;

View File

@ -11,7 +11,7 @@ private:
std::stack<int> ret; // ptr stack stores address for function to return std::stack<int> ret; // ptr stack stores address for function to return
std::stack<int> counter; // iterator stack for forindex/foreach std::stack<int> counter; // iterator stack for forindex/foreach
std::vector<std::string> str_table;// symbols used in process std::vector<std::string> str_table;// symbols used in process
std::vector<int32_t> imm; // immediate number std::vector<uint32_t> imm; // immediate number
nasal_val** mem_addr; // used for mem_call nasal_val** mem_addr; // used for mem_call
nasal_gc gc; // garbage collector nasal_gc gc; // garbage collector
@ -63,6 +63,10 @@ private:
void opr_leq(); void opr_leq();
void opr_grt(); void opr_grt();
void opr_geq(); void opr_geq();
void opr_lessc();
void opr_leqc();
void opr_grtc();
void opr_geqc();
void opr_pop(); void opr_pop();
void opr_jmp(); void opr_jmp();
void opr_jt(); 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; stack_top[0]=(stack_top[0]->to_number()>=stack_top[1]->to_number())?gc.one_addr:gc.zero_addr;
return; return;
} }
inline void nasal_vm::opr_lessc()
{
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_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() inline void nasal_vm::opr_pop()
{ {
--stack_top; --stack_top;
@ -841,7 +865,7 @@ inline void nasal_vm::opr_ret()
} }
void nasal_vm::run(std::vector<opcode>& exec) void nasal_vm::run(std::vector<opcode>& exec)
{ {
int count[72]={0}; // int count[op_ret]={0};
void* opr_table[]= void* opr_table[]=
{ {
&&nop, &&intg, &&intl, &&offset, &&nop, &&intg, &&intl, &&offset,
@ -855,7 +879,8 @@ void nasal_vm::run(std::vector<opcode>& exec)
&&muleq, &&diveq, &&lnkeq, &&addeqc, &&muleq, &&diveq, &&lnkeq, &&addeqc,
&&subeqc, &&muleqc, &&diveqc, &&lnkeqc, &&subeqc, &&muleqc, &&diveqc, &&lnkeqc,
&&meq, &&eq, &&neq, &&less, &&meq, &&eq, &&neq, &&less,
&&leq, &&grt, &&geq, &&pop, &&leq, &&grt, &&geq, &&lessc,
&&leqc, &&grtc, &&geqc, &&pop,
&&jmp, &&jt, &&jf, &&counter, &&jmp, &&jt, &&jf, &&counter,
&&cntpop, &&findex, &&feach, &&callg, &&cntpop, &&findex, &&feach, &&callg,
&&calll, &&callv, &&callvi, &&callh, &&calll, &&callv, &&callvi, &&callh,
@ -939,30 +964,34 @@ less: exec_operand(opr_less ,43);
leq: exec_operand(opr_leq ,44); leq: exec_operand(opr_leq ,44);
grt: exec_operand(opr_grt ,45); grt: exec_operand(opr_grt ,45);
geq: exec_operand(opr_geq ,46); geq: exec_operand(opr_geq ,46);
pop: exec_operand(opr_pop ,47); lessc: exec_operand(opr_lessc ,47);
jmp: exec_operand(opr_jmp ,48); leqc: exec_operand(opr_leqc ,48);
jt: exec_operand(opr_jt ,49); grtc: exec_operand(opr_grtc ,49);
jf: exec_operand(opr_jf ,50); geqc: exec_operand(opr_geqc ,50);
counter: exec_operand(opr_counter ,51); pop: exec_operand(opr_pop ,51);
cntpop: exec_operand(opr_cntpop ,52); jmp: exec_operand(opr_jmp ,52);
findex: exec_operand(opr_findex ,53); jt: exec_operand(opr_jt ,53);
feach: exec_operand(opr_feach ,54); jf: exec_operand(opr_jf ,54);
callg: exec_operand(opr_callg ,55); counter: exec_operand(opr_counter ,55);
calll: exec_operand(opr_calll ,56); cntpop: exec_operand(opr_cntpop ,56);
callv: exec_operand(opr_callv ,57); findex: exec_operand(opr_findex ,57);
callvi: exec_operand(opr_callvi ,58); feach: exec_operand(opr_feach ,58);
callh: exec_operand(opr_callh ,59); callg: exec_operand(opr_callg ,59);
callfv: exec_operand(opr_callfv ,60); calll: exec_operand(opr_calll ,60);
callfh: exec_operand(opr_callfh ,61); callv: exec_operand(opr_callv ,61);
callb: exec_operand(opr_callb ,62); callvi: exec_operand(opr_callvi ,62);
slcbegin:exec_operand(opr_slcbegin,63); callh: exec_operand(opr_callh ,63);
slcend: exec_operand(opr_slcend ,64); callfv: exec_operand(opr_callfv ,64);
slc: exec_operand(opr_slc ,65); callfh: exec_operand(opr_callfh ,65);
slc2: exec_operand(opr_slc2 ,66); callb: exec_operand(opr_callb ,66);
mcallg: exec_operand(opr_mcallg ,67); slcbegin:exec_operand(opr_slcbegin,67);
mcalll: exec_operand(opr_mcalll ,68); slcend: exec_operand(opr_slcend ,68);
mcallv: exec_operand(opr_mcallv ,69); slc: exec_operand(opr_slc ,69);
mcallh: exec_operand(opr_mcallh ,70); slc2: exec_operand(opr_slc2 ,70);
ret: exec_operand(opr_ret ,71); 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 #endif

View File

@ -2,22 +2,23 @@ import("lib.nas");
var lexer=func(file) var lexer=func(file)
{ {
var _={s:io.fin(file),len:0,ptr:0,token:[]}; var _={ptr:0,token:[]};
_.len=size(_.s); var s=io.fin(file);
var len=size(s);
return return
{ {
jmp_note:func() jmp_note:func()
{ {
while(_.ptr<_.len and chr(_.s[_.ptr])!='\n') while(_.ptr<len and chr(s[_.ptr])!='\n')
_.ptr+=1; _.ptr+=1;
_.ptr+=1; _.ptr+=1;
}, },
id_gen:func() id_gen:func()
{ {
var tmp=""; var tmp="";
while(_.ptr<_.len) while(_.ptr<len)
{ {
var c=_.s[_.ptr]; var c=s[_.ptr];
if(('a'[0]<=c and c<='z'[0]) if(('a'[0]<=c and c<='z'[0])
or ('A'[0]<=c and c<='Z'[0]) or ('A'[0]<=c and c<='Z'[0])
or ('0'[0]<=c and c<='9'[0]) or ('0'[0]<=c and c<='9'[0])
@ -32,14 +33,14 @@ var lexer=func(file)
str_gen:func() str_gen:func()
{ {
var str=""; var str="";
var mark=chr(_.s[_.ptr]); var mark=chr(s[_.ptr]);
_.ptr+=1; _.ptr+=1;
while(_.ptr<_.len and chr(_.s[_.ptr])!=mark) while(_.ptr<len and chr(s[_.ptr])!=mark)
{ {
if(chr(_.s[_.ptr])=='\\') if(chr(s[_.ptr])=='\\')
{ {
_.ptr+=1; _.ptr+=1;
var c=chr(_.s[_.ptr]); var c=chr(s[_.ptr]);
if (c=='a' ) str~='\a'; if (c=='a' ) str~='\a';
elsif(c=='b' ) str~='\b'; elsif(c=='b' ) str~='\b';
elsif(c=='f' ) str~='\f'; elsif(c=='f' ) str~='\f';
@ -55,69 +56,69 @@ var lexer=func(file)
else str~=c; else str~=c;
} }
else else
str~=chr(_.s[_.ptr]); str~=chr(s[_.ptr]);
_.ptr+=1; _.ptr+=1;
} }
if(_.ptr>=_.len) if(_.ptr>=len)
print("read eof when generating string.\n"); print("read eof when generating string.\n");
_.ptr+=1; _.ptr+=1;
append(_.token,str); append(_.token,str);
}, },
num_gen:func() num_gen:func()
{ {
var number=chr(_.s[_.ptr]); var number=chr(s[_.ptr]);
_.ptr+=1; _.ptr+=1;
if(_.ptr<_.len and chr(_.s[_.ptr])=='x') if(_.ptr<len and chr(s[_.ptr])=='x')
{ {
_.ptr+=1; _.ptr+=1;
while(_.ptr<_.len and while(_.ptr<len and
('a'[0]<=_.s[_.ptr] and _.s[_.ptr]<='f'[0] ('a'[0]<=s[_.ptr] and s[_.ptr]<='f'[0]
or '0'[0]<=_.s[_.ptr] and _.s[_.ptr]<='9'[0])) or '0'[0]<=s[_.ptr] and s[_.ptr]<='9'[0]))
{ {
number~=chr(_.s[_.ptr]); number~=chr(s[_.ptr]);
_.ptr+=1; _.ptr+=1;
} }
append(_.token,num(number)); append(_.token,num(number));
return; return;
} }
elsif(_.ptr<_.len and chr(_.s[_.ptr])=='o') elsif(_.ptr<len and chr(s[_.ptr])=='o')
{ {
_.ptr+=1; _.ptr+=1;
while(_.ptr<_.len and ('0'[0]<=_.s[_.ptr] and _.s[_.ptr]<='7'[0])) while(_.ptr<len and ('0'[0]<=s[_.ptr] and s[_.ptr]<='7'[0]))
{ {
number~=chr(_.s[_.ptr]); number~=chr(s[_.ptr]);
_.ptr+=1; _.ptr+=1;
} }
append(_.token,num(number)); append(_.token,num(number));
return; return;
} }
while(_.ptr<_.len and ('0'[0]<=_.s[_.ptr] and _.s[_.ptr]<='9'[0])) while(_.ptr<len and ('0'[0]<=s[_.ptr] and s[_.ptr]<='9'[0]))
{ {
number~=chr(_.s[_.ptr]); number~=chr(s[_.ptr]);
_.ptr+=1; _.ptr+=1;
} }
if(_.ptr<_.len and chr(_.s[_.ptr])=='.') if(_.ptr<len and chr(s[_.ptr])=='.')
{ {
number~=chr(_.s[_.ptr]); number~=chr(s[_.ptr]);
_.ptr+=1; _.ptr+=1;
while(_.ptr<_.len and ('0'[0]<=_.s[_.ptr] and _.s[_.ptr]<='9'[0])) while(_.ptr<len and ('0'[0]<=s[_.ptr] and s[_.ptr]<='9'[0]))
{ {
number~=chr(_.s[_.ptr]); number~=chr(s[_.ptr]);
_.ptr+=1; _.ptr+=1;
} }
} }
if(chr(_.s[_.ptr])=='e' or chr(_.s[_.ptr])=='E') if(chr(s[_.ptr])=='e' or chr(s[_.ptr])=='E')
{ {
number~=chr(_.s[_.ptr]); number~=chr(s[_.ptr]);
_.ptr+=1; _.ptr+=1;
if(chr(_.s[_.ptr])=='-' or chr(_.s[_.ptr])=='+') if(chr(s[_.ptr])=='-' or chr(s[_.ptr])=='+')
{ {
number~=chr(_.s[_.ptr]); number~=chr(s[_.ptr]);
_.ptr+=1; _.ptr+=1;
} }
while(_.ptr<_.len and ('0'[0]<=_.s[_.ptr] and _.s[_.ptr]<='9'[0])) while(_.ptr<len and ('0'[0]<=s[_.ptr] and s[_.ptr]<='9'[0]))
{ {
number~=chr(_.s[_.ptr]); number~=chr(s[_.ptr]);
_.ptr+=1; _.ptr+=1;
} }
} }
@ -128,14 +129,14 @@ var lexer=func(file)
}, },
opr_gen:func() opr_gen:func()
{ {
var c=chr(_.s[_.ptr]); var c=chr(s[_.ptr]);
if(c=='+' or c=='-' or c=='~' or c=='/' or c=='*' or c=='>' or c=='<' or c=='!' or c=='=') if(c=='+' or c=='-' or c=='~' or c=='/' or c=='*' or c=='>' or c=='<' or c=='!' or c=='=')
{ {
var tmp=c; var tmp=c;
_.ptr+=1; _.ptr+=1;
if(_.ptr<_.len and chr(_.s[_.ptr])=='=') if(_.ptr<len and chr(s[_.ptr])=='=')
{ {
tmp~=chr(_.s[_.ptr]); tmp~=chr(s[_.ptr]);
_.ptr+=1; _.ptr+=1;
} }
append(_.token,tmp); append(_.token,tmp);
@ -143,7 +144,7 @@ var lexer=func(file)
} }
elsif(c=='.') elsif(c=='.')
{ {
if(_.ptr+2<_.len and chr(_.s[_.ptr+1])=='.' and chr(_.s[_.ptr+2])=='.') if(_.ptr+2<len and chr(s[_.ptr+1])=='.' and chr(s[_.ptr+2])=='.')
{ {
append(_.token,"..."); append(_.token,"...");
_.ptr+=3; _.ptr+=3;
@ -155,16 +156,16 @@ var lexer=func(file)
} }
return; return;
} }
elsif(c!=' ' and c!='\t' and c!='\n' and c!='\r' and _.s[_.ptr]>0) elsif(c!=' ' and c!='\t' and c!='\n' and c!='\r' and s[_.ptr]>0)
append(_.token,c); append(_.token,c);
_.ptr+=1; _.ptr+=1;
return; return;
}, },
main:func() main:func()
{ {
while(_.ptr<_.len) while(_.ptr<len)
{ {
var c=_.s[_.ptr]; var c=s[_.ptr];
if(c=='#'[0]) if(c=='#'[0])
me.jmp_note(); me.jmp_note();
elsif('a'[0]<=c and c<='z'[0] elsif('a'[0]<=c and c<='z'[0]