nothing changed

This commit is contained in:
Valk Richard Li 2021-06-20 01:27:01 +08:00
parent cdf7b92a8e
commit 00c6e3b4fd
7 changed files with 231 additions and 277 deletions

View File

@ -245,11 +245,11 @@ f(1024,2048);
## Test data ## Test data
### version 6.5 gc(i5-8250U windows10) ### version 6.5(i5-8250U windows10 2021/6/19)
running time and gc time: running time and gc time:
|file|call|total time|gc time| |file|call gc|total time|gc time|
|:----|:----|:----|:----| |:----|:----|:----|:----|
|pi.nas|12000049|0.593s|0.222s| |pi.nas|12000049|0.593s|0.222s|
|fib.nas|10573747|2.838s|0.187s| |fib.nas|10573747|2.838s|0.187s|
@ -264,7 +264,7 @@ running time and gc time:
operands calling frequency: operands calling frequency:
|file|1st called op|2nd called op|3rd called op|4th called op|5th called op| |file|1st|2nd|3rd|4th|5th|
|:----|:----|:----|:----|:----|:----| |:----|:----|:----|:----|:----|:----|
|pi.nas|callg|pop|mcallg|pnum|pone| |pi.nas|callg|pop|mcallg|pnum|pone|
|fib.nas|calll|pnum|callg|less|jf| |fib.nas|calll|pnum|callg|less|jf|
@ -279,7 +279,7 @@ operands calling frequency:
operands calling total times: operands calling total times:
|file|1st called time|2nd called time|3rd called time|4th called time|5th called time| |file|1st|2nd|3rd|4th|5th|
|:----|:----|:----|:----|:----|:----| |:----|:----|:----|:----|:----|:----|
|pi.nas|6000004|6000003|6000000|4000005|4000002| |pi.nas|6000004|6000003|6000000|4000005|4000002|
|fib.nas|17622792|10573704|7049218|7049155|7049155| |fib.nas|17622792|10573704|7049218|7049155|7049155|

View File

