📝 change some identifiers' name.

This commit is contained in:
ValKmjolnir 2022-07-08 18:16:00 +08:00
parent 5d4cff0aa8
commit 11e9567b55
4 changed files with 390 additions and 395 deletions

13
nasal.h
View File

@ -127,18 +127,17 @@ double str2num(const char* str)
return is_negative?-ret_num:ret_num; return is_negative?-ret_num:ret_num;
} }
int utf8_hdchk(char head) int utf8_hdchk(const char head)
{ {
// RFC-2279 but now we use RFC-3629 so nbytes is less than 4 // RFC-2279 but now we use RFC-3629 so nbytes is less than 4
uint8_t c=(uint8_t)head; const uint8_t c=(uint8_t)head;
uint32_t nbytes=0;
if((c>>5)==0x06) // 110x xxxx (10xx xxxx)^1 if((c>>5)==0x06) // 110x xxxx (10xx xxxx)^1
nbytes=1; return 1;
if((c>>4)==0x0e) // 1110 xxxx (10xx xxxx)^2 if((c>>4)==0x0e) // 1110 xxxx (10xx xxxx)^2
nbytes=2; return 2;
if((c>>3)==0x1e) // 1111 0xxx (10xx xxxx)^3 if((c>>3)==0x1e) // 1111 0xxx (10xx xxxx)^3
nbytes=3; return 3;
return nbytes; return 0;
} }
std::string chrhex(const char c) std::string chrhex(const char c)

View File

