delete op_cntpop & counter stack

now the iterator will be type vm_cnt and be stored on value stack.
This commit is contained in:
ValKmjolnir 2021-11-25 18:13:31 +08:00
parent 0a8655eb4d
commit b8ef3cf6b6
4 changed files with 41 additions and 47 deletions

View File

@ -59,7 +59,6 @@ enum op_code
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
op_jf, // used in conditional/loop,jmp when condition is false and POP STACK op_jf, // used in conditional/loop,jmp when condition is false and POP STACK
op_cnt, // add counter for forindex/foreach op_cnt, // add counter for forindex/foreach
op_cntpop, // pop counter
op_findex, // index counter on the top of forindex_stack plus 1 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_feach, // index counter on the top of forindex_stack plus 1 and get the value in vector
op_callg, // get value in global scope op_callg, // get value in global scope
@ -146,7 +145,6 @@ struct
{op_jt, "jt "}, {op_jt, "jt "},
{op_jf, "jf "}, {op_jf, "jf "},
{op_cnt, "cnt "}, {op_cnt, "cnt "},
{op_cntpop, "cntpop"},
{op_findex, "findx "}, {op_findex, "findx "},
{op_feach, "feach "}, {op_feach, "feach "},
{op_callg, "callg "}, {op_callg, "callg "},
@ -880,7 +878,7 @@ void nasal_codegen::forindex_gen(const nasal_ast& ast)
code[ptr].num=code.size(); code[ptr].num=code.size();
load_continue_break(code.size()-1,code.size()); load_continue_break(code.size()-1,code.size());
gen(op_pop,0,0);// pop vector gen(op_pop,0,0);// pop vector
gen(op_cntpop,0,0); gen(op_pop,0,0);// pop iterator
} }
void nasal_codegen::foreach_gen(const nasal_ast& ast) void nasal_codegen::foreach_gen(const nasal_ast& ast)
{ {
@ -908,7 +906,7 @@ void nasal_codegen::foreach_gen(const nasal_ast& ast)
code[ptr].num=code.size(); code[ptr].num=code.size();
load_continue_break(code.size()-1,code.size()); load_continue_break(code.size()-1,code.size());
gen(op_pop,0,0);// pop vector gen(op_pop,0,0);// pop vector
gen(op_cntpop,0,0); gen(op_pop,0,0);// pop iterator
} }
void nasal_codegen::or_gen(const nasal_ast& ast) void nasal_codegen::or_gen(const nasal_ast& ast)
@ -1138,7 +1136,7 @@ void nasal_codegen::ret_gen(const nasal_ast& ast)
for(uint32_t i=0;i<in_iterloop.top();++i) for(uint32_t i=0;i<in_iterloop.top();++i)
{ {
gen(op_pop,0,0); gen(op_pop,0,0);
gen(op_cntpop,0,0); gen(op_pop,0,0);
} }
if(ast.size()) if(ast.size())
calc_gen(ast[0]); calc_gen(ast[0]);

View File