@ -26,7 +26,6 @@
check if a string can be converted to a number check if a string can be converted to a number
if this string cannot be converted to a number,it will return nan if this string cannot be converted to a number,it will return nan
*/ */
inline double hex_to_double(const char* str) inline double hex_to_double(const char* str)
{ {
double ret=0; double ret=0;

View File

@ -62,55 +62,55 @@ void builtin_err(const char* func_name,std::string info)
} }
// register builtin function's name and it's address here in this table below // register builtin function's name and it's address here in this table below
// this table must end with {"",NULL} // this table must end with {"",nullptr}
struct FUNC_TABLE struct FUNC_TABLE
{ {
const char* name; const char* name;
nasal_val* (*func)(std::vector<nasal_val*>&,nasal_gc&); nasal_val* (*func)(std::vector<nasal_val*>&,nasal_gc&);
} builtin_func[]= } builtin_func[]=
{ {
{"__builtin_print", builtin_print }, {"__builtin_print", builtin_print },
{"__builtin_append", builtin_append }, {"__builtin_append", builtin_append },
{"__builtin_setsize", builtin_setsize }, {"__builtin_setsize", builtin_setsize },
{"__builtin_system", builtin_system }, {"__builtin_system", builtin_system },
{"__builtin_input", builtin_input }, {"__builtin_input", builtin_input },
{"__builtin_sleep", builtin_sleep }, {"__builtin_sleep", builtin_sleep },
{"__builtin_fin", builtin_fin }, {"__builtin_fin", builtin_fin },
{"__builtin_fout", builtin_fout }, {"__builtin_fout", builtin_fout },
{"__builtin_split", builtin_split }, {"__builtin_split", builtin_split },
{"__builtin_rand", builtin_rand }, {"__builtin_rand", builtin_rand },
{"__builtin_id", builtin_id }, {"__builtin_id", builtin_id },
{"__builtin_int", builtin_int }, {"__builtin_int", builtin_int },
{"__builtin_num", builtin_num }, {"__builtin_num", builtin_num },
{"__builtin_pop", builtin_pop }, {"__builtin_pop", builtin_pop },
{"__builtin_str", builtin_str }, {"__builtin_str", builtin_str },
{"__builtin_size", builtin_size }, {"__builtin_size", builtin_size },
{"__builtin_xor", builtin_xor }, {"__builtin_xor", builtin_xor },
{"__builtin_and", builtin_and }, {"__builtin_and", builtin_and },
{"__builtin_or", builtin_or }, {"__builtin_or", builtin_or },
{"__builtin_nand", builtin_nand }, {"__builtin_nand", builtin_nand },
{"__builtin_not", builtin_not }, {"__builtin_not", builtin_not },
{"__builtin_sin", builtin_sin }, {"__builtin_sin", builtin_sin },
{"__builtin_cos", builtin_cos }, {"__builtin_cos", builtin_cos },
{"__builtin_tan", builtin_tan }, {"__builtin_tan", builtin_tan },
{"__builtin_exp", builtin_exp }, {"__builtin_exp", builtin_exp },
{"__builtin_ln", builtin_ln }, {"__builtin_ln", builtin_ln },
{"__builtin_sqrt", builtin_sqrt }, {"__builtin_sqrt", builtin_sqrt },
{"__builtin_atan2", builtin_atan2 }, {"__builtin_atan2", builtin_atan2 },
{"__builtin_time", builtin_time }, {"__builtin_time", builtin_time },
{"__builtin_contains", builtin_contains}, {"__builtin_contains",builtin_contains},
{"__builtin_delete", builtin_delete }, {"__builtin_delete", builtin_delete },
{"__builtin_keys", builtin_keys }, {"__builtin_keys", builtin_keys },
{"__builtin_import", builtin_import }, {"__builtin_import", builtin_import },
{"__builtin_die", builtin_die }, {"__builtin_die", builtin_die },
{"__builtin_type", builtin_type }, {"__builtin_type", builtin_type },
{"__builtin_substr", builtin_substr }, {"__builtin_substr", builtin_substr },
{"__builtin_streq", builtin_streq }, {"__builtin_streq", builtin_streq },
{"__builtin_left", builtin_left }, {"__builtin_left", builtin_left },
{"__builtin_right", builtin_right }, {"__builtin_right", builtin_right },
{"__builtin_cmp", builtin_cmp }, {"__builtin_cmp", builtin_cmp },
{"__builtin_chr", builtin_chr }, {"__builtin_chr", builtin_chr },
{nullptr, nullptr } {nullptr, nullptr }
}; };
nasal_val* builtin_print(std::vector<nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_print(std::vector<nasal_val*>& local_scope,nasal_gc& gc)

View File

@ -73,69 +73,69 @@ struct
const char* name; const char* name;
}code_table[]= }code_table[]=
{ {
{op_nop, "nop "}, {op_nop, "nop "},
{op_intg, "intg "}, {op_intg, "intg "},
{op_intl, "intl "}, {op_intl, "intl "},
{op_offset, "offset"}, {op_offset, "offset"},
{op_loadg, "loadg "}, {op_loadg, "loadg "},
{op_loadl, "loadl "}, {op_loadl, "loadl "},
{op_pnum, "pnum "}, {op_pnum, "pnum "},
{op_pone, "pone "}, {op_pone, "pone "},
{op_pzero, "pzero "}, {op_pzero, "pzero "},
{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_defpara, "def "},
{op_dynpara, "dyn "}, {op_dynpara, "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, "link "}, {op_lnk, "link "},
{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_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_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_cntpop, "cntpop"}, {op_cntpop, "cntpop"},
{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_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_slcbegin,"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_mcallv, "mcallv"}, {op_mcallv, "mcallv"},
{op_mcallh, "mcallh"}, {op_mcallh, "mcallh"},
{op_ret, "ret "}, {op_ret, "ret "},
{-1, NULL }, {-1, nullptr },
}; };
struct opcode struct opcode
@ -211,7 +211,6 @@ private:
void block_gen(nasal_ast&); void block_gen(nasal_ast&);
void ret_gen(nasal_ast&); void ret_gen(nasal_ast&);
public: public:
nasal_codegen();
int get_error(){return error;} int get_error(){return error;}
void main_progress(nasal_ast&); void main_progress(nasal_ast&);
void print_op(int); void print_op(int);
@ -221,14 +220,6 @@ public:
std::vector<opcode>& get_exec_code(){return exec_code;} std::vector<opcode>& get_exec_code(){return exec_code;}
}; };
nasal_codegen::nasal_codegen()
{
error=0;
in_foreach=0;
in_forindex=0;
return;
}
void nasal_codegen::die(std::string info,int line) void nasal_codegen::die(std::string info,int line)
{ {
++error; ++error;
@ -301,8 +292,8 @@ void nasal_codegen::gen(uint8_t op,uint32_t num)
void nasal_codegen::num_gen(nasal_ast& ast) void nasal_codegen::num_gen(nasal_ast& ast)
{ {
double num=ast.get_num(); double num=ast.get_num();
if(num==1) gen(op_pone,0); if(num==0)gen(op_pzero,0);
else if(num==0) gen(op_pzero,0); else if(num==1)gen(op_pone,0);
else else
{ {
regist_number(num); regist_number(num);
@ -346,8 +337,7 @@ void nasal_codegen::func_gen(nasal_ast& ast)
gen(op_newf,0); gen(op_newf,0);
int local_label=exec_code.size(); int local_label=exec_code.size();
gen(op_intl,0); gen(op_intl,0);
std::vector<std::string> new_scope; local.push_back(std::vector<std::string>());
local.push_back(new_scope);
// add special keyword 'me' into symbol table // add special keyword 'me' into symbol table
// this symbol is only used in local scope(function's scope) // this symbol is only used in local scope(function's scope)
@ -392,8 +382,8 @@ void nasal_codegen::func_gen(nasal_ast& ast)
exec_code[newfunc_label].num=exec_code.size()+1; exec_code[newfunc_label].num=exec_code.size()+1;
int jmp_ptr=exec_code.size(); int jmp_ptr=exec_code.size();
gen(op_jmp,0); gen(op_jmp,0);
nasal_ast& block=ast.get_children()[1];
nasal_ast& block=ast.get_children()[1];
block_gen(block); block_gen(block);
for(auto& i:local) for(auto& i:local)
exec_code[local_label].num+=i.size(); exec_code[local_label].num+=i.size();
@ -509,10 +499,7 @@ void nasal_codegen::call_func(nasal_ast& ast)
void nasal_codegen::mcall(nasal_ast& ast) void nasal_codegen::mcall(nasal_ast& ast)
{ {
if(ast.get_type()==ast_id) mcall_id(ast.get_type()==ast_id?ast:ast.get_children()[0]);
mcall_id(ast);
else
mcall_id(ast.get_children()[0]);
int child_size=ast.get_children().size(); int child_size=ast.get_children().size();
for(int i=1;i<child_size;++i) for(int i=1;i<child_size;++i)
{ {
@ -671,9 +658,8 @@ void nasal_codegen::conditional_gen(nasal_ast& ast)
void nasal_codegen::loop_gen(nasal_ast& ast) void nasal_codegen::loop_gen(nasal_ast& ast)
{ {
std::vector<int> new_level; continue_ptr.push_front(std::vector<int>());
continue_ptr.push_front(new_level); break_ptr.push_front(std::vector<int>());
break_ptr.push_front(new_level);
switch(ast.get_type()) switch(ast.get_type())
{ {
case ast_while: while_gen(ast); break; case ast_while: while_gen(ast); break;
@ -1009,6 +995,9 @@ void nasal_codegen::ret_gen(nasal_ast& ast)
void nasal_codegen::main_progress(nasal_ast& ast) void nasal_codegen::main_progress(nasal_ast& ast)
{ {
error=0; error=0;
in_foreach=0;
in_forindex=0;
number_table.clear(); number_table.clear();
string_table.clear(); string_table.clear();
exec_code.clear(); exec_code.clear();

View File

@ -82,7 +82,7 @@ struct
{"<=" ,tok_leq }, {"<=" ,tok_leq },
{">" ,tok_grt }, {">" ,tok_grt },
{">=" ,tok_geq }, {">=" ,tok_geq },
{NULL ,-1 } {nullptr ,-1 }
}; };
struct token struct token

View File

@ -48,7 +48,6 @@ private:
std::vector<token> error_token; std::vector<token> error_token;
int in_function; // count when generating function block,used to check return-expression int in_function; // count when generating function block,used to check return-expression
int in_loop; // count when generating loop block,used to check break/continue-expression int in_loop; // count when generating loop block,used to check break/continue-expression
void reset();
void die(int,std::string); void die(int,std::string);
void match(int type,std::string err_info=""); void match(int type,std::string err_info="");
bool check_comma(int*); bool check_comma(int*);
@ -106,7 +105,10 @@ public:
}; };
void nasal_parse::main_process() void nasal_parse::main_process()
{ {
reset(); ptr=in_function=in_loop=error=0;
root.clear();
error_token.clear();
root.set_line(1); root.set_line(1);
root.set_type(ast_root); root.set_type(ast_root);
while(tok_list[ptr].type!=tok_eof) while(tok_list[ptr].type!=tok_eof)
@ -138,13 +140,6 @@ void nasal_parse::main_process()
<<"please check \'(\',\'[\',\'{\',\')\',\']\',\'}\' match or not.\n"; <<"please check \'(\',\'[\',\'{\',\')\',\']\',\'}\' match or not.\n";
return; return;
} }
void nasal_parse::reset()
{
ptr=in_function=in_loop=error=0;
root.clear();
error_token.clear();
return;
}
void nasal_parse::die(int line,std::string info) void nasal_parse::die(int line,std::string info)
{ {
++error; ++error;
@ -285,13 +280,11 @@ void nasal_parse::check_memory_reachable(nasal_ast& node)
} }
nasal_ast nasal_parse::null_node_gen() nasal_ast nasal_parse::null_node_gen()
{ {
nasal_ast node(tok_list[ptr].line,ast_null); return nasal_ast(tok_list[ptr].line,ast_null);
return node;
} }
nasal_ast nasal_parse::nil_gen() nasal_ast nasal_parse::nil_gen()
{ {
nasal_ast node(tok_list[ptr].line,ast_nil); return nasal_ast(tok_list[ptr].line,ast_nil);
return node;
} }
nasal_ast nasal_parse::num_gen() nasal_ast nasal_parse::num_gen()
{ {
@ -336,7 +329,7 @@ nasal_ast nasal_parse::hash_gen()
{ {
nasal_ast node(tok_list[ptr].line,ast_hash); nasal_ast node(tok_list[ptr].line,ast_hash);
match(tok_lbrace); match(tok_lbrace);
while (tok_list[ptr].type!=tok_rbrace) while(tok_list[ptr].type!=tok_rbrace)
{ {
node.add_child(hmem_gen()); node.add_child(hmem_gen());
if(tok_list[ptr].type==tok_comma) if(tok_list[ptr].type==tok_comma)

View File

@ -148,12 +148,12 @@ void nasal_vm::opr_intg()
} }
void nasal_vm::opr_intl() void nasal_vm::opr_intl()
{ {
(*stack_top)->ptr.func->closure.resize(exec_code[pc].num,gc.nil_addr); stack_top[0]->ptr.func->closure.resize(exec_code[pc].num,gc.nil_addr);
return; return;
} }
void nasal_vm::opr_offset() void nasal_vm::opr_offset()
{ {
(*stack_top)->ptr.func->offset=exec_code[pc].num; stack_top[0]->ptr.func->offset=exec_code[pc].num;
return; return;
} }
void nasal_vm::opr_loadg() void nasal_vm::opr_loadg()
@ -168,27 +168,27 @@ void nasal_vm::opr_loadl()
} }
void nasal_vm::opr_pnum() void nasal_vm::opr_pnum()
{ {
*(++stack_top)=gc.num_addrs[exec_code[pc].num]; (++stack_top)[0]=gc.num_addrs[exec_code[pc].num];
return; return;
} }
void nasal_vm::opr_pone() void nasal_vm::opr_pone()
{ {
*(++stack_top)=gc.one_addr; (++stack_top)[0]=gc.one_addr;
return; return;
} }
void nasal_vm::opr_pzero() void nasal_vm::opr_pzero()
{ {
*(++stack_top)=gc.zero_addr; (++stack_top)[0]=gc.zero_addr;
return; return;
} }
void nasal_vm::opr_pnil() void nasal_vm::opr_pnil()
{ {
*(++stack_top)=gc.nil_addr; (++stack_top)[0]=gc.nil_addr;
return; return;
} }
void nasal_vm::opr_pstr() void nasal_vm::opr_pstr()
{ {
*(++stack_top)=gc.str_addrs[exec_code[pc].num]; (++stack_top)[0]=gc.str_addrs[exec_code[pc].num];
return; return;
} }
void nasal_vm::opr_newv() void nasal_vm::opr_newv()
@ -200,13 +200,12 @@ void nasal_vm::opr_newv()
for(int i=0;i<exec_code[pc].num;++i) for(int i=0;i<exec_code[pc].num;++i)
vec[i]=begin[i]; vec[i]=begin[i];
stack_top=begin; stack_top=begin;
*stack_top=vec_addr; stack_top[0]=vec_addr;
return; return;
} }
void nasal_vm::opr_newh() void nasal_vm::opr_newh()
{ {
nasal_val* hash=gc.gc_alloc(vm_hash); (++stack_top)[0]=gc.gc_alloc(vm_hash);
*(++stack_top)=hash;
return; return;
} }
void nasal_vm::opr_newf() void nasal_vm::opr_newf()
@ -217,51 +216,52 @@ void nasal_vm::opr_newf()
val->ptr.func->closure.push_back(gc.nil_addr);// me val->ptr.func->closure.push_back(gc.nil_addr);// me
else else
val->ptr.func->closure=gc.local.back();// local contains 'me' val->ptr.func->closure=gc.local.back();// local contains 'me'
*(++stack_top)=val; (++stack_top)[0]=val;
return; return;
} }
void nasal_vm::opr_happ() void nasal_vm::opr_happ()
{ {
nasal_val* val=*stack_top--; nasal_val* val=stack_top[0];
(*stack_top)->ptr.hash->elems[str_table[exec_code[pc].num]]=val; (--stack_top)[0]->ptr.hash->elems[str_table[exec_code[pc].num]]=val;
return; return;
} }
void nasal_vm::opr_para() void nasal_vm::opr_para()
{ {
int size=(*stack_top)->ptr.func->key_table.size(); nasal_func* func=stack_top[0]->ptr.func;
(*stack_top)->ptr.func->key_table[str_table[exec_code[pc].num]]=size; int size=func->key_table.size();
(*stack_top)->ptr.func->default_para.push_back(nullptr); func->key_table[str_table[exec_code[pc].num]]=size;
func->default_para.push_back(nullptr);
return; return;
} }
void nasal_vm::opr_defpara() void nasal_vm::opr_defpara()
{ {
nasal_val* def_val=*stack_top--; nasal_val* def_val=stack_top[0];
int size=(*stack_top)->ptr.func->key_table.size(); nasal_func* func=(--stack_top)[0]->ptr.func;
(*stack_top)->ptr.func->key_table[str_table[exec_code[pc].num]]=size; int size=func->key_table.size();
(*stack_top)->ptr.func->default_para.push_back(def_val); func->key_table[str_table[exec_code[pc].num]]=size;
func->default_para.push_back(def_val);
return; return;
} }
void nasal_vm::opr_dynpara() void nasal_vm::opr_dynpara()
{ {
(*stack_top)->ptr.func->dynpara=exec_code[pc].num; stack_top[0]->ptr.func->dynpara=exec_code[pc].num;
return; return;
} }
void nasal_vm::opr_unot() void nasal_vm::opr_unot()
{ {
nasal_val* val=*stack_top; nasal_val* val=stack_top[0];
nasal_val* new_val=nullptr;
int type=val->type; int type=val->type;
if(type==vm_nil) if(type==vm_nil)
*stack_top=gc.one_addr; stack_top[0]=gc.one_addr;
else if(type==vm_num) else if(type==vm_num)
*stack_top=val->ptr.num?gc.zero_addr:gc.one_addr; stack_top[0]=val->ptr.num?gc.zero_addr:gc.one_addr;
else if(type==vm_str) else if(type==vm_str)
{ {
double number=str2num(val->ptr.str->c_str()); double number=str2num(val->ptr.str->c_str());
if(std::isnan(number)) if(std::isnan(number))
*stack_top=val->ptr.str->empty()?gc.one_addr:gc.zero_addr; stack_top[0]=val->ptr.str->empty()?gc.one_addr:gc.zero_addr;
else else
*stack_top=number?gc.zero_addr:gc.one_addr; stack_top[0]=number?gc.zero_addr:gc.one_addr;
} }
else else
die("unot: incorrect value type"); die("unot: incorrect value type");
@ -269,193 +269,167 @@ void nasal_vm::opr_unot()
} }
void nasal_vm::opr_usub() void nasal_vm::opr_usub()
{ {
nasal_val* val=*stack_top;
nasal_val* new_val=gc.gc_alloc(vm_num); nasal_val* new_val=gc.gc_alloc(vm_num);
new_val->ptr.num=-val->to_number(); new_val->ptr.num=-stack_top[0]->to_number();
*stack_top=new_val; stack_top[0]=new_val;
return; return;
} }
void nasal_vm::opr_add() void nasal_vm::opr_add()
{ {
nasal_val* new_val=gc.gc_alloc(vm_num); nasal_val* new_val=gc.gc_alloc(vm_num);
nasal_val* val2=*stack_top--; new_val->ptr.num=stack_top[-1]->to_number()+stack_top[0]->to_number();
nasal_val* val1=*stack_top; (--stack_top)[0]=new_val;
new_val->ptr.num=val1->to_number()+val2->to_number();
*stack_top=new_val;
return; return;
} }
void nasal_vm::opr_sub() void nasal_vm::opr_sub()
{ {
nasal_val* new_val=gc.gc_alloc(vm_num); nasal_val* new_val=gc.gc_alloc(vm_num);
nasal_val* val2=*stack_top--; new_val->ptr.num=stack_top[-1]->to_number()-stack_top[0]->to_number();
nasal_val* val1=*stack_top; (--stack_top)[0]=new_val;
new_val->ptr.num=val1->to_number()-val2->to_number();
*stack_top=new_val;
return; return;
} }
void nasal_vm::opr_mul() void nasal_vm::opr_mul()
{ {
nasal_val* new_val=gc.gc_alloc(vm_num); nasal_val* new_val=gc.gc_alloc(vm_num);
nasal_val* val2=*stack_top--; new_val->ptr.num=stack_top[-1]->to_number()*stack_top[0]->to_number();
nasal_val* val1=*stack_top; (--stack_top)[0]=new_val;
new_val->ptr.num=val1->to_number()*val2->to_number();
*stack_top=new_val;
return; return;
} }
void nasal_vm::opr_div() void nasal_vm::opr_div()
{ {
nasal_val* new_val=gc.gc_alloc(vm_num); nasal_val* new_val=gc.gc_alloc(vm_num);
nasal_val* val2=*stack_top--; new_val->ptr.num=stack_top[-1]->to_number()/stack_top[0]->to_number();
nasal_val* val1=*stack_top; (--stack_top)[0]=new_val;
new_val->ptr.num=val1->to_number()/val2->to_number();
*stack_top=new_val;
return; return;
} }
void nasal_vm::opr_lnk() void nasal_vm::opr_lnk()
{ {
nasal_val* new_val=gc.gc_alloc(vm_str); nasal_val* new_val=gc.gc_alloc(vm_str);
nasal_val* val2=*stack_top--; *new_val->ptr.str=stack_top[-1]->to_string()+stack_top[0]->to_string();
nasal_val* val1=*stack_top; (--stack_top)[0]=new_val;
*new_val->ptr.str=val1->to_string()+val2->to_string();
*stack_top=new_val;
return; return;
} }
void nasal_vm::opr_addeq() void nasal_vm::opr_addeq()
{ {
nasal_val** mem_addr=addr_stack.top(); nasal_val** mem_addr=addr_stack.top();
addr_stack.pop(); addr_stack.pop();
nasal_val* val2=*stack_top;
nasal_val* val1=*mem_addr;
nasal_val* new_val=gc.gc_alloc(vm_num); nasal_val* new_val=gc.gc_alloc(vm_num);
new_val->ptr.num=val1->to_number()+val2->to_number(); new_val->ptr.num=mem_addr[0]->to_number()+stack_top[0]->to_number();
*stack_top=new_val; stack_top[0]=mem_addr[0]=new_val;
*mem_addr=new_val;
return; return;
} }
void nasal_vm::opr_subeq() void nasal_vm::opr_subeq()
{ {
nasal_val** mem_addr=addr_stack.top(); nasal_val** mem_addr=addr_stack.top();
addr_stack.pop(); addr_stack.pop();
nasal_val* val2=*stack_top;
nasal_val* val1=*mem_addr;
nasal_val* new_val=gc.gc_alloc(vm_num); nasal_val* new_val=gc.gc_alloc(vm_num);
new_val->ptr.num=val1->to_number()-val2->to_number(); new_val->ptr.num=mem_addr[0]->to_number()-stack_top[0]->to_number();
*stack_top=new_val; stack_top[0]=mem_addr[0]=new_val;
*mem_addr=new_val;
return; return;
} }
void nasal_vm::opr_muleq() void nasal_vm::opr_muleq()
{ {
nasal_val** mem_addr=addr_stack.top(); nasal_val** mem_addr=addr_stack.top();
addr_stack.pop(); addr_stack.pop();
nasal_val* val2=*stack_top;
nasal_val* val1=*mem_addr;
nasal_val* new_val=gc.gc_alloc(vm_num); nasal_val* new_val=gc.gc_alloc(vm_num);
new_val->ptr.num=val1->to_number()*val2->to_number(); new_val->ptr.num=mem_addr[0]->to_number()*stack_top[0]->to_number();
*stack_top=new_val; stack_top[0]=mem_addr[0]=new_val;
*mem_addr=new_val;
return; return;
} }
void nasal_vm::opr_diveq() void nasal_vm::opr_diveq()
{ {
nasal_val** mem_addr=addr_stack.top(); nasal_val** mem_addr=addr_stack.top();
addr_stack.pop(); addr_stack.pop();
nasal_val* val2=*stack_top;
nasal_val* val1=*mem_addr;
nasal_val* new_val=gc.gc_alloc(vm_num); nasal_val* new_val=gc.gc_alloc(vm_num);
new_val->ptr.num=val1->to_number()/val2->to_number(); new_val->ptr.num=mem_addr[0]->to_number()/stack_top[0]->to_number();
*stack_top=new_val; stack_top[0]=mem_addr[0]=new_val;
*mem_addr=new_val;
return; return;
} }
void nasal_vm::opr_lnkeq() void nasal_vm::opr_lnkeq()
{ {
nasal_val** mem_addr=addr_stack.top(); nasal_val** mem_addr=addr_stack.top();
addr_stack.pop(); addr_stack.pop();
nasal_val* val2=*stack_top;
nasal_val* val1=*mem_addr;
nasal_val* new_val=gc.gc_alloc(vm_str); nasal_val* new_val=gc.gc_alloc(vm_str);
*new_val->ptr.str=val1->to_string()+val2->to_string(); *new_val->ptr.str=mem_addr[0]->to_string()+stack_top[0]->to_string();
*stack_top=new_val; stack_top[0]=mem_addr[0]=new_val;
*mem_addr=new_val;
return; return;
} }
void nasal_vm::opr_meq() void nasal_vm::opr_meq()
{ {
*addr_stack.top()=*stack_top; addr_stack.top()[0]=stack_top[0];
addr_stack.pop(); addr_stack.pop();
return; return;
} }
void nasal_vm::opr_eq() void nasal_vm::opr_eq()
{ {
nasal_val* val2=*stack_top--; nasal_val* val2=stack_top[0];
nasal_val* val1=*stack_top; nasal_val* val1=(--stack_top)[0];
int a_type=val1->type; int a_type=val1->type;
int b_type=val2->type; int b_type=val2->type;
if(a_type==vm_nil && b_type==vm_nil) if(a_type==vm_nil && b_type==vm_nil)
*stack_top=gc.one_addr; stack_top[0]=gc.one_addr;
else if(a_type==vm_str && b_type==vm_str) else if(a_type==vm_str && b_type==vm_str)
*stack_top=(*val1->ptr.str==*val2->ptr.str)?gc.one_addr:gc.zero_addr; stack_top[0]=(*val1->ptr.str==*val2->ptr.str)?gc.one_addr:gc.zero_addr;
else if(a_type==vm_num || b_type==vm_num) else if(a_type==vm_num || b_type==vm_num)
*stack_top=(val1->to_number()==val2->to_number())?gc.one_addr:gc.zero_addr; stack_top[0]=(val1->to_number()==val2->to_number())?gc.one_addr:gc.zero_addr;
else else
*stack_top=(val1==val2)?gc.one_addr:gc.zero_addr; stack_top[0]=(val1==val2)?gc.one_addr:gc.zero_addr;
return; return;
} }
void nasal_vm::opr_neq() void nasal_vm::opr_neq()
{ {
nasal_val* val2=*stack_top--; nasal_val* val2=stack_top[0];
nasal_val* val1=*stack_top; nasal_val* val1=(--stack_top)[0];
int a_type=val1->type; int a_type=val1->type;
int b_type=val2->type; int b_type=val2->type;
if(a_type==vm_nil && b_type==vm_nil) if(a_type==vm_nil && b_type==vm_nil)
*stack_top=gc.zero_addr; stack_top[0]=gc.zero_addr;
else if(a_type==vm_str && b_type==vm_str) else if(a_type==vm_str && b_type==vm_str)
*stack_top=(*val1->ptr.str!=*val2->ptr.str)?gc.one_addr:gc.zero_addr; stack_top[0]=(*val1->ptr.str!=*val2->ptr.str)?gc.one_addr:gc.zero_addr;
else if(a_type==vm_num || b_type==vm_num) else if(a_type==vm_num || b_type==vm_num)
*stack_top=(val1->to_number()!=val2->to_number())?gc.one_addr:gc.zero_addr; stack_top[0]=(val1->to_number()!=val2->to_number())?gc.one_addr:gc.zero_addr;
else else
*stack_top=(val1!=val2)?gc.one_addr:gc.zero_addr; stack_top[0]=(val1!=val2)?gc.one_addr:gc.zero_addr;
return; return;
} }
void nasal_vm::opr_less() void nasal_vm::opr_less()
{ {
nasal_val* val2=*stack_top--; nasal_val* val2=stack_top[0];
nasal_val* val1=*stack_top; nasal_val* val1=(--stack_top)[0];
if(val1->type==vm_str && val2->type==vm_str) if(val1->type==vm_str && val2->type==vm_str)
*stack_top=(*val1->ptr.str<*val2->ptr.str)?gc.one_addr:gc.zero_addr; stack_top[0]=(*val1->ptr.str<*val2->ptr.str)?gc.one_addr:gc.zero_addr;
else else
*stack_top=(val1->to_number()<val2->to_number())?gc.one_addr:gc.zero_addr; stack_top[0]=(val1->to_number()<val2->to_number())?gc.one_addr:gc.zero_addr;
return; return;
} }
void nasal_vm::opr_leq() void nasal_vm::opr_leq()
{ {
nasal_val* val2=*stack_top--; nasal_val* val2=stack_top[0];
nasal_val* val1=*stack_top; nasal_val* val1=(--stack_top)[0];
if(val1->type==vm_str && val2->type==vm_str) if(val1->type==vm_str && val2->type==vm_str)
*stack_top=(*val1->ptr.str<=*val2->ptr.str)?gc.one_addr:gc.zero_addr; stack_top[0]=(*val1->ptr.str<=*val2->ptr.str)?gc.one_addr:gc.zero_addr;
else else
*stack_top=(val1->to_number()<=val2->to_number())?gc.one_addr:gc.zero_addr; stack_top[0]=(val1->to_number()<=val2->to_number())?gc.one_addr:gc.zero_addr;
return; return;
} }
void nasal_vm::opr_grt() void nasal_vm::opr_grt()
{ {
nasal_val* val2=*stack_top--; nasal_val* val2=stack_top[0];
nasal_val* val1=*stack_top; nasal_val* val1=(--stack_top)[0];
if(val1->type==vm_str && val2->type==vm_str) if(val1->type==vm_str && val2->type==vm_str)
*stack_top=(*val1->ptr.str>*val2->ptr.str)?gc.one_addr:gc.zero_addr; stack_top[0]=(*val1->ptr.str>*val2->ptr.str)?gc.one_addr:gc.zero_addr;
else else
*stack_top=(val1->to_number()>val2->to_number())?gc.one_addr:gc.zero_addr; stack_top[0]=(val1->to_number()>val2->to_number())?gc.one_addr:gc.zero_addr;
return; return;
} }
void nasal_vm::opr_geq() void nasal_vm::opr_geq()
{ {
nasal_val* val2=*stack_top--; nasal_val* val2=stack_top[0];
nasal_val* val1=*stack_top; nasal_val* val1=(--stack_top)[0];
if(val1->type==vm_str && val2->type==vm_str) if(val1->type==vm_str && val2->type==vm_str)
*stack_top=(*val1->ptr.str>=*val2->ptr.str)?gc.one_addr:gc.zero_addr; stack_top[0]=(*val1->ptr.str>=*val2->ptr.str)?gc.one_addr:gc.zero_addr;
else else
*stack_top=(val1->to_number()>=val2->to_number())?gc.one_addr:gc.zero_addr; stack_top[0]=(val1->to_number()>=val2->to_number())?gc.one_addr:gc.zero_addr;
return; return;
} }
void nasal_vm::opr_pop() void nasal_vm::opr_pop()
@ -470,13 +444,13 @@ void nasal_vm::opr_jmp()
} }
void nasal_vm::opr_jt() void nasal_vm::opr_jt()
{ {
if(condition(*stack_top)) if(condition(stack_top[0]))
pc=exec_code[pc].num-1; pc=exec_code[pc].num-1;
return; return;
} }
void nasal_vm::opr_jf() void nasal_vm::opr_jf()
{ {
if(!condition(*stack_top)) if(!condition(stack_top[0]))
pc=exec_code[pc].num-1; pc=exec_code[pc].num-1;
--stack_top; --stack_top;
return; return;
@ -484,7 +458,7 @@ void nasal_vm::opr_jf()
void nasal_vm::opr_counter() void nasal_vm::opr_counter()
{ {
counter.push(-1); counter.push(-1);
if((*stack_top)->type!=vm_vec) if(stack_top[0]->type!=vm_vec)
die("cnt: must use vector in forindex/foreach"); die("cnt: must use vector in forindex/foreach");
return; return;
} }
@ -495,36 +469,35 @@ void nasal_vm::opr_cntpop()
} }
void nasal_vm::opr_findex() void nasal_vm::opr_findex()
{ {
if(++counter.top()>=(*stack_top)->ptr.vec->elems.size()) if(++counter.top()>=stack_top[0]->ptr.vec->elems.size())
{ {
pc=exec_code[pc].num-1; pc=exec_code[pc].num-1;
return; return;
} }
nasal_val* res=gc.gc_alloc(vm_num); nasal_val* res=gc.gc_alloc(vm_num);
res->ptr.num=counter.top(); res->ptr.num=counter.top();
*(++stack_top)=res; (++stack_top)[0]=res;
return; return;
} }
void nasal_vm::opr_feach() void nasal_vm::opr_feach()
{ {
std::vector<nasal_val*>& ref=(*stack_top)->ptr.vec->elems; std::vector<nasal_val*>& ref=stack_top[0]->ptr.vec->elems;
if(++counter.top()>=ref.size()) if(++counter.top()>=ref.size())
{ {
pc=exec_code[pc].num-1; pc=exec_code[pc].num-1;
return; return;
} }
nasal_val* res=ref[counter.top()]; (++stack_top)[0]=ref[counter.top()];
*(++stack_top)=res;
return; return;
} }
void nasal_vm::opr_callg() void nasal_vm::opr_callg()
{ {
*(++stack_top)=gc.global[exec_code[pc].num]; (++stack_top)[0]=gc.global[exec_code[pc].num];
return; return;
} }
void nasal_vm::opr_calll() void nasal_vm::opr_calll()
{ {
*(++stack_top)=gc.local.back()[exec_code[pc].num]; (++stack_top)[0]=gc.local.back()[exec_code[pc].num];
return; return;
} }
void nasal_vm::opr_callv() void nasal_vm::opr_callv()
@ -537,7 +510,7 @@ void nasal_vm::opr_callv()
nasal_val* res=vec_addr->ptr.vec->get_val(val->to_number()); nasal_val* res=vec_addr->ptr.vec->get_val(val->to_number());
if(!res) if(!res)
die("callv: index out of range"); die("callv: index out of range");
*stack_top=res; stack_top[0]=res;
} }
else if(type==vm_hash) else if(type==vm_hash)
{ {
@ -554,7 +527,7 @@ void nasal_vm::opr_callv()
} }
if(res->type==vm_func) if(res->type==vm_func)
res->ptr.func->closure[0]=val;// me res->ptr.func->closure[0]=val;// me
*stack_top=res; stack_top[0]=res;
} }
else if(type==vm_str) else if(type==vm_str)
{ {
@ -568,7 +541,7 @@ void nasal_vm::opr_callv()
} }
nasal_val* res=gc.gc_alloc(vm_num); nasal_val* res=gc.gc_alloc(vm_num);
res->ptr.num=(str[num>=0? num:num+str_size]); res->ptr.num=(str[num>=0? num:num+str_size]);
*stack_top=res; stack_top[0]=res;
} }
else else
die("callv: must call a vector/hash/string"); die("callv: must call a vector/hash/string");
@ -576,7 +549,7 @@ void nasal_vm::opr_callv()
} }
void nasal_vm::opr_callvi() void nasal_vm::opr_callvi()
{ {
nasal_val* val=*stack_top; nasal_val* val=stack_top[0];
if(val->type!=vm_vec) if(val->type!=vm_vec)
{ {
die("callvi: multi-definition/multi-assignment must use a vector"); die("callvi: multi-definition/multi-assignment must use a vector");
@ -586,12 +559,12 @@ void nasal_vm::opr_callvi()
nasal_val* res=val->ptr.vec->get_val(exec_code[pc].num); nasal_val* res=val->ptr.vec->get_val(exec_code[pc].num);
if(!res) if(!res)
die("callvi: index out of range"); die("callvi: index out of range");
*(++stack_top)=res; (++stack_top)[0]=res;
return; return;
} }
void nasal_vm::opr_callh() void nasal_vm::opr_callh()
{ {
nasal_val* val=*stack_top; nasal_val* val=stack_top[0];
if(val->type!=vm_hash) if(val->type!=vm_hash)
{ {
die("callh: must call a hash"); die("callh: must call a hash");
@ -605,7 +578,7 @@ void nasal_vm::opr_callh()
} }
if(res->type==vm_func) if(res->type==vm_func)
res->ptr.func->closure[0]=val;// me res->ptr.func->closure[0]=val;// me
*stack_top=res; stack_top[0]=res;
return; return;
} }
void nasal_vm::opr_callfv() void nasal_vm::opr_callfv()
@ -657,7 +630,7 @@ void nasal_vm::opr_callfh()
{ {
// get parameter list and function value // get parameter list and function value
std::unordered_map<std::string,nasal_val*>& ref_hash=(*stack_top)->ptr.hash->elems; std::unordered_map<std::string,nasal_val*>& ref_hash=(*stack_top)->ptr.hash->elems;
nasal_val* func_addr=*(stack_top-1); nasal_val* func_addr=stack_top[-1];
if(func_addr->type!=vm_func) if(func_addr->type!=vm_func)
{ {
die("callfh: must call a function"); die("callfh: must call a function");
@ -698,20 +671,20 @@ void nasal_vm::opr_callfh()
void nasal_vm::opr_callb() void nasal_vm::opr_callb()
{ {
nasal_val* res=(*builtin_func[exec_code[pc].num].func)(gc.local.back(),gc); nasal_val* res=(*builtin_func[exec_code[pc].num].func)(gc.local.back(),gc);
*(++stack_top)=res; (++stack_top)[0]=res;
loop_mark=res; loop_mark=res;
return; return;
} }
void nasal_vm::opr_slcbegin() void nasal_vm::opr_slcbegin()
{ {
gc.slice_stack.push_back(gc.gc_alloc(vm_vec)); gc.slice_stack.push_back(gc.gc_alloc(vm_vec));
if((*stack_top)->type!=vm_vec) if(stack_top[0]->type!=vm_vec)
die("slcbegin: must slice a vector"); die("slcbegin: must slice a vector");
return; return;
} }
void nasal_vm::opr_slcend() void nasal_vm::opr_slcend()
{ {
*stack_top=gc.slice_stack.back(); stack_top[0]=gc.slice_stack.back();
gc.slice_stack.pop_back(); gc.slice_stack.pop_back();
return; return;
} }
@ -725,7 +698,7 @@ void nasal_vm::opr_slc()
case vm_str:num=(int)str2num(val->ptr.str->c_str());break; case vm_str:num=(int)str2num(val->ptr.str->c_str());break;
default:die("slc: error value type");break; default:die("slc: error value type");break;
} }
nasal_val* res=(*stack_top)->ptr.vec->get_val(num); nasal_val* res=stack_top[0]->ptr.vec->get_val(num);
if(!res) if(!res)
die("slc: index out of range"); die("slc: index out of range");
gc.slice_stack.back()->ptr.vec->elems.push_back(res); gc.slice_stack.back()->ptr.vec->elems.push_back(res);
@ -735,7 +708,7 @@ void nasal_vm::opr_slc2()
{ {
nasal_val* val2=*stack_top--; nasal_val* val2=*stack_top--;
nasal_val* val1=*stack_top--; nasal_val* val1=*stack_top--;
std::vector<nasal_val*>& ref=(*stack_top)->ptr.vec->elems; std::vector<nasal_val*>& ref=stack_top[0]->ptr.vec->elems;
std::vector<nasal_val*>& aim=gc.slice_stack.back()->ptr.vec->elems; std::vector<nasal_val*>& aim=gc.slice_stack.back()->ptr.vec->elems;
int type1=val1->type,type2=val2->type; int type1=val1->type,type2=val2->type;
@ -848,9 +821,9 @@ void nasal_vm::opr_ret()
gc.local.pop_back(); gc.local.pop_back();
pc=ret.top(); pc=ret.top();
ret.pop(); ret.pop();
nasal_val* ret_val=*stack_top--; nasal_val* ret_val=stack_top[0];
(*stack_top)->ptr.func->closure[0]=gc.nil_addr;// set me to nil (--stack_top)[0]->ptr.func->closure[0]=gc.nil_addr;// set me to nil
*stack_top=ret_val; stack_top[0]=ret_val;
return; return;
} }
void nasal_vm::run() void nasal_vm::run()