@ -3,81 +3,81 @@
enum op_code enum op_code
{ {
op_exit, // stop the virtual machine op_exit, // stop the virtual machine
op_intg, // global scope size op_intg, // global scope size
op_intl, // local scope size op_intl, // local scope size
op_loadg, // load global value op_loadg, // load global value
op_loadl, // load local value op_loadl, // load local value
op_loadu, // load upvalue op_loadu, // load upvalue
op_pnum, // push constant number to the stack op_pnum, // push constant number to the stack
op_pnil, // push constant nil to the stack op_pnil, // push constant nil to the stack
op_pstr, // push constant string to the stack op_pstr, // push constant string to the stack
op_newv, // push new vector with initial values from stack op_newv, // push new vector with initial values from stack
op_newh, // push new hash to the stack op_newh, // push new hash to the stack
op_newf, // push new function to the stack op_newf, // push new function to the stack
op_happ, // hash append op_happ, // hash append
op_para, // normal parameter op_para, // normal parameter
op_defpara, // default parameter op_deft, // default parameter
op_dynpara, // dynamic parameter op_dyn, // dynamic parameter
op_unot, // ! op_unot, // !
op_usub, // - op_usub, // -
op_add, // + op_add, // +
op_sub, // - op_sub, // -
op_mul, // * op_mul, // *
op_div, // / op_div, // /
op_lnk, // ~ op_lnk, // ~
op_addc, // + const op_addc, // + const
op_subc, // - const op_subc, // - const
op_mulc, // * const op_mulc, // * const
op_divc, // / const op_divc, // / const
op_lnkc, // ~ const op_lnkc, // ~ const
op_addeq, // += op_addeq, // +=
op_subeq, // -= op_subeq, // -=
op_muleq, // *= op_muleq, // *=
op_diveq, // /= op_diveq, // /=
op_lnkeq, // ~= op_lnkeq, // ~=
op_addeqc, // += const op_addeqc, // += const
op_subeqc, // -= const op_subeqc, // -= const
op_muleqc, // *= const op_muleqc, // *= const
op_diveqc, // /= const op_diveqc, // /= const
op_lnkeqc, // ~= const op_lnkeqc, // ~= const
op_meq, // = op_meq, // =
op_eq, // == op_eq, // ==
op_neq, // != op_neq, // !=
op_less, // < op_less, // <
op_leq, // <= op_leq, // <=
op_grt, // > op_grt, // >
op_geq, // >= op_geq, // >=
op_lessc, // < const op_lessc, // < const
op_leqc, // <= const op_leqc, // <= const
op_grtc, // > const op_grtc, // > const
op_geqc, // >= 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
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_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
op_calll, // get value in local scope op_calll, // get value in local scope
op_upval, // get upvalue in closure op_upval, // get upvalue in closure
op_callv, // call vec[index] op_callv, // call vec[index]
op_callvi, // call vec[immediate] (used in multi-assign/multi-define) op_callvi, // call vec[immediate] (used in multi-assign/multi-define)
op_callh, // call hash.label op_callh, // call hash.label
op_callfv, // call function(vector as parameters) op_callfv, // call function(vector as parameters)
op_callfh, // call function(hash as parameters) op_callfh, // call function(hash as parameters)
op_callb, // call builtin-function op_callb, // call builtin-function
op_slcbegin,// begin of slice like: vec[1,2,3:6,0,-1] op_slcbeg, // begin of slice like: vec[1,2,3:6,0,-1]
op_slcend, // end of slice op_slcend, // end of slice
op_slc, // slice like vec[1] op_slc, // slice like vec[1]
op_slc2, // slice like vec[nil:10] op_slc2, // slice like vec[nil:10]
op_mcallg, // get memory space of value in global scope op_mcallg, // get memory space of value in global scope
op_mcalll, // get memory space of value in local scope op_mcalll, // get memory space of value in local scope
op_mupval, // get memory space of value in closure op_mupval, // get memory space of value in closure
op_mcallv, // get memory space of vec[index] op_mcallv, // get memory space of vec[index]
op_mcallh, // get memory space of hash.label op_mcallh, // get memory space of hash.label
op_ret // return op_ret // return
}; };
struct struct
@ -86,82 +86,82 @@ struct
const char* name; const char* name;
}code_table[]= }code_table[]=
{ {
{op_exit, "exit "}, {op_exit, "exit "},
{op_intg, "intg "}, {op_intg, "intg "},
{op_intl, "intl "}, {op_intl, "intl "},
{op_loadg, "loadg "}, {op_loadg, "loadg "},
{op_loadl, "loadl "}, {op_loadl, "loadl "},
{op_loadu, "loadu "}, {op_loadu, "loadu "},
{op_pnum, "pnum "}, {op_pnum, "pnum "},
{op_pnil, "pnil "}, {op_pnil, "pnil "},
{op_pstr, "pstr "}, {op_pstr, "pstr "},
{op_newv, "newv "}, {op_newv, "newv "},
{op_newh, "newh "}, {op_newh, "newh "},
{op_newf, "newf "}, {op_newf, "newf "},
{op_happ, "happ "}, {op_happ, "happ "},
{op_para, "para "}, {op_para, "para "},
{op_defpara, "def "}, {op_deft, "def "},
{op_dynpara, "dyn "}, {op_dyn, "dyn "},
{op_unot, "not "}, {op_unot, "not "},
{op_usub, "usub "}, {op_usub, "usub "},
{op_add, "add "}, {op_add, "add "},
{op_sub, "sub "}, {op_sub, "sub "},
{op_mul, "mult "}, {op_mul, "mult "},
{op_div, "div "}, {op_div, "div "},
{op_lnk, "lnk "}, {op_lnk, "lnk "},
{op_addc, "addc "}, {op_addc, "addc "},
{op_subc, "subc "}, {op_subc, "subc "},
{op_mulc, "multc "}, {op_mulc, "multc "},
{op_divc, "divc "}, {op_divc, "divc "},
{op_lnkc, "lnkc "}, {op_lnkc, "lnkc "},
{op_addeq, "addeq "}, {op_addeq, "addeq "},
{op_subeq, "subeq "}, {op_subeq, "subeq "},
{op_muleq, "muleq "}, {op_muleq, "muleq "},
{op_diveq, "diveq "}, {op_diveq, "diveq "},
{op_lnkeq, "lnkeq "}, {op_lnkeq, "lnkeq "},
{op_addeqc, "addeqc"}, {op_addeqc, "addeqc"},
{op_subeqc, "subeqc"}, {op_subeqc, "subeqc"},
{op_muleqc, "muleqc"}, {op_muleqc, "muleqc"},
{op_diveqc, "diveqc"}, {op_diveqc, "diveqc"},
{op_lnkeqc, "lnkeqc"}, {op_lnkeqc, "lnkeqc"},
{op_meq, "meq "}, {op_meq, "meq "},
{op_eq, "eq "}, {op_eq, "eq "},
{op_neq, "neq "}, {op_neq, "neq "},
{op_less, "less "}, {op_less, "less "},
{op_leq, "leq "}, {op_leq, "leq "},
{op_grt, "grt "}, {op_grt, "grt "},
{op_geq, "geq "}, {op_geq, "geq "},
{op_lessc, "lessc "}, {op_lessc, "lessc "},
{op_leqc, "leqc "}, {op_leqc, "leqc "},
{op_grtc, "grtc "}, {op_grtc, "grtc "},
{op_geqc, "geqc "}, {op_geqc, "geqc "},
{op_pop, "pop "}, {op_pop, "pop "},
{op_jmp, "jmp "}, {op_jmp, "jmp "},
{op_jt, "jt "}, {op_jt, "jt "},
{op_jf, "jf "}, {op_jf, "jf "},
{op_cnt, "cnt "}, {op_cnt, "cnt "},
{op_findex, "findx "}, {op_findex, "findx "},
{op_feach, "feach "}, {op_feach, "feach "},
{op_callg, "callg "}, {op_callg, "callg "},
{op_calll, "calll "}, {op_calll, "calll "},
{op_upval, "upval "}, {op_upval, "upval "},
{op_callv, "callv "}, {op_callv, "callv "},
{op_callvi, "callvi"}, {op_callvi, "callvi"},
{op_callh, "callh "}, {op_callh, "callh "},
{op_callfv, "callfv"}, {op_callfv, "callfv"},
{op_callfh, "callfh"}, {op_callfh, "callfh"},
{op_callb, "callb "}, {op_callb, "callb "},
{op_slcbegin,"slcbeg"}, {op_slcbeg, "slcbeg"},
{op_slcend, "slcend"}, {op_slcend, "slcend"},
{op_slc, "slc "}, {op_slc, "slc "},
{op_slc2, "slc2 "}, {op_slc2, "slc2 "},
{op_mcallg, "mcallg"}, {op_mcallg, "mcallg"},
{op_mcalll, "mcalll"}, {op_mcalll, "mcalll"},
{op_mupval, "mupval"}, {op_mupval, "mupval"},
{op_mcallv, "mcallv"}, {op_mcallv, "mcallv"},
{op_mcallh, "mcallh"}, {op_mcallh, "mcallh"},
{op_ret, "ret "}, {op_ret, "ret "},
{-1, nullptr }, {-1, nullptr },
}; };
struct opcode struct opcode
@ -189,13 +189,13 @@ private:
nasal_err& nerr; nasal_err& nerr;
const std::string* file; const std::string* file;
std::stack<uint32_t> in_iterloop; std::stack<uint32_t> in_iterloop;
std::unordered_map<double,int> num_table; std::unordered_map<double,uint32_t> num_table;
std::unordered_map<std::string,int> str_table; std::unordered_map<std::string,uint32_t> str_table;
std::vector<double> num_res; std::vector<double> num_res;
std::vector<std::string> str_res; std::vector<std::string> str_res;
std::vector<opcode> code; std::vector<opcode> code;
std::list<std::vector<int>> continue_ptr; std::list<std::vector<int>> continue_ptr;
std::list<std::vector<int>> break_ptr; std::list<std::vector<int>> break_ptr;
// global : max 4095 values // global : max 4095 values
std::unordered_map<std::string,int> global; std::unordered_map<std::string,int> global;
// local : max 32768 upvalues 65536 values // local : max 32768 upvalues 65536 values
@ -206,8 +206,8 @@ private:
std::stack<uint32_t> festk; std::stack<uint32_t> festk;
void die(std::string,const uint32_t); void die(std::string,const uint32_t);
void regist_number(const double); void regist_num(const double);
void regist_string(const std::string&); void regist_str(const std::string&);
void find_symbol(const nasal_ast&); void find_symbol(const nasal_ast&);
void add_sym(const std::string&); void add_sym(const std::string&);
int local_find(const std::string&); int local_find(const std::string&);
@ -261,21 +261,21 @@ void nasal_codegen::die(std::string info,const uint32_t line)
nerr.err("code",line,info); nerr.err("code",line,info);
} }
void nasal_codegen::regist_number(const double num) void nasal_codegen::regist_num(const double num)
{ {
int size=num_table.size();
if(!num_table.count(num)) if(!num_table.count(num))
{ {
uint32_t size=num_table.size();
num_table[num]=size; num_table[num]=size;
num_res.push_back(num); num_res.push_back(num);
} }
} }
void nasal_codegen::regist_string(const std::string& str) void nasal_codegen::regist_str(const std::string& str)
{ {
int size=str_table.size();
if(!str_table.count(str)) if(!str_table.count(str))
{ {
uint32_t size=str_table.size();
str_table[str]=size; str_table[str]=size;
str_res.push_back(str); str_res.push_back(str);
} }
@ -356,13 +356,13 @@ void nasal_codegen::gen(uint8_t op,uint32_t num,uint32_t line)
void nasal_codegen::num_gen(const nasal_ast& ast) void nasal_codegen::num_gen(const nasal_ast& ast)
{ {
double num=ast.num(); double num=ast.num();
regist_number(num); regist_num(num);
gen(op_pnum,num_table[num],ast.line()); gen(op_pnum,num_table[num],ast.line());
} }
void nasal_codegen::str_gen(const nasal_ast& ast) void nasal_codegen::str_gen(const nasal_ast& ast)
{ {
regist_string(ast.str()); regist_str(ast.str());
gen(op_pstr,str_table[ast.str()],ast.line()); gen(op_pstr,str_table[ast.str()],ast.line());
} }
@ -380,7 +380,7 @@ void nasal_codegen::hash_gen(const nasal_ast& ast)
{ {
calc_gen(node[1]); calc_gen(node[1]);
const std::string& str=node[0].str(); const std::string& str=node[0].str();
regist_string(str); regist_str(str);
gen(op_happ,str_table[str],node.line()); gen(op_happ,str_table[str],node.line());
} }
} }
@ -405,15 +405,15 @@ void nasal_codegen::func_gen(const nasal_ast& ast)
const std::string& str=tmp.str(); const std::string& str=tmp.str();
if(str=="me") if(str=="me")
die("\"me\" should not be a parameter",tmp.line()); die("\"me\" should not be a parameter",tmp.line());
regist_string(str); regist_str(str);
switch(tmp.type()) switch(tmp.type())
{ {
case ast_id:gen(op_para,str_table[str],tmp.line());break; case ast_id:gen(op_para,str_table[str],tmp.line());break;
case ast_default: case ast_default:
calc_gen(tmp[0]); calc_gen(tmp[0]);
gen(op_defpara,str_table[str],tmp.line()); gen(op_deft,str_table[str],tmp.line());
break; break;
case ast_dynamic:gen(op_dynpara,str_table[str],tmp.line());break; case ast_dynamic:gen(op_dyn,str_table[str],tmp.line());break;
} }
add_sym(str); add_sym(str);
} }
@ -492,7 +492,7 @@ void nasal_codegen::call_id(const nasal_ast& ast)
void nasal_codegen::call_hash(const nasal_ast& ast) void nasal_codegen::call_hash(const nasal_ast& ast)
{ {
regist_string(ast.str()); regist_str(ast.str());
gen(op_callh,str_table[ast.str()],ast.line()); gen(op_callh,str_table[ast.str()],ast.line());
} }
@ -505,7 +505,7 @@ void nasal_codegen::call_vec(const nasal_ast& ast)
gen(op_callv,0,ast[0].line()); gen(op_callv,0,ast[0].line());
return; return;
} }
gen(op_slcbegin,0,ast.line()); gen(op_slcbeg,0,ast.line());
for(auto& tmp:ast.child()) for(auto& tmp:ast.child())
{ {
if(tmp.type()!=ast_subvec) if(tmp.type()!=ast_subvec)
@ -614,7 +614,7 @@ void nasal_codegen::mcall_vec(const nasal_ast& ast)
void nasal_codegen::mcall_hash(const nasal_ast& ast) void nasal_codegen::mcall_hash(const nasal_ast& ast)
{ {
regist_string(ast.str()); regist_str(ast.str());
gen(op_mcallh,str_table[ast.str()],ast.line()); gen(op_mcallh,str_table[ast.str()],ast.line());
} }
@ -1041,7 +1041,7 @@ void nasal_codegen::calc_gen(const nasal_ast& ast)
gen(ast.type()-ast_addeq+op_addeq,0,ast.line()); gen(ast.type()-ast_addeq+op_addeq,0,ast.line());
else else
{ {
regist_number(ast[1].num()); regist_num(ast[1].num());
gen(ast.type()-ast_addeq+op_addeqc,num_table[ast[1].num()],ast.line()); gen(ast.type()-ast_addeq+op_addeqc,num_table[ast[1].num()],ast.line());
} }
break; break;
@ -1049,7 +1049,7 @@ void nasal_codegen::calc_gen(const nasal_ast& ast)
if(ast[1].type()!=ast_str) if(ast[1].type()!=ast_str)
calc_gen(ast[1]); calc_gen(ast[1]);
else else
regist_string(ast[1].str()); regist_str(ast[1].str());
mcall(ast[0]); mcall(ast[0]);
if(ast[1].type()!=ast_str) if(ast[1].type()!=ast_str)
gen(op_lnkeq,0,ast.line()); gen(op_lnkeq,0,ast.line());
@ -1068,7 +1068,7 @@ void nasal_codegen::calc_gen(const nasal_ast& ast)
} }
else else
{ {
regist_number(ast[1].num()); regist_num(ast[1].num());
gen(ast.type()-ast_add+op_addc,num_table[ast[1].num()],ast.line()); gen(ast.type()-ast_add+op_addc,num_table[ast[1].num()],ast.line());
} }
break; break;
@ -1081,7 +1081,7 @@ void nasal_codegen::calc_gen(const nasal_ast& ast)
} }
else else
{ {
regist_string(ast[1].str()); regist_str(ast[1].str());
gen(op_lnkc,str_table[ast[1].str()],ast.line()); gen(op_lnkc,str_table[ast[1].str()],ast.line());
} }
break; break;
@ -1100,7 +1100,7 @@ void nasal_codegen::calc_gen(const nasal_ast& ast)
} }
else else
{ {
regist_number(ast[1].num()); regist_num(ast[1].num());
gen(ast.type()-ast_less+op_lessc,num_table[ast[1].num()],ast.line()); gen(ast.type()-ast_less+op_lessc,num_table[ast[1].num()],ast.line());
} }
break; break;
@ -1225,8 +1225,8 @@ void nasal_codegen::compile(const nasal_parse& parse,const nasal_import& import)
file=import.get_file().data(); file=import.get_file().data();
in_iterloop.push(0); in_iterloop.push(0);
regist_number(0); regist_num(0);
regist_number(1); regist_num(1);
find_symbol(parse.ast()); // search symbols first find_symbol(parse.ast()); // search symbols first
gen(op_intg,global.size(),0); gen(op_intg,global.size(),0);
@ -1299,7 +1299,7 @@ void nasal_codegen::print_op(uint32_t index)
case op_happ: case op_pstr: case op_happ: case op_pstr:
case op_lnkc: case op_lnkc:
case op_callh: case op_mcallh: case op_callh: case op_mcallh:
case op_para: case op_defpara:case op_dynpara: case op_para: case op_deft: case op_dyn:
printf("0x%x (\"%s\")\n",c.num,rawstr(str_res[c.num],16).c_str());break; printf("0x%x (\"%s\")\n",c.num,rawstr(str_res[c.num],16).c_str());break;
default:printf("\n");break; default:printf("\n");break;
} }
@ -1308,11 +1308,11 @@ void nasal_codegen::print_op(uint32_t index)
void nasal_codegen::print() void nasal_codegen::print()
{ {
for(auto& num:num_res) for(auto& num:num_res)
std::cout<<" .number "<<num<<'\n'; std::cout<<" .number "<<num<<"\n";
for(auto& str:str_res) for(auto& str:str_res)
std::cout<<" .symbol \""<<rawstr(str)<<"\"\n"; std::cout<<" .symbol \""<<rawstr(str)<<"\"\n";
std::cout<<"\n"; std::cout<<"\n";
for(uint32_t i=0;i<code.size();++i) for(size_t i=0;i<code.size();++i)
print_op(i); print_op(i);
} }

