add const compare instructions
This commit is contained in:
parent
0b2fe61e6e
commit
57d6bcdc52
|
@ -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:
|
||||
|
|
28
nasal_gc.h
28
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;
|
||||
|
|
85
nasal_vm.h
85
nasal_vm.h
|
@ -11,7 +11,7 @@ private:
|
|||
std::stack<int> ret; // ptr stack stores address for function to return
|
||||
std::stack<int> counter; // iterator stack for forindex/foreach
|
||||
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_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()<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()
|
||||
{
|
||||
--stack_top;
|
||||
|
@ -841,7 +865,7 @@ inline void nasal_vm::opr_ret()
|
|||
}
|
||||
void nasal_vm::run(std::vector<opcode>& 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<opcode>& 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
|
|
@ -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 and chr(s[_.ptr])!='\n')
|
||||
_.ptr+=1;
|
||||
_.ptr+=1;
|
||||
},
|
||||
id_gen:func()
|
||||
{
|
||||
var tmp="";
|
||||
while(_.ptr<_.len)
|
||||
while(_.ptr<len)
|
||||
{
|
||||
var c=_.s[_.ptr];
|
||||
var c=s[_.ptr];
|
||||
if(('a'[0]<=c and c<='z'[0])
|
||||
or ('A'[0]<=c and c<='Z'[0])
|
||||
or ('0'[0]<=c and c<='9'[0])
|
||||
|
@ -32,14 +33,14 @@ var lexer=func(file)
|
|||
str_gen:func()
|
||||
{
|
||||
var str="";
|
||||
var mark=chr(_.s[_.ptr]);
|
||||
var mark=chr(s[_.ptr]);
|
||||
_.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;
|
||||
var c=chr(_.s[_.ptr]);
|
||||
var c=chr(s[_.ptr]);
|
||||
if (c=='a' ) str~='\a';
|
||||
elsif(c=='b' ) str~='\b';
|
||||
elsif(c=='f' ) str~='\f';
|
||||
|
@ -55,69 +56,69 @@ var lexer=func(file)
|
|||
else str~=c;
|
||||
}
|
||||
else
|
||||
str~=chr(_.s[_.ptr]);
|
||||
str~=chr(s[_.ptr]);
|
||||
_.ptr+=1;
|
||||
}
|
||||
if(_.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<len and chr(s[_.ptr])=='x')
|
||||
{
|
||||
_.ptr+=1;
|
||||
while(_.ptr<_.len and
|
||||
('a'[0]<=_.s[_.ptr] and _.s[_.ptr]<='f'[0]
|
||||
or '0'[0]<=_.s[_.ptr] and _.s[_.ptr]<='9'[0]))
|
||||
while(_.ptr<len and
|
||||
('a'[0]<=s[_.ptr] and s[_.ptr]<='f'[0]
|
||||
or '0'[0]<=s[_.ptr] and s[_.ptr]<='9'[0]))
|
||||
{
|
||||
number~=chr(_.s[_.ptr]);
|
||||
number~=chr(s[_.ptr]);
|
||||
_.ptr+=1;
|
||||
}
|
||||
append(_.token,num(number));
|
||||
return;
|
||||
}
|
||||
elsif(_.ptr<_.len and chr(_.s[_.ptr])=='o')
|
||||
elsif(_.ptr<len and chr(s[_.ptr])=='o')
|
||||
{
|
||||
_.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;
|
||||
}
|
||||
append(_.token,num(number));
|
||||
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;
|
||||
}
|
||||
if(_.ptr<_.len and chr(_.s[_.ptr])=='.')
|
||||
if(_.ptr<len and chr(s[_.ptr])=='.')
|
||||
{
|
||||
number~=chr(_.s[_.ptr]);
|
||||
number~=chr(s[_.ptr]);
|
||||
_.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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -128,14 +129,14 @@ var lexer=func(file)
|
|||
},
|
||||
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=='=')
|
||||
{
|
||||
var tmp=c;
|
||||
_.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;
|
||||
}
|
||||
append(_.token,tmp);
|
||||
|
@ -143,7 +144,7 @@ var lexer=func(file)
|
|||
}
|
||||
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,"...");
|
||||
_.ptr+=3;
|
||||
|
@ -155,16 +156,16 @@ var lexer=func(file)
|
|||
}
|
||||
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);
|
||||
_.ptr+=1;
|
||||
return;
|
||||
},
|
||||
main:func()
|
||||
{
|
||||
while(_.ptr<_.len)
|
||||
while(_.ptr<len)
|
||||
{
|
||||
var c=_.s[_.ptr];
|
||||
var c=s[_.ptr];
|
||||
if(c=='#'[0])
|
||||
me.jmp_note();
|
||||
elsif('a'[0]<=c and c<='z'[0]
|
||||
|
|
Loading…
Reference in New Issue