@ -5,6 +5,7 @@ enum nasal_type
{ {
/* none-gc object */ /* none-gc object */
vm_none=0, vm_none=0,
vm_cnt,
vm_nil, vm_nil,
vm_num, vm_num,
/* gc object */ /* gc object */
@ -22,6 +23,7 @@ const uint32_t increment[vm_type_size]=
{ {
/* none-gc object */ /* none-gc object */
0, // vm_none, error type 0, // vm_none, error type
0, // vm_count, used in foreach/forindex
0, // vm_nil 0, // vm_nil
0, // vm_num 0, // vm_num
/* gc object */ /* gc object */
@ -43,11 +45,13 @@ struct nasal_ref
uint8_t type; uint8_t type;
union union
{ {
int64_t cnt;
double num; double num;
nasal_val* gcobj; nasal_val* gcobj;
}value; }value;
nasal_ref(const uint8_t t=vm_none):type(t){} nasal_ref(const uint8_t t=vm_none):type(t){}
nasal_ref(const uint8_t t,const int64_t n):type(t){value.cnt=n;}
nasal_ref(const uint8_t t,const double n):type(t){value.num=n;} nasal_ref(const uint8_t t,const double n):type(t){value.num=n;}
nasal_ref(const uint8_t t,nasal_val* n):type(t){value.gcobj=n;} nasal_ref(const uint8_t t,nasal_val* n):type(t){value.gcobj=n;}
nasal_ref(const nasal_ref& nr):type(nr.type),value(nr.value){} nasal_ref(const nasal_ref& nr):type(nr.type),value(nr.value){}
@ -62,6 +66,7 @@ struct nasal_ref
// number and string can be translated to each other // number and string can be translated to each other
double to_number(); double to_number();
std::string to_string(); std::string to_string();
inline int64_t& cnt ();
inline double& num (); inline double& num ();
inline std::string* str (); inline std::string* str ();
inline nasal_vec* vec (); inline nasal_vec* vec ();
@ -300,6 +305,7 @@ std::string nasal_ref::to_string()
return std::to_string(num()); return std::to_string(num());
return ""; return "";
} }
inline int64_t& nasal_ref::cnt (){return value.cnt; }
inline double& nasal_ref::num (){return value.num; } inline double& nasal_ref::num (){return value.num; }
inline std::string* nasal_ref::str (){return value.gcobj->ptr.str; } inline std::string* nasal_ref::str (){return value.gcobj->ptr.str; }
inline nasal_vec* nasal_ref::vec (){return value.gcobj->ptr.vec; } inline nasal_vec* nasal_ref::vec (){return value.gcobj->ptr.vec; }

View File

@ -270,9 +270,9 @@ std::string nasal_lexer::str_gen()
void nasal_lexer::scan(const std::string& file) void nasal_lexer::scan(const std::string& file)
{ {
open(file);
line=1; line=1;
error=ptr=0; error=ptr=0;
open(file);
std::string str; std::string str;
while(ptr<res.size()) while(ptr<res.size())

View File

@ -11,7 +11,6 @@ private:
const std::string* str_table;// const symbols, ref from nasal_codegen const std::string* str_table;// const symbols, ref from nasal_codegen
std::stack<uint32_t> ret; // stack to store return pc std::stack<uint32_t> ret; // stack to store return pc
std::stack<nasal_func*> func_stk; // stack to store function, used to get upvalues std::stack<nasal_func*> func_stk; // stack to store function, used to get upvalues
std::stack<int> counter; // iterator stack for forindex/foreach
std::vector<uint32_t> imm; // immediate number std::vector<uint32_t> imm; // immediate number
nasal_ref* mem_addr; // used for mem_call nasal_ref* mem_addr; // used for mem_call
/* garbage collector */ /* garbage collector */
@ -92,7 +91,6 @@ private:
void opr_jt(); void opr_jt();
void opr_jf(); void opr_jf();
void opr_counter(); void opr_counter();
void opr_cntpop();
void opr_findex(); void opr_findex();
void opr_feach(); void opr_feach();
void opr_callg(); void opr_callg();
@ -138,8 +136,6 @@ void nasal_vm::clear()
gc.clear(); gc.clear();
while(!ret.empty()) while(!ret.empty())
ret.pop(); ret.pop();
while(!counter.empty())
counter.pop();
imm.clear(); imm.clear();
} }
void nasal_vm::valinfo(nasal_ref& val) void nasal_vm::valinfo(nasal_ref& val)
@ -147,14 +143,15 @@ void nasal_vm::valinfo(nasal_ref& val)
const nasal_val* p=val.value.gcobj; const nasal_val* p=val.value.gcobj;
switch(val.type) switch(val.type)
{ {
case vm_none: printf("\tnull |\n");break; case vm_none: printf("\t|null |\n");break;
case vm_nil: printf("\tnil |\n");break; case vm_cnt: printf("\t|counter| %ld\n",val.cnt());break;
case vm_num: printf("\tnum | %lf\n",val.num());break; case vm_nil: printf("\t|nil |\n");break;
case vm_str: printf("\tstr | <%p> %s\n",p,rawstr(*val.str()).c_str());break; case vm_num: printf("\t|number | %lf\n",val.num());break;
case vm_func: printf("\tfunc | <%p> func{entry=0x%x}\n",p,val.func()->entry);break; case vm_str: printf("\t|string | <%p> %s\n",p,rawstr(*val.str()).c_str());break;
case vm_vec: printf("\tvec | <%p> [%lu val]\n",p,val.vec()->elems.size());break; case vm_func: printf("\t|func | <%p> func{entry=0x%x}\n",p,val.func()->entry);break;
case vm_hash: printf("\thash | <%p> {%lu member}\n",p,val.hash()->elems.size());break; case vm_vec: printf("\t|vector | <%p> [%lu val]\n",p,val.vec()->elems.size());break;
case vm_obj: printf("\tobj | <%p>\n",p);break; case vm_hash: printf("\t|hash | <%p> {%lu member}\n",p,val.hash()->elems.size());break;
case vm_obj: printf("\t|object | <%p>\n",p);break;
} }
} }
void nasal_vm::bytecodeinfo(const uint32_t p) void nasal_vm::bytecodeinfo(const uint32_t p)
@ -192,7 +189,7 @@ void nasal_vm::stackinfo(const uint32_t limit=20)
{ {
printf("vm stack(limit %d):\n",limit); printf("vm stack(limit %d):\n",limit);
uint32_t same=0,global_size=bytecode[0].num; uint32_t same=0,global_size=bytecode[0].num;
nasal_ref last={vm_none,0xffffffff}; nasal_ref last={vm_none,(nasal_val*)0xffffffff};
for(uint32_t i=0;i<limit && gc.top>=gc.stack+global_size;++i,--gc.top) for(uint32_t i=0;i<limit && gc.top>=gc.stack+global_size;++i,--gc.top)
{ {
if(gc.top[0]==last) if(gc.top[0]==last)
@ -475,13 +472,11 @@ inline void nasal_vm::opr_eq()
{ {
nasal_ref val2=gc.top[0]; nasal_ref val2=gc.top[0];
nasal_ref val1=(--gc.top)[0]; nasal_ref val1=(--gc.top)[0];
uint8_t a_type=val1.type; if(val1.type==vm_nil && val2.type==vm_nil)
uint8_t b_type=val2.type;
if(a_type==vm_nil && b_type==vm_nil)
gc.top[0]=gc.one; gc.top[0]=gc.one;
else if(a_type==vm_str && b_type==vm_str) else if(val1.type==vm_str && val2.type==vm_str)
gc.top[0]=(*val1.str()==*val2.str())?gc.one:gc.zero; gc.top[0]=(*val1.str()==*val2.str())?gc.one:gc.zero;
else if(a_type==vm_num || b_type==vm_num) else if(val1.type==vm_num || val2.type==vm_num)
gc.top[0]=(val1.to_number()==val2.to_number())?gc.one:gc.zero; gc.top[0]=(val1.to_number()==val2.to_number())?gc.one:gc.zero;
else else
gc.top[0]=(val1==val2)?gc.one:gc.zero; gc.top[0]=(val1==val2)?gc.one:gc.zero;
@ -490,13 +485,11 @@ inline void nasal_vm::opr_neq()
{ {
nasal_ref val2=gc.top[0]; nasal_ref val2=gc.top[0];
nasal_ref val1=(--gc.top)[0]; nasal_ref val1=(--gc.top)[0];
uint8_t a_type=val1.type; if(val1.type==vm_nil && val2.type==vm_nil)
uint8_t b_type=val2.type;
if(a_type==vm_nil && b_type==vm_nil)
gc.top[0]=gc.zero; gc.top[0]=gc.zero;
else if(a_type==vm_str && b_type==vm_str) else if(val1.type==vm_str && val2.type==vm_str)
gc.top[0]=(*val1.str()!=*val2.str())?gc.one:gc.zero; gc.top[0]=(*val1.str()!=*val2.str())?gc.one:gc.zero;
else if(a_type==vm_num || b_type==vm_num) else if(val1.type==vm_num || val2.type==vm_num)
gc.top[0]=(val1.to_number()!=val2.to_number())?gc.one:gc.zero; gc.top[0]=(val1.to_number()!=val2.to_number())?gc.one:gc.zero;
else else
gc.top[0]=(val1!=val2)?gc.one:gc.zero; gc.top[0]=(val1!=val2)?gc.one:gc.zero;
@ -540,32 +533,30 @@ inline void nasal_vm::opr_jf()
} }
inline void nasal_vm::opr_counter() inline void nasal_vm::opr_counter()
{ {
counter.push(-1); (++gc.top)[0]={vm_cnt,(int64_t)-1};
if(gc.top[0].type!=vm_vec) if(gc.top[-1].type!=vm_vec)
die("cnt: must use vector in forindex/foreach"); die("cnt: must use vector in forindex/foreach");
} }
inline void nasal_vm::opr_cntpop()
{
counter.pop();
}
inline void nasal_vm::opr_findex() inline void nasal_vm::opr_findex()
{ {
if(++counter.top()>=gc.top[0].vec()->elems.size()) if(++gc.top[0].cnt()>=gc.top[-1].vec()->elems.size())
{ {
pc=imm[pc]-1; pc=imm[pc]-1;
return; return;
} }
(++gc.top)[0]={vm_num,(double)counter.top()}; gc.top[1]={vm_num,(double)gc.top[0].cnt()};
++gc.top;
} }
inline void nasal_vm::opr_feach() inline void nasal_vm::opr_feach()
{ {
std::vector<nasal_ref>& ref=gc.top[0].vec()->elems; std::vector<nasal_ref>& ref=gc.top[-1].vec()->elems;
if(++counter.top()>=ref.size()) if(++gc.top[0].cnt()>=ref.size())
{ {
pc=imm[pc]-1; pc=imm[pc]-1;
return; return;
} }
(++gc.top)[0]=ref[counter.top()]; gc.top[1]=ref[gc.top[0].cnt()];
++gc.top;
} }
inline void nasal_vm::opr_callg() inline void nasal_vm::opr_callg()
{ {
@ -848,12 +839,12 @@ void nasal_vm::run(
&&leq, &&grt, &&geq, &&lessc, &&leq, &&grt, &&geq, &&lessc,
&&leqc, &&grtc, &&geqc, &&pop, &&leqc, &&grtc, &&geqc, &&pop,
&&jmp, &&jt, &&jf, &&counter, &&jmp, &&jt, &&jf, &&counter,
&&cntpop, &&findex, &&feach, &&callg, &&findex, &&feach, &&callg, &&calll,
&&calll, &&upval, &&callv, &&callvi, &&upval, &&callv, &&callvi, &&callh,
&&callh, &&callfv, &&callfh, &&callb, &&callfv, &&callfh, &&callb, &&slcbegin,
&&slcbegin,&&slcend, &&slc, &&slc2, &&slcend, &&slc, &&slc2, &&mcallg,
&&mcallg, &&mcalll, &&mupval, &&mcallv, &&mcalll, &&mupval, &&mcallv, &&mcallh,
&&mcallh, &&ret, &&vmexit &&ret, &&vmexit
}; };
bytecode=gen.get_code().data(); bytecode=gen.get_code().data();
std::vector<const void*> code; std::vector<const void*> code;
@ -938,7 +929,6 @@ jmp: exec_opnodie(opr_jmp ,op_jmp ); // -0
jt: exec_opnodie(opr_jt ,op_jt ); // -0 jt: exec_opnodie(opr_jt ,op_jt ); // -0
jf: exec_opnodie(opr_jf ,op_jf ); // -1 jf: exec_opnodie(opr_jf ,op_jf ); // -1
counter: exec_opnodie(opr_counter ,op_cnt ); // -0 counter: exec_opnodie(opr_counter ,op_cnt ); // -0
cntpop: exec_opnodie(opr_cntpop ,op_cntpop ); // -0
findex: exec_operand(opr_findex ,op_findex ); // +1 findex: exec_operand(opr_findex ,op_findex ); // +1
feach: exec_operand(opr_feach ,op_feach ); // +1 feach: exec_operand(opr_feach ,op_feach ); // +1
callg: exec_operand(opr_callg ,op_callg ); // +1 callg: exec_operand(opr_callg ,op_callg ); // +1