View File

@ -184,25 +184,25 @@ void nasal_dbg::run(
init(gen.get_strs(),gen.get_nums(),gen.get_code(),linker.get_file(),argv); init(gen.get_strs(),gen.get_nums(),gen.get_code(),linker.get_file(),argv);
const void* oprs[]= const void* oprs[]=
{ {
&&vmexit, &&intg, &&intl, &&loadg, &&vmexit, &&intg, &&intl, &&loadg,
&&loadl, &&loadu, &&pnum, &&pnil, &&loadl, &&loadu, &&pnum, &&pnil,
&&pstr, &&newv, &&newh, &&newf, &&pstr, &&newv, &&newh, &&newf,
&&happ, &&para, &&defpara,&&dynpara, &&happ, &&para, &&deft, &&dyn,
&&unot, &&usub, &&add, &&sub, &&unot, &&usub, &&add, &&sub,
&&mul, &&div, &&lnk, &&addc, &&mul, &&div, &&lnk, &&addc,
&&subc, &&mulc, &&divc, &&lnkc, &&subc, &&mulc, &&divc, &&lnkc,
&&addeq, &&subeq, &&muleq, &&diveq, &&addeq, &&subeq, &&muleq, &&diveq,
&&lnkeq, &&addeqc, &&subeqc, &&muleqc, &&lnkeq, &&addeqc, &&subeqc, &&muleqc,
&&diveqc, &&lnkeqc, &&meq, &&eq, &&diveqc, &&lnkeqc, &&meq, &&eq,
&&neq, &&less, &&leq, &&grt, &&neq, &&less, &&leq, &&grt,
&&geq, &&lessc, &&leqc, &&grtc, &&geq, &&lessc, &&leqc, &&grtc,
&&geqc, &&pop, &&jmp, &&jt, &&geqc, &&pop, &&jmp, &&jt,
&&jf, &&counter, &&findex, &&feach, &&jf, &&cnt, &&findex, &&feach,
&&callg, &&calll, &&upval, &&callv, &&callg, &&calll, &&upval, &&callv,
&&callvi, &&callh, &&callfv, &&callfh, &&callvi, &&callh, &&callfv, &&callfh,
&&callb, &&slcbegin, &&slcend, &&slc, &&callb, &&slcbeg, &&slcend, &&slc,
&&slc2, &&mcallg, &&mcalll, &&mupval, &&slc2, &&mcallg, &&mcalll, &&mupval,
&&mcallv, &&mcallh, &&ret &&mcallv, &&mcallh, &&ret
}; };
std::vector<const void*> code; std::vector<const void*> code;
for(auto& i:gen.get_code()) for(auto& i:gen.get_code())
@ -222,80 +222,80 @@ vmexit:
return; return;
#define dbg(op) {interact();op();if(top<canary)goto *code[++pc];goto vmexit;} #define dbg(op) {interact();op();if(top<canary)goto *code[++pc];goto vmexit;}
intg: dbg(opr_intg ); intg: dbg(opr_intg );
intl: dbg(opr_intl ); intl: dbg(opr_intl );
loadg: dbg(opr_loadg ); loadg: dbg(opr_loadg );
loadl: dbg(opr_loadl ); loadl: dbg(opr_loadl );
loadu: dbg(opr_loadu ); loadu: dbg(opr_loadu );
pnum: dbg(opr_pnum ); pnum: dbg(opr_pnum );
pnil: dbg(opr_pnil ); pnil: dbg(opr_pnil );
pstr: dbg(opr_pstr ); pstr: dbg(opr_pstr );
newv: dbg(opr_newv ); newv: dbg(opr_newv );
newh: dbg(opr_newh ); newh: dbg(opr_newh );
newf: dbg(opr_newf ); newf: dbg(opr_newf );
happ: dbg(opr_happ ); happ: dbg(opr_happ );
para: dbg(opr_para ); para: dbg(opr_para );
defpara: dbg(opr_defpara ); deft: dbg(opr_deft );
dynpara: dbg(opr_dynpara ); dyn: dbg(opr_dyn );
unot: dbg(opr_unot ); unot: dbg(opr_unot );
usub: dbg(opr_usub ); usub: dbg(opr_usub );
add: dbg(opr_add ); add: dbg(opr_add );
sub: dbg(opr_sub ); sub: dbg(opr_sub );
mul: dbg(opr_mul ); mul: dbg(opr_mul );
div: dbg(opr_div ); div: dbg(opr_div );
lnk: dbg(opr_lnk ); lnk: dbg(opr_lnk );
addc: dbg(opr_addc ); addc: dbg(opr_addc );
subc: dbg(opr_subc ); subc: dbg(opr_subc );
mulc: dbg(opr_mulc ); mulc: dbg(opr_mulc );
divc: dbg(opr_divc ); divc: dbg(opr_divc );
lnkc: dbg(opr_lnkc ); lnkc: dbg(opr_lnkc );
addeq: dbg(opr_addeq ); addeq: dbg(opr_addeq );
subeq: dbg(opr_subeq ); subeq: dbg(opr_subeq );
muleq: dbg(opr_muleq ); muleq: dbg(opr_muleq );
diveq: dbg(opr_diveq ); diveq: dbg(opr_diveq );
lnkeq: dbg(opr_lnkeq ); lnkeq: dbg(opr_lnkeq );
addeqc: dbg(opr_addeqc ); addeqc: dbg(opr_addeqc);
subeqc: dbg(opr_subeqc ); subeqc: dbg(opr_subeqc);
muleqc: dbg(opr_muleqc ); muleqc: dbg(opr_muleqc);
diveqc: dbg(opr_diveqc ); diveqc: dbg(opr_diveqc);
lnkeqc: dbg(opr_lnkeqc ); lnkeqc: dbg(opr_lnkeqc);
meq: dbg(opr_meq ); meq: dbg(opr_meq );
eq: dbg(opr_eq ); eq: dbg(opr_eq );
neq: dbg(opr_neq ); neq: dbg(opr_neq );
less: dbg(opr_less ); less: dbg(opr_less );
leq: dbg(opr_leq ); leq: dbg(opr_leq );
grt: dbg(opr_grt ); grt: dbg(opr_grt );
geq: dbg(opr_geq ); geq: dbg(opr_geq );
lessc: dbg(opr_lessc ); lessc: dbg(opr_lessc );
leqc: dbg(opr_leqc ); leqc: dbg(opr_leqc );
grtc: dbg(opr_grtc ); grtc: dbg(opr_grtc );
geqc: dbg(opr_geqc ); geqc: dbg(opr_geqc );
pop: dbg(opr_pop ); pop: dbg(opr_pop );
jmp: dbg(opr_jmp ); jmp: dbg(opr_jmp );
jt: dbg(opr_jt ); jt: dbg(opr_jt );
jf: dbg(opr_jf ); jf: dbg(opr_jf );
counter: dbg(opr_counter ); cnt: dbg(opr_cnt );
findex: dbg(opr_findex ); findex: dbg(opr_findex);
feach: dbg(opr_feach ); feach: dbg(opr_feach );
callg: dbg(opr_callg ); callg: dbg(opr_callg );
calll: dbg(opr_calll ); calll: dbg(opr_calll );
upval: dbg(opr_upval ); upval: dbg(opr_upval );
callv: dbg(opr_callv ); callv: dbg(opr_callv );
callvi: dbg(opr_callvi ); callvi: dbg(opr_callvi);
callh: dbg(opr_callh ); callh: dbg(opr_callh );
callfv: dbg(opr_callfv ); callfv: dbg(opr_callfv);
callfh: dbg(opr_callfh ); callfh: dbg(opr_callfh);
callb: dbg(opr_callb ); callb: dbg(opr_callb );
slcbegin:dbg(opr_slcbegin); slcbeg: dbg(opr_slcbeg);
slcend: dbg(opr_slcend ); slcend: dbg(opr_slcend);
slc: dbg(opr_slc ); slc: dbg(opr_slc );
slc2: dbg(opr_slc2 ); slc2: dbg(opr_slc2 );
mcallg: dbg(opr_mcallg ); mcallg: dbg(opr_mcallg);
mcalll: dbg(opr_mcalll ); mcalll: dbg(opr_mcalll);
mupval: dbg(opr_mupval ); mupval: dbg(opr_mupval);
mcallv: dbg(opr_mcallv ); mcallv: dbg(opr_mcallv);
mcallh: dbg(opr_mcallh ); mcallh: dbg(opr_mcallh);
ret: dbg(opr_ret ); ret: dbg(opr_ret );
} }
#endif #endif

View File

@ -61,8 +61,8 @@ protected:
void opr_newf(); void opr_newf();
void opr_happ(); void opr_happ();
void opr_para(); void opr_para();
void opr_defpara(); void opr_deft();
void opr_dynpara(); void opr_dyn();
void opr_unot(); void opr_unot();
void opr_usub(); void opr_usub();
void opr_add(); void opr_add();
@ -100,7 +100,7 @@ protected:
void opr_jmp(); void opr_jmp();
void opr_jt(); void opr_jt();
void opr_jf(); void opr_jf();
void opr_counter(); void opr_cnt();
void opr_findex(); void opr_findex();
void opr_feach(); void opr_feach();
void opr_callg(); void opr_callg();
@ -112,7 +112,7 @@ protected:
void opr_callfv(); void opr_callfv();
void opr_callfh(); void opr_callfh();
void opr_callb(); void opr_callb();
void opr_slcbegin(); void opr_slcbeg();
void opr_slcend(); void opr_slcend();
void opr_slc(); void opr_slc();
void opr_slc2(); void opr_slc2();
@ -179,13 +179,9 @@ void nasal_vm::bytecodeinfo(const char* header,const uint32_t p)
{ {
const opcode& c=bytecode[p]; const opcode& c=bytecode[p];
printf("%s0x%.8x: %.2x %.2x %.2x %.2x %.2x %s ", printf("%s0x%.8x: %.2x %.2x %.2x %.2x %.2x %s ",
header, header,p,c.op,
p, uint8_t((c.num>>24)&0xff),uint8_t((c.num>>16)&0xff),
c.op, uint8_t((c.num>>8)&0xff),uint8_t(c.num&0xff),
uint8_t((c.num>>24)&0xff),
uint8_t((c.num>>16)&0xff),
uint8_t((c.num>>8)&0xff),
uint8_t(c.num&0xff),
code_table[c.op].name code_table[c.op].name
); );
switch(c.op) switch(c.op)
@ -217,7 +213,7 @@ void nasal_vm::bytecodeinfo(const char* header,const uint32_t p)
case op_happ: case op_pstr: case op_happ: case op_pstr:
case op_lnkc: case op_lnkc:
case op_callh: case op_mcallh: case op_callh: case op_mcallh:
case op_para: case op_defpara:case op_dynpara: case op_para: case op_deft: case op_dyn:
printf("0x%x (\"%s\")",c.num,rawstr(str_table[c.num],16).c_str()); printf("0x%x (\"%s\")",c.num,rawstr(str_table[c.num],16).c_str());
break; break;
default:printf("0x%x",c.num);break; default:printf("0x%x",c.num);break;
@ -471,14 +467,14 @@ inline void nasal_vm::opr_para()
func.keys[str_table[imm[pc]]]=func.psize;// func->size has 1 place reserved for "me" func.keys[str_table[imm[pc]]]=func.psize;// func->size has 1 place reserved for "me"
func.local[func.psize++]={vm_none}; func.local[func.psize++]={vm_none};
} }
inline void nasal_vm::opr_defpara() inline void nasal_vm::opr_deft()
{ {
nasal_ref val=top[0]; nasal_ref val=top[0];
nasal_func& func=(--top)[0].func(); nasal_func& func=(--top)[0].func();
func.keys[str_table[imm[pc]]]=func.psize;// func->size has 1 place reserved for "me" func.keys[str_table[imm[pc]]]=func.psize;// func->size has 1 place reserved for "me"
func.local[func.psize++]=val; func.local[func.psize++]=val;
} }
inline void nasal_vm::opr_dynpara() inline void nasal_vm::opr_dyn()
{ {
top[0].func().dynpara=imm[pc]; top[0].func().dynpara=imm[pc];
} }
@ -646,7 +642,7 @@ inline void nasal_vm::opr_jf()
pc=imm[pc]-1; pc=imm[pc]-1;
--top; --top;
} }
inline void nasal_vm::opr_counter() inline void nasal_vm::opr_cnt()
{ {
(++top)[0]={vm_cnt,(int64_t)-1}; (++top)[0]={vm_cnt,(int64_t)-1};
if(top[-1].type!=vm_vec) if(top[-1].type!=vm_vec)
@ -829,7 +825,7 @@ inline void nasal_vm::opr_callb()
if(top[0].type==vm_none) if(top[0].type==vm_none)
die("native function error."); die("native function error.");
} }
inline void nasal_vm::opr_slcbegin() inline void nasal_vm::opr_slcbeg()
{ {
// +--------------+ // +--------------+
// | slice_vector | <-- top[0] // | slice_vector | <-- top[0]
@ -998,29 +994,29 @@ void nasal_vm::run(
{ {
detail_info=detail; detail_info=detail;
init(gen.get_strs(),gen.get_nums(),gen.get_code(),linker.get_file(),argv); init(gen.get_strs(),gen.get_nums(),gen.get_code(),linker.get_file(),argv);
uint64_t count[op_ret+1]={0};
const void* oprs[]= const void* oprs[]=
{ {
&&vmexit, &&intg, &&intl, &&loadg, &&vmexit, &&intg, &&intl, &&loadg,
&&loadl, &&loadu, &&pnum, &&pnil, &&loadl, &&loadu, &&pnum, &&pnil,
&&pstr, &&newv, &&newh, &&newf, &&pstr, &&newv, &&newh, &&newf,
&&happ, &&para, &&defpara,&&dynpara, &&happ, &&para, &&deft, &&dyn,
&&unot, &&usub, &&add, &&sub, &&unot, &&usub, &&add, &&sub,
&&mul, &&div, &&lnk, &&addc, &&mul, &&div, &&lnk, &&addc,
&&subc, &&mulc, &&divc, &&lnkc, &&subc, &&mulc, &&divc, &&lnkc,
&&addeq, &&subeq, &&muleq, &&diveq, &&addeq, &&subeq, &&muleq, &&diveq,
&&lnkeq, &&addeqc, &&subeqc, &&muleqc, &&lnkeq, &&addeqc, &&subeqc, &&muleqc,
&&diveqc, &&lnkeqc, &&meq, &&eq, &&diveqc, &&lnkeqc, &&meq, &&eq,
&&neq, &&less, &&leq, &&grt, &&neq, &&less, &&leq, &&grt,
&&geq, &&lessc, &&leqc, &&grtc, &&geq, &&lessc, &&leqc, &&grtc,
&&geqc, &&pop, &&jmp, &&jt, &&geqc, &&pop, &&jmp, &&jt,
&&jf, &&counter, &&findex, &&feach, &&jf, &&cnt, &&findex, &&feach,
&&callg, &&calll, &&upval, &&callv, &&callg, &&calll, &&upval, &&callv,
&&callvi, &&callh, &&callfv, &&callfh, &&callvi, &&callh, &&callfv, &&callfh,
&&callb, &&slcbegin, &&slcend, &&slc, &&callb, &&slcbeg, &&slcend, &&slc,
&&slc2, &&mcallg, &&mcalll, &&mupval, &&slc2, &&mcallg, &&mcalll, &&mupval,
&&mcallv, &&mcallh, &&ret &&mcallv, &&mcallh, &&ret
}; };
uint64_t count[op_ret+1]={0};
std::vector<const void*> code; std::vector<const void*> code;
for(auto& i:gen.get_code()) for(auto& i:gen.get_code())
{ {
@ -1041,83 +1037,83 @@ vmexit:
imm.clear(); imm.clear();
return; return;
// may cause stackoverflow // may cause stackoverflow
#define exec_operand(op,num) {op();++count[num];if(top<canary)goto *code[++pc];goto vmexit;} #define exec_operand(op,num) {++count[num];op();if(top<canary)goto *code[++pc];goto vmexit;}
// do not cause stackoverflow // do not cause stackoverflow
#define exec_opnodie(op,num) {op();++count[num];goto *code[++pc];} #define exec_opnodie(op,num) {++count[num];op();goto *code[++pc];}
intg: exec_opnodie(opr_intg ,op_intg ); // +imm[pc] (detected at codegen) intg: exec_opnodie(opr_intg ,op_intg ); // +imm[pc] (detected at codegen)
intl: exec_opnodie(opr_intl ,op_intl ); // -0 intl: exec_opnodie(opr_intl ,op_intl ); // -0
loadg: exec_opnodie(opr_loadg ,op_loadg ); // -1 loadg: exec_opnodie(opr_loadg ,op_loadg ); // -1
loadl: exec_opnodie(opr_loadl ,op_loadl ); // -1 loadl: exec_opnodie(opr_loadl ,op_loadl ); // -1
loadu: exec_opnodie(opr_loadu ,op_loadu ); // -1 loadu: exec_opnodie(opr_loadu ,op_loadu ); // -1
pnum: exec_operand(opr_pnum ,op_pnum ); // +1 pnum: exec_operand(opr_pnum ,op_pnum ); // +1
pnil: exec_operand(opr_pnil ,op_pnil ); // +1 pnil: exec_operand(opr_pnil ,op_pnil ); // +1
pstr: exec_operand(opr_pstr ,op_pstr ); // +1 pstr: exec_operand(opr_pstr ,op_pstr ); // +1
newv: exec_operand(opr_newv ,op_newv ); // +1-imm[pc] newv: exec_operand(opr_newv ,op_newv ); // +1-imm[pc]
newh: exec_operand(opr_newh ,op_newh ); // +1 newh: exec_operand(opr_newh ,op_newh ); // +1
newf: exec_operand(opr_newf ,op_newf ); // +1 newf: exec_operand(opr_newf ,op_newf ); // +1
happ: exec_opnodie(opr_happ ,op_happ ); // -1 happ: exec_opnodie(opr_happ ,op_happ ); // -1
para: exec_opnodie(opr_para ,op_para ); // -0 para: exec_opnodie(opr_para ,op_para ); // -0
defpara: exec_opnodie(opr_defpara ,op_defpara ); // -1 deft: exec_opnodie(opr_deft ,op_deft ); // -1
dynpara: exec_opnodie(opr_dynpara ,op_dynpara ); // -0 dyn: exec_opnodie(opr_dyn ,op_dyn ); // -0
unot: exec_opnodie(opr_unot ,op_unot ); // -0 unot: exec_opnodie(opr_unot ,op_unot ); // -0
usub: exec_opnodie(opr_usub ,op_usub ); // -0 usub: exec_opnodie(opr_usub ,op_usub ); // -0
add: exec_opnodie(opr_add ,op_add ); // -1 add: exec_opnodie(opr_add ,op_add ); // -1
sub: exec_opnodie(opr_sub ,op_sub ); // -1 sub: exec_opnodie(opr_sub ,op_sub ); // -1
mul: exec_opnodie(opr_mul ,op_mul ); // -1 mul: exec_opnodie(opr_mul ,op_mul ); // -1
div: exec_opnodie(opr_div ,op_div ); // -1 div: exec_opnodie(opr_div ,op_div ); // -1
lnk: exec_opnodie(opr_lnk ,op_lnk ); // -1 lnk: exec_opnodie(opr_lnk ,op_lnk ); // -1
addc: exec_opnodie(opr_addc ,op_addc ); // -0 addc: exec_opnodie(opr_addc ,op_addc ); // -0
subc: exec_opnodie(opr_subc ,op_subc ); // -0 subc: exec_opnodie(opr_subc ,op_subc ); // -0
mulc: exec_opnodie(opr_mulc ,op_mulc ); // -0 mulc: exec_opnodie(opr_mulc ,op_mulc ); // -0
divc: exec_opnodie(opr_divc ,op_divc ); // -0 divc: exec_opnodie(opr_divc ,op_divc ); // -0
lnkc: exec_opnodie(opr_lnkc ,op_lnkc ); // -0 lnkc: exec_opnodie(opr_lnkc ,op_lnkc ); // -0
addeq: exec_opnodie(opr_addeq ,op_addeq ); // -1 addeq: exec_opnodie(opr_addeq ,op_addeq ); // -1
subeq: exec_opnodie(opr_subeq ,op_subeq ); // -1 subeq: exec_opnodie(opr_subeq ,op_subeq ); // -1
muleq: exec_opnodie(opr_muleq ,op_muleq ); // -1 muleq: exec_opnodie(opr_muleq ,op_muleq ); // -1
diveq: exec_opnodie(opr_diveq ,op_diveq ); // -1 diveq: exec_opnodie(opr_diveq ,op_diveq ); // -1
lnkeq: exec_opnodie(opr_lnkeq ,op_lnkeq ); // -1 lnkeq: exec_opnodie(opr_lnkeq ,op_lnkeq ); // -1
addeqc: exec_opnodie(opr_addeqc ,op_addeqc ); // -0 addeqc: exec_opnodie(opr_addeqc,op_addeqc); // -0
subeqc: exec_opnodie(opr_subeqc ,op_subeqc ); // -0 subeqc: exec_opnodie(opr_subeqc,op_subeqc); // -0
muleqc: exec_opnodie(opr_muleqc ,op_muleqc ); // -0 muleqc: exec_opnodie(opr_muleqc,op_muleqc); // -0
diveqc: exec_opnodie(opr_diveqc ,op_diveqc ); // -0 diveqc: exec_opnodie(opr_diveqc,op_diveqc); // -0
lnkeqc: exec_opnodie(opr_lnkeqc ,op_lnkeqc ); // -0 lnkeqc: exec_opnodie(opr_lnkeqc,op_lnkeqc); // -0
meq: exec_opnodie(opr_meq ,op_meq ); // -1 meq: exec_opnodie(opr_meq ,op_meq ); // -1
eq: exec_opnodie(opr_eq ,op_eq ); // -1 eq: exec_opnodie(opr_eq ,op_eq ); // -1
neq: exec_opnodie(opr_neq ,op_neq ); // -1 neq: exec_opnodie(opr_neq ,op_neq ); // -1
less: exec_opnodie(opr_less ,op_less ); // -1 less: exec_opnodie(opr_less ,op_less ); // -1
leq: exec_opnodie(opr_leq ,op_leq ); // -1 leq: exec_opnodie(opr_leq ,op_leq ); // -1
grt: exec_opnodie(opr_grt ,op_grt ); // -1 grt: exec_opnodie(opr_grt ,op_grt ); // -1
geq: exec_opnodie(opr_geq ,op_geq ); // -1 geq: exec_opnodie(opr_geq ,op_geq ); // -1
lessc: exec_opnodie(opr_lessc ,op_lessc ); // -0 lessc: exec_opnodie(opr_lessc ,op_lessc ); // -0
leqc: exec_opnodie(opr_leqc ,op_leqc ); // -0 leqc: exec_opnodie(opr_leqc ,op_leqc ); // -0
grtc: exec_opnodie(opr_grtc ,op_grtc ); // -0 grtc: exec_opnodie(opr_grtc ,op_grtc ); // -0
geqc: exec_opnodie(opr_geqc ,op_geqc ); // -0 geqc: exec_opnodie(opr_geqc ,op_geqc ); // -0
pop: exec_opnodie(opr_pop ,op_pop ); // -1 pop: exec_opnodie(opr_pop ,op_pop ); // -1
jmp: exec_opnodie(opr_jmp ,op_jmp ); // -0 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 cnt: exec_opnodie(opr_cnt ,op_cnt ); // -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
calll: exec_operand(opr_calll ,op_calll ); // +1 calll: exec_operand(opr_calll ,op_calll ); // +1
upval: exec_operand(opr_upval ,op_upval ); // +1 upval: exec_operand(opr_upval ,op_upval ); // +1
callv: exec_opnodie(opr_callv ,op_callv ); // -0 callv: exec_opnodie(opr_callv ,op_callv ); // -0
callvi: exec_opnodie(opr_callvi ,op_callvi ); // -0 callvi: exec_opnodie(opr_callvi,op_callvi); // -0
callh: exec_opnodie(opr_callh ,op_callh ); // -0 callh: exec_opnodie(opr_callh ,op_callh ); // -0
callfv: exec_opnodie(opr_callfv ,op_callfv ); // check in the function callfv: exec_opnodie(opr_callfv,op_callfv); // check in the function
callfh: exec_opnodie(opr_callfh ,op_callfh ); // check in the function callfh: exec_opnodie(opr_callfh,op_callfh); // check in the function
callb: exec_opnodie(opr_callb ,op_callb ); // -0 callb: exec_opnodie(opr_callb ,op_callb ); // -0
slcbegin:exec_operand(opr_slcbegin,op_slcbegin); // +1 slcbeg: exec_operand(opr_slcbeg,op_slcbeg); // +1
slcend: exec_opnodie(opr_slcend ,op_slcend ); // -1 slcend: exec_opnodie(opr_slcend,op_slcend); // -1
slc: exec_opnodie(opr_slc ,op_slc ); // -1 slc: exec_opnodie(opr_slc ,op_slc ); // -1
slc2: exec_opnodie(opr_slc2 ,op_slc2 ); // -2 slc2: exec_opnodie(opr_slc2 ,op_slc2 ); // -2
mcallg: exec_operand(opr_mcallg ,op_mcallg ); // +1 mcallg: exec_operand(opr_mcallg,op_mcallg); // +1
mcalll: exec_operand(opr_mcalll ,op_mcalll ); // +1 mcalll: exec_operand(opr_mcalll,op_mcalll); // +1
mupval: exec_operand(opr_mupval ,op_mupval ); // +1 mupval: exec_operand(opr_mupval,op_mupval); // +1
mcallv: exec_opnodie(opr_mcallv ,op_mcallv ); // -0 mcallv: exec_opnodie(opr_mcallv,op_mcallv); // -0
mcallh: exec_opnodie(opr_mcallh ,op_mcallh ); // -0 mcallh: exec_opnodie(opr_mcallh,op_mcallh); // -0
ret: exec_opnodie(opr_ret ,op_ret ); // -2 ret: exec_opnodie(opr_ret ,op_ret ); // -2
} }
#endif #endif