prepare for debugger

This commit is contained in:
ValKmjolnir 2021-07-16 02:17:53 +08:00
parent 8b8e72c879
commit 9da029b8fe
3 changed files with 190 additions and 183 deletions

View File

@ -5,7 +5,6 @@ void help_interact()
std::cout std::cout
<<">> [ ] input a file name to execute. \n" <<">> [ ] input a file name to execute. \n"
<<">> [help ] show help. \n" <<">> [help ] show help. \n"
<<">> [clear] clear the screen. \n"
<<">> [lex ] view tokens. \n" <<">> [lex ] view tokens. \n"
<<">> [ast ] view abstract syntax tree. \n" <<">> [ast ] view abstract syntax tree. \n"
<<">> [code ] view byte code. \n" <<">> [code ] view byte code. \n"
@ -20,10 +19,10 @@ void help_cmd()
#ifdef _WIN32 #ifdef _WIN32
<<"use command \'chcp 65001\' if want to use unicode.\n" <<"use command \'chcp 65001\' if want to use unicode.\n"
#endif #endif
<<"nasal | use interactive interpreter.\n" <<"nasal | use interactive interpreter.\n"
<<"nasal -h -help | get help.\n" <<"nasal -h, --help | get help.\n"
<<"nasal -v -version | get version of nasal interpreter.\n" <<"nasal -v, --version | get version of nasal interpreter.\n"
<<"nasal filename | execute script file.\n"; <<"nasal filename | execute script file.\n";
return; return;
} }
void info() void info()
@ -125,14 +124,6 @@ void interact()
std::cin>>command; std::cin>>command;
if(command=="help") if(command=="help")
help_interact(); help_interact();
else if(command=="clear")
{
#ifdef _WIN32
system("cls");
#else
int rs=system("clear");
#endif
}
else if(command=="logo") else if(command=="logo")
logo(); logo();
else if(command=="exit") else if(command=="exit")
@ -148,9 +139,9 @@ int main(int argc,const char* argv[])
std::string command,file="null"; std::string command,file="null";
if(argc==1) if(argc==1)
interact(); interact();
else if(argc==2 && (!strcmp(argv[1],"-v") || !strcmp(argv[1],"-version"))) else if(argc==2 && (!strcmp(argv[1],"-v") || !strcmp(argv[1],"--version")))
logo(); logo();
else if(argc==2 && (!strcmp(argv[1],"-h") || !strcmp(argv[1],"-help"))) else if(argc==2 && (!strcmp(argv[1],"-h") || !strcmp(argv[1],"--help")))
help_cmd(); help_cmd();
else if(argc==2 && argv[1][0]!='-') else if(argc==2 && argv[1][0]!='-')
{ {

View File

@ -170,16 +170,19 @@ struct opcode
{ {
uint8_t op; uint8_t op;
uint32_t num; uint32_t num;
opcode(uint8_t _op=op_nop,uint32_t _num=0) uint32_t line;
opcode(uint8_t _op=op_nop,uint32_t _num=0,uint32_t _line=0)
{ {
op=_op; op=_op;
num=_num; num=_num;
line=_line;
return; return;
} }
opcode& operator=(const opcode& tmp) opcode& operator=(const opcode& tmp)
{ {
op=tmp.op; op=tmp.op;
num=tmp.num; num=tmp.num;
line=tmp.line;
return *this; return *this;
} }
}; };
@ -206,7 +209,7 @@ private:
void add_sym(std::string&); void add_sym(std::string&);
int local_find(std::string&); int local_find(std::string&);
int global_find(std::string&); int global_find(std::string&);
void gen(uint8_t,uint32_t); void gen(uint8_t,uint32_t,uint32_t);
void num_gen(nasal_ast&); void num_gen(nasal_ast&);
void str_gen(nasal_ast&); void str_gen(nasal_ast&);
void vec_gen(nasal_ast&); void vec_gen(nasal_ast&);
@ -311,21 +314,21 @@ int nasal_codegen::global_find(std::string& name)
return -1; return -1;
} }
void nasal_codegen::gen(uint8_t op,uint32_t num) void nasal_codegen::gen(uint8_t op,uint32_t num,uint32_t line)
{ {
exec_code.push_back({op,num}); exec_code.push_back({op,num,line});
return; return;
} }
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==0)gen(op_pzero,0); if(num==0)gen(op_pzero,0,ast.get_line());
else if(num==1)gen(op_pone,0); else if(num==1)gen(op_pone,0,ast.get_line());
else else
{ {
regist_number(num); regist_number(num);
gen(op_pnum,number_table[num]); gen(op_pnum,number_table[num],ast.get_line());
} }
return; return;
} }
@ -334,7 +337,7 @@ void nasal_codegen::str_gen(nasal_ast& ast)
{ {
std::string& str=ast.get_str(); std::string& str=ast.get_str();
regist_string(str); regist_string(str);
gen(op_pstr,string_table[str]); gen(op_pstr,string_table[str],ast.get_line());
return; return;
} }
@ -342,19 +345,19 @@ void nasal_codegen::vec_gen(nasal_ast& ast)
{ {
for(auto& node:ast.get_children()) for(auto& node:ast.get_children())
calc_gen(node); calc_gen(node);
gen(op_newv,ast.get_children().size()); gen(op_newv,ast.get_children().size(),ast.get_line());
return; return;
} }
void nasal_codegen::hash_gen(nasal_ast& ast) void nasal_codegen::hash_gen(nasal_ast& ast)
{ {
gen(op_newh,0); gen(op_newh,0,ast.get_line());
for(auto& node:ast.get_children()) for(auto& node:ast.get_children())
{ {
calc_gen(node.get_children()[1]); calc_gen(node.get_children()[1]);
std::string& str=node.get_children()[0].get_str(); std::string& str=node.get_children()[0].get_str();
regist_string(str); regist_string(str);
gen(op_happ,string_table[str]); gen(op_happ,string_table[str],node.get_line());
} }
return; return;
} }
@ -362,9 +365,9 @@ void nasal_codegen::hash_gen(nasal_ast& ast)
void nasal_codegen::func_gen(nasal_ast& ast) void nasal_codegen::func_gen(nasal_ast& ast)
{ {
int newfunc_label=exec_code.size(); int newfunc_label=exec_code.size();
gen(op_newf,0); gen(op_newf,0,ast.get_line());
int local_label=exec_code.size(); int local_label=exec_code.size();
gen(op_intl,0); gen(op_intl,0,ast.get_line());
local.push_back(std::vector<std::string>()); local.push_back(std::vector<std::string>());
// add special keyword 'me' into symbol table // add special keyword 'me' into symbol table
@ -378,7 +381,7 @@ void nasal_codegen::func_gen(nasal_ast& ast)
add_sym(me); add_sym(me);
} }
gen(op_offset,0); gen(op_offset,0,ast.get_line());
for(auto& i:local) for(auto& i:local)
exec_code.back().num+=i.size(); exec_code.back().num+=i.size();
// generate parameter list // generate parameter list
@ -389,7 +392,7 @@ void nasal_codegen::func_gen(nasal_ast& ast)
std::string& str=tmp.get_str(); std::string& str=tmp.get_str();
regist_string(str); regist_string(str);
add_sym(str); add_sym(str);
gen(op_para,string_table[str]); gen(op_para,string_table[str],tmp.get_line());
} }
else if(tmp.get_type()==ast_default_arg) else if(tmp.get_type()==ast_default_arg)
{ {
@ -397,19 +400,19 @@ void nasal_codegen::func_gen(nasal_ast& ast)
std::string& str=tmp.get_str(); std::string& str=tmp.get_str();
regist_string(str); regist_string(str);
add_sym(str); add_sym(str);
gen(op_defpara,string_table[str]); gen(op_defpara,string_table[str],tmp.get_line());
} }
else if(tmp.get_type()==ast_dynamic_id) else if(tmp.get_type()==ast_dynamic_id)
{ {
std::string& str=tmp.get_str(); std::string& str=tmp.get_str();
regist_string(str); regist_string(str);
add_sym(str); add_sym(str);
gen(op_dynpara,string_table[str]); gen(op_dynpara,string_table[str],tmp.get_line());
} }
} }
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,0);
nasal_ast& block=ast.get_children()[1]; nasal_ast& block=ast.get_children()[1];
block_gen(block); block_gen(block);
@ -419,8 +422,8 @@ void nasal_codegen::func_gen(nasal_ast& ast)
if(!block.get_children().size() || block.get_children().back().get_type()!=ast_ret) if(!block.get_children().size() || block.get_children().back().get_type()!=ast_ret)
{ {
gen(op_pnil,0); gen(op_pnil,0,block.get_line());
gen(op_ret,0); gen(op_ret,0,block.get_line());
} }
exec_code[jmp_ptr].num=exec_code.size(); exec_code[jmp_ptr].num=exec_code.size();
return; return;
@ -451,7 +454,7 @@ void nasal_codegen::call_id(nasal_ast& ast)
for(int i=0;builtin_func[i].name;++i) for(int i=0;builtin_func[i].name;++i)
if(builtin_func[i].name==str) if(builtin_func[i].name==str)
{ {
gen(op_callb,i); gen(op_callb,i,ast.get_line());
if(local.empty()) if(local.empty())
die("builtin functions work in a local scope.",ast.get_line()); die("builtin functions work in a local scope.",ast.get_line());
return; return;
@ -459,13 +462,13 @@ void nasal_codegen::call_id(nasal_ast& ast)
int index=local_find(str); int index=local_find(str);
if(index>=0) if(index>=0)
{ {
gen(op_calll,index); gen(op_calll,index,ast.get_line());
return; return;
} }
index=global_find(str); index=global_find(str);
if(index>=0) if(index>=0)
{ {
gen(op_callg,index); gen(op_callg,index,ast.get_line());
return; return;
} }
die("undefined symbol \""+str+"\".",ast.get_line()); die("undefined symbol \""+str+"\".",ast.get_line());
@ -476,7 +479,7 @@ void nasal_codegen::call_hash(nasal_ast& ast)
{ {
std::string& str=ast.get_str(); std::string& str=ast.get_str();
regist_string(str); regist_string(str);
gen(op_callh,string_table[str]); gen(op_callh,string_table[str],ast.get_line());
return; return;
} }
@ -486,42 +489,42 @@ void nasal_codegen::call_vec(nasal_ast& ast)
if(ast.get_children().size()==1 && ast.get_children()[0].get_type()!=ast_subvec) if(ast.get_children().size()==1 && ast.get_children()[0].get_type()!=ast_subvec)
{ {
calc_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
gen(op_callv,0); gen(op_callv,0,ast.get_children()[0].get_line());
return; return;
} }
gen(op_slcbegin,0); gen(op_slcbegin,0,ast.get_line());
for(auto& tmp:ast.get_children()) for(auto& tmp:ast.get_children())
{ {
if(tmp.get_type()!=ast_subvec) if(tmp.get_type()!=ast_subvec)
{ {
calc_gen(tmp); calc_gen(tmp);
gen(op_slc,0); gen(op_slc,0,tmp.get_line());
} }
else else
{ {
calc_gen(tmp.get_children()[0]); calc_gen(tmp.get_children()[0]);
calc_gen(tmp.get_children()[1]); calc_gen(tmp.get_children()[1]);
gen(op_slc2,0); gen(op_slc2,0,tmp.get_line());
} }
} }
gen(op_slcend,0); gen(op_slcend,0,ast.get_line());
return; return;
} }
void nasal_codegen::call_func(nasal_ast& ast) void nasal_codegen::call_func(nasal_ast& ast)
{ {
if(!ast.get_children().size()) if(!ast.get_children().size())
gen(op_callfv,0); gen(op_callfv,0,ast.get_line());
else if(ast.get_children()[0].get_type()==ast_hashmember) else if(ast.get_children()[0].get_type()==ast_hashmember)
{ {
hash_gen(ast); hash_gen(ast);
gen(op_callfh,0); gen(op_callfh,0,ast.get_line());
} }
else else
{ {
for(auto& node:ast.get_children()) for(auto& node:ast.get_children())
calc_gen(node); calc_gen(node);
gen(op_callfv,ast.get_children().size()); gen(op_callfv,ast.get_children().size(),ast.get_line());
} }
return; return;
} }
@ -564,13 +567,13 @@ void nasal_codegen::mcall_id(nasal_ast& ast)
int index=local_find(str); int index=local_find(str);
if(index>=0) if(index>=0)
{ {
gen(op_mcalll,index); gen(op_mcalll,index,ast.get_line());
return; return;
} }
index=global_find(str); index=global_find(str);
if(index>=0) if(index>=0)
{ {
gen(op_mcallg,index); gen(op_mcallg,index,ast.get_line());
return; return;
} }
die("undefined symbol \""+str+"\".",ast.get_line()); die("undefined symbol \""+str+"\".",ast.get_line());
@ -580,7 +583,7 @@ void nasal_codegen::mcall_id(nasal_ast& ast)
void nasal_codegen::mcall_vec(nasal_ast& ast) void nasal_codegen::mcall_vec(nasal_ast& ast)
{ {
calc_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
gen(op_mcallv,0); gen(op_mcallv,0,ast.get_line());
return; return;
} }
@ -588,7 +591,7 @@ void nasal_codegen::mcall_hash(nasal_ast& ast)
{ {
std::string& str=ast.get_str(); std::string& str=ast.get_str();
regist_string(str); regist_string(str);
gen(op_mcallh,string_table[str]); gen(op_mcallh,string_table[str],ast.get_line());
return; return;
} }
@ -597,7 +600,7 @@ void nasal_codegen::single_def(nasal_ast& ast)
std::string& str=ast.get_children()[0].get_str(); std::string& str=ast.get_children()[0].get_str();
add_sym(str); add_sym(str);
calc_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
local.empty()?gen(op_loadg,global_find(str)):gen(op_loadl,local_find(str)); local.empty()?gen(op_loadg,global_find(str),ast.get_line()):gen(op_loadl,local_find(str),ast.get_line());
return; return;
} }
void nasal_codegen::multi_def(nasal_ast& ast) void nasal_codegen::multi_def(nasal_ast& ast)
@ -612,7 +615,7 @@ void nasal_codegen::multi_def(nasal_ast& ast)
calc_gen(vals[i]); calc_gen(vals[i]);
std::string& str=ids[i].get_str(); std::string& str=ids[i].get_str();
add_sym(str); add_sym(str);
local.empty()?gen(op_loadg,global_find(str)):gen(op_loadl,local_find(str)); local.empty()?gen(op_loadg,global_find(str),ids[i].get_line()):gen(op_loadl,local_find(str),ids[i].get_line());
} }
} }
else else
@ -620,12 +623,12 @@ void nasal_codegen::multi_def(nasal_ast& ast)
calc_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
for(int i=0;i<size;++i) for(int i=0;i<size;++i)
{ {
gen(op_callvi,i); gen(op_callvi,i,ast.get_children()[1].get_line());
std::string& str=ids[i].get_str(); std::string& str=ids[i].get_str();
add_sym(str); add_sym(str);
local.empty()?gen(op_loadg,global_find(str)):gen(op_loadl,local_find(str)); local.empty()?gen(op_loadg,global_find(str),ids[i].get_line()):gen(op_loadl,local_find(str),ids[i].get_line());
} }
gen(op_pop,0); gen(op_pop,0,ast.get_line());
} }
return; return;
} }
@ -657,8 +660,8 @@ void nasal_codegen::multi_assign_gen(nasal_ast& ast)
exec_code.back().op=op_loadg; exec_code.back().op=op_loadg;
else else
{ {
gen(op_meq,0); gen(op_meq,0,ast.get_children()[0].get_children()[i].get_line());
gen(op_pop,0); gen(op_pop,0,ast.get_children()[0].get_children()[i].get_line());
} }
} }
} }
@ -667,7 +670,7 @@ void nasal_codegen::multi_assign_gen(nasal_ast& ast)
calc_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
for(int i=0;i<size;++i) for(int i=0;i<size;++i)
{ {
gen(op_callvi,i); gen(op_callvi,i,ast.get_children()[1].get_line());
// multi assign user loadl and loadg to avoid meq's stack-- // multi assign user loadl and loadg to avoid meq's stack--
// and this operation changes local and global value directly // and this operation changes local and global value directly
mcall(ast.get_children()[0].get_children()[i]); mcall(ast.get_children()[0].get_children()[i]);
@ -677,11 +680,11 @@ void nasal_codegen::multi_assign_gen(nasal_ast& ast)
exec_code.back().op=op_loadg; exec_code.back().op=op_loadg;
else else
{ {
gen(op_meq,0); gen(op_meq,0,ast.get_children()[0].get_children()[i].get_line());
gen(op_pop,0); gen(op_pop,0,ast.get_children()[0].get_children()[i].get_line());
} }
} }
gen(op_pop,0); gen(op_pop,0,ast.get_line());
} }
return; return;
} }
@ -695,12 +698,12 @@ void nasal_codegen::conditional_gen(nasal_ast& ast)
{ {
calc_gen(tmp.get_children()[0]); calc_gen(tmp.get_children()[0]);
int ptr=exec_code.size(); int ptr=exec_code.size();
gen(op_jf,0); gen(op_jf,0,0);
block_gen(tmp.get_children()[1]); block_gen(tmp.get_children()[1]);
jmp_label.push_back(exec_code.size()); jmp_label.push_back(exec_code.size());
// without 'else' the last condition doesn't need to jmp // without 'else' the last condition doesn't need to jmp
if(&tmp!=&ast.get_children().back()) if(&tmp!=&ast.get_children().back())
gen(op_jmp,0); gen(op_jmp,0,0);
exec_code[ptr].num=exec_code.size(); exec_code[ptr].num=exec_code.size();
} }
else else
@ -744,10 +747,10 @@ void nasal_codegen::while_gen(nasal_ast& ast)
int loop_ptr=exec_code.size(); int loop_ptr=exec_code.size();
calc_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
int condition_ptr=exec_code.size(); int condition_ptr=exec_code.size();
gen(op_jf,0); gen(op_jf,0,0);
block_gen(ast.get_children()[1]); block_gen(ast.get_children()[1]);
gen(op_jmp,loop_ptr); gen(op_jmp,loop_ptr,0);
exec_code[condition_ptr].num=exec_code.size(); exec_code[condition_ptr].num=exec_code.size();
load_continue_break(exec_code.size()-1,exec_code.size()); load_continue_break(exec_code.size()-1,exec_code.size());
return; return;
@ -786,15 +789,18 @@ void nasal_codegen::for_gen(nasal_ast& ast)
case ast_less: case ast_less:
case ast_geq: case ast_geq:
case ast_grt: case ast_grt:
case ast_trino:calc_gen(ast.get_children()[0]);gen(op_pop,0);break; case ast_trino:
calc_gen(ast.get_children()[0]);
gen(op_pop,0,0);
break;
} }
int jmp_place=exec_code.size(); int jmp_place=exec_code.size();
if(ast.get_children()[1].get_type()==ast_null) if(ast.get_children()[1].get_type()==ast_null)
gen(op_pone,0); gen(op_pone,0,ast.get_children()[1].get_line());
else else
calc_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
int label_exit=exec_code.size(); int label_exit=exec_code.size();
gen(op_jf,0); gen(op_jf,0,0);
block_gen(ast.get_children()[3]); block_gen(ast.get_children()[3]);
int continue_place=exec_code.size(); int continue_place=exec_code.size();
@ -810,9 +816,12 @@ void nasal_codegen::for_gen(nasal_ast& ast)
case ast_neg:case ast_not: case ast_neg:case ast_not:
case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link: case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link:
case ast_cmpeq:case ast_neq:case ast_leq:case ast_less:case ast_geq:case ast_grt: case ast_cmpeq:case ast_neq:case ast_leq:case ast_less:case ast_geq:case ast_grt:
case ast_trino:calc_gen(ast.get_children()[2]);gen(op_pop,0);break; case ast_trino:
calc_gen(ast.get_children()[2]);
gen(op_pop,0,0);
break;
} }
gen(op_jmp,jmp_place); gen(op_jmp,jmp_place,0);
exec_code[label_exit].num=exec_code.size(); exec_code[label_exit].num=exec_code.size();
load_continue_break(continue_place,exec_code.size()); load_continue_break(continue_place,exec_code.size());
@ -821,55 +830,59 @@ void nasal_codegen::for_gen(nasal_ast& ast)
void nasal_codegen::forindex_gen(nasal_ast& ast) void nasal_codegen::forindex_gen(nasal_ast& ast)
{ {
calc_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
gen(op_cnt,0); gen(op_cnt,0,ast.get_children()[1].get_line());
int ptr=exec_code.size(); int ptr=exec_code.size();
gen(op_findex,0); gen(op_findex,0,ast.get_line());
if(ast.get_children()[0].get_type()==ast_new_iter) if(ast.get_children()[0].get_type()==ast_new_iter)
{ {
std::string& str=ast.get_children()[0].get_children()[0].get_str(); std::string& str=ast.get_children()[0].get_children()[0].get_str();
add_sym(str); add_sym(str);
local.empty()?gen(op_loadg,global_find(str)):gen(op_loadl,local_find(str)); local.empty()?
gen(op_loadg,global_find(str),ast.get_children()[0].get_children()[0].get_line())
:gen(op_loadl,local_find(str),ast.get_children()[0].get_children()[0].get_line());
} }
else else
{ {
mcall(ast.get_children()[0]); mcall(ast.get_children()[0]);
gen(op_meq,0); gen(op_meq,0,ast.get_children()[0].get_line());
gen(op_pop,0); gen(op_pop,0,0);
} }
block_gen(ast.get_children()[2]); block_gen(ast.get_children()[2]);
gen(op_jmp,ptr); gen(op_jmp,ptr,0);
exec_code[ptr].num=exec_code.size(); exec_code[ptr].num=exec_code.size();
load_continue_break(exec_code.size()-1,exec_code.size()); load_continue_break(exec_code.size()-1,exec_code.size());
gen(op_pop,0);// pop vector gen(op_pop,0,0);// pop vector
gen(op_cntpop,0); gen(op_cntpop,0,0);
return; return;
} }
void nasal_codegen::foreach_gen(nasal_ast& ast) void nasal_codegen::foreach_gen(nasal_ast& ast)
{ {
calc_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
gen(op_cnt,0); gen(op_cnt,0,ast.get_line());
int ptr=exec_code.size(); int ptr=exec_code.size();
gen(op_feach,0); gen(op_feach,0,ast.get_line());
if(ast.get_children()[0].get_type()==ast_new_iter) if(ast.get_children()[0].get_type()==ast_new_iter)
{ {
std::string& str=ast.get_children()[0].get_children()[0].get_str(); std::string& str=ast.get_children()[0].get_children()[0].get_str();
add_sym(str); add_sym(str);
local.empty()?gen(op_loadg,global_find(str)):gen(op_loadl,local_find(str)); local.empty()?
gen(op_loadg,global_find(str),ast.get_children()[0].get_children()[0].get_line())
:gen(op_loadl,local_find(str),ast.get_children()[0].get_children()[0].get_line());
} }
else else
{ {
mcall(ast.get_children()[0]); mcall(ast.get_children()[0]);
gen(op_meq,0); gen(op_meq,0,ast.get_children()[0].get_line());
gen(op_pop,0); gen(op_pop,0,0);
} }
block_gen(ast.get_children()[2]); block_gen(ast.get_children()[2]);
gen(op_jmp,ptr); gen(op_jmp,ptr,0);
exec_code[ptr].num=exec_code.size(); exec_code[ptr].num=exec_code.size();
load_continue_break(exec_code.size()-1,exec_code.size()); load_continue_break(exec_code.size()-1,exec_code.size());
gen(op_pop,0);// pop vector gen(op_pop,0,0);// pop vector
gen(op_cntpop,0); gen(op_cntpop,0,0);
return; return;
} }
@ -877,15 +890,15 @@ void nasal_codegen::or_gen(nasal_ast& ast)
{ {
calc_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
int l1=exec_code.size(); int l1=exec_code.size();
gen(op_jt,0); gen(op_jt,0,0);
gen(op_pop,0); gen(op_pop,0,0);
calc_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
int l2=exec_code.size(); int l2=exec_code.size();
gen(op_jt,0); gen(op_jt,0,0);
gen(op_pop,0); gen(op_pop,0,0);
gen(op_pnil,0); gen(op_pnil,0,0);
exec_code[l1].num=exec_code[l2].num=exec_code.size(); exec_code[l1].num=exec_code[l2].num=exec_code.size();
return; return;
@ -894,18 +907,18 @@ void nasal_codegen::or_gen(nasal_ast& ast)
void nasal_codegen::and_gen(nasal_ast& ast) void nasal_codegen::and_gen(nasal_ast& ast)
{ {
calc_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
gen(op_jt,exec_code.size()+2); gen(op_jt,exec_code.size()+2,0);
int lfalse=exec_code.size(); int lfalse=exec_code.size();
gen(op_jmp,0); gen(op_jmp,0,0);
gen(op_pop,0);// jt jumps here gen(op_pop,0,0);// jt jumps here
calc_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
gen(op_jt,exec_code.size()+3); gen(op_jt,exec_code.size()+3,0);
exec_code[lfalse].num=exec_code.size(); exec_code[lfalse].num=exec_code.size();
gen(op_pop,0); gen(op_pop,0,0);
gen(op_pnil,0); gen(op_pnil,0,0);
//jt jumps here //jt jumps here
return; return;
} }
@ -914,10 +927,10 @@ void nasal_codegen::trino_gen(nasal_ast& ast)
{ {
calc_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
int lfalse=exec_code.size(); int lfalse=exec_code.size();
gen(op_jf,0); gen(op_jf,0,0);
calc_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
int lexit=exec_code.size(); int lexit=exec_code.size();
gen(op_jmp,0); gen(op_jmp,0,0);
exec_code[lfalse].num=exec_code.size(); exec_code[lfalse].num=exec_code.size();
calc_gen(ast.get_children()[2]); calc_gen(ast.get_children()[2]);
exec_code[lexit].num=exec_code.size(); exec_code[lexit].num=exec_code.size();
@ -928,7 +941,7 @@ void nasal_codegen::calc_gen(nasal_ast& ast)
{ {
switch(ast.get_type()) switch(ast.get_type())
{ {
case ast_nil: gen(op_pnil,0); break; case ast_nil: gen(op_pnil,0,ast.get_line());break;
case ast_num: num_gen(ast); break; case ast_num: num_gen(ast); break;
case ast_str: str_gen(ast); break; case ast_str: str_gen(ast); break;
case ast_id: call_id(ast); break; case ast_id: call_id(ast); break;
@ -939,7 +952,7 @@ void nasal_codegen::calc_gen(nasal_ast& ast)
case ast_equal: case ast_equal:
calc_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
mcall(ast.get_children()[0]); mcall(ast.get_children()[0]);
gen(op_meq,0); gen(op_meq,0,ast.get_line());
break; break;
// ast_addeq(22)~ast_lnkeq(26) op_addeq(23)~op_lnkeq(27) // ast_addeq(22)~ast_lnkeq(26) op_addeq(23)~op_lnkeq(27)
case ast_addeq:case ast_subeq:case ast_multeq:case ast_diveq: case ast_addeq:case ast_subeq:case ast_multeq:case ast_diveq:
@ -947,11 +960,11 @@ void nasal_codegen::calc_gen(nasal_ast& ast)
calc_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
mcall(ast.get_children()[0]); mcall(ast.get_children()[0]);
if(ast.get_children()[1].get_type()!=ast_num) if(ast.get_children()[1].get_type()!=ast_num)
gen(ast.get_type()-ast_addeq+op_addeq,0); gen(ast.get_type()-ast_addeq+op_addeq,0,ast.get_line());
else else
{ {
regist_number(ast.get_children()[1].get_num()); regist_number(ast.get_children()[1].get_num());
gen(ast.get_type()-ast_addeq+op_addeqc,number_table[ast.get_children()[1].get_num()]); gen(ast.get_type()-ast_addeq+op_addeqc,number_table[ast.get_children()[1].get_num()],ast.get_line());
} }
break; break;
case ast_lnkeq: case ast_lnkeq:
@ -961,9 +974,9 @@ void nasal_codegen::calc_gen(nasal_ast& ast)
regist_string(ast.get_children()[1].get_str()); regist_string(ast.get_children()[1].get_str());
mcall(ast.get_children()[0]); mcall(ast.get_children()[0]);
if(ast.get_children()[1].get_type()!=ast_str) if(ast.get_children()[1].get_type()!=ast_str)
gen(op_lnkeq,0); gen(op_lnkeq,0,ast.get_line());
else else
gen(op_lnkeqc,string_table[ast.get_children()[1].get_str()]); gen(op_lnkeqc,string_table[ast.get_children()[1].get_str()],ast.get_line());
break; break;
case ast_or:or_gen(ast);break; case ast_or:or_gen(ast);break;
case ast_and:and_gen(ast);break; case ast_and:and_gen(ast);break;
@ -973,12 +986,12 @@ void nasal_codegen::calc_gen(nasal_ast& ast)
if(ast.get_children()[1].get_type()!=ast_num) if(ast.get_children()[1].get_type()!=ast_num)
{ {
calc_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
gen(ast.get_type()-ast_add+op_add,0); gen(ast.get_type()-ast_add+op_add,0,ast.get_line());
} }
else else
{ {
regist_number(ast.get_children()[1].get_num()); regist_number(ast.get_children()[1].get_num());
gen(ast.get_type()-ast_add+op_addc,number_table[ast.get_children()[1].get_num()]); gen(ast.get_type()-ast_add+op_addc,number_table[ast.get_children()[1].get_num()],ast.get_line());
} }
break; break;
case ast_link: case ast_link:
@ -986,41 +999,41 @@ void nasal_codegen::calc_gen(nasal_ast& ast)
if(ast.get_children()[1].get_type()!=ast_str) if(ast.get_children()[1].get_type()!=ast_str)
{ {
calc_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
gen(op_lnk,0); gen(op_lnk,0,ast.get_line());
} }
else else
{ {
regist_string(ast.get_children()[1].get_str()); regist_string(ast.get_children()[1].get_str());
gen(op_lnkc,string_table[ast.get_children()[1].get_str()]); gen(op_lnkc,string_table[ast.get_children()[1].get_str()],ast.get_line());
} }
break; break;
// ast_cmpeq(27)~ast_geq(32) op_eq(29)~op_geq(34) // ast_cmpeq(27)~ast_geq(32) op_eq(29)~op_geq(34)
case ast_cmpeq:case ast_neq: case ast_cmpeq:case ast_neq:
calc_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
calc_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
gen(ast.get_type()-ast_cmpeq+op_eq,0); gen(ast.get_type()-ast_cmpeq+op_eq,0,ast.get_line());
break; break;
case ast_less:case ast_leq:case ast_grt:case ast_geq: case ast_less:case ast_leq:case ast_grt:case ast_geq:
calc_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
if(ast.get_children()[1].get_type()!=ast_num) if(ast.get_children()[1].get_type()!=ast_num)
{ {
calc_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
gen(ast.get_type()-ast_less+op_less,0); gen(ast.get_type()-ast_less+op_less,0,ast.get_line());
} }
else else
{ {
regist_number(ast.get_children()[1].get_num()); regist_number(ast.get_children()[1].get_num());
gen(ast.get_type()-ast_less+op_lessc,number_table[ast.get_children()[1].get_num()]); gen(ast.get_type()-ast_less+op_lessc,number_table[ast.get_children()[1].get_num()],ast.get_line());
} }
break; break;
case ast_trino:trino_gen(ast);break; case ast_trino:trino_gen(ast);break;
case ast_neg: case ast_neg:
calc_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
gen(op_usub,0); gen(op_usub,0,ast.get_line());
break; break;
case ast_not: case ast_not:
calc_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
gen(op_unot,0); gen(op_unot,0,ast.get_line());
break; break;
case ast_def: case ast_def:
single_def(ast); single_def(ast);
@ -1041,11 +1054,11 @@ void nasal_codegen::block_gen(nasal_ast& ast)
case ast_conditional:conditional_gen(tmp);break; case ast_conditional:conditional_gen(tmp);break;
case ast_continue: case ast_continue:
continue_ptr.front().push_back(exec_code.size()); continue_ptr.front().push_back(exec_code.size());
gen(op_jmp,0); gen(op_jmp,0,0);
break; break;
case ast_break: case ast_break:
break_ptr.front().push_back(exec_code.size()); break_ptr.front().push_back(exec_code.size());
gen(op_jmp,0); gen(op_jmp,0,0);
break; break;
case ast_while: case ast_while:
case ast_for: case ast_for:
@ -1065,7 +1078,7 @@ void nasal_codegen::block_gen(nasal_ast& ast)
else else
{ {
calc_gen(tmp); calc_gen(tmp);
gen(op_pop,0); gen(op_pop,0,tmp.get_line());
} }
break; break;
case ast_id: case ast_id:
@ -1092,7 +1105,7 @@ void nasal_codegen::block_gen(nasal_ast& ast)
case ast_grt: case ast_grt:
case ast_or: case ast_or:
case ast_and: case ast_and:
case ast_trino:calc_gen(tmp);gen(op_pop,0);break; case ast_trino:calc_gen(tmp);gen(op_pop,0,0);break;
case ast_ret:ret_gen(tmp);break; case ast_ret:ret_gen(tmp);break;
} }
return; return;
@ -1102,19 +1115,19 @@ void nasal_codegen::ret_gen(nasal_ast& ast)
{ {
for(int i=0;i<in_foreach;++i) for(int i=0;i<in_foreach;++i)
{ {
gen(op_pop,0); gen(op_pop,0,0);
gen(op_cntpop,0); gen(op_cntpop,0,0);
} }
for(int i=0;i<in_forindex;++i) for(int i=0;i<in_forindex;++i)
{ {
gen(op_pop,0); gen(op_pop,0,0);
gen(op_cntpop,0); gen(op_cntpop,0,0);
} }
if(ast.get_children().size()) if(ast.get_children().size())
calc_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
else else
gen(op_pnil,0); gen(op_pnil,0,ast.get_line());
gen(op_ret,0); gen(op_ret,0,ast.get_line());
return; return;
} }
@ -1130,7 +1143,7 @@ void nasal_codegen::main_progress(nasal_ast& ast)
global.clear(); global.clear();
local.clear(); local.clear();
gen(op_intg,0); gen(op_intg,0,0);
for(auto& tmp:ast.get_children()) for(auto& tmp:ast.get_children())
{ {
switch(tmp.get_type()) switch(tmp.get_type())
@ -1157,7 +1170,7 @@ void nasal_codegen::main_progress(nasal_ast& ast)
else else
{ {
calc_gen(tmp); calc_gen(tmp);
gen(op_pop,0); gen(op_pop,0,tmp.get_line());
} }
break; break;
case ast_id: case ast_id:
@ -1184,10 +1197,10 @@ void nasal_codegen::main_progress(nasal_ast& ast)
case ast_grt: case ast_grt:
case ast_or: case ast_or:
case ast_and: case ast_and:
case ast_trino:calc_gen(tmp);gen(op_pop,0);break; case ast_trino:calc_gen(tmp);gen(op_pop,0,tmp.get_line());break;
} }
} }
gen(op_nop,0); gen(op_nop,0,0);
exec_code[0].num=global.size(); exec_code[0].num=global.size();
num_res_table.resize(number_table.size()); num_res_table.resize(number_table.size());
str_res_table.resize(string_table.size()); str_res_table.resize(string_table.size());

View File

@ -930,11 +930,14 @@ nop:
return; return;
//#define exec_operand(op,num) {op();++count[num];if(!canary[0])goto *code[++pc];goto nop;} //#define exec_operand(op,num) {op();++count[num];if(!canary[0])goto *code[++pc];goto nop;}
#define exec_operand(op,num) {op();if(!canary[0])goto *code[++pc];goto nop;} #define exec_operand(op,num) {op();if(!canary[0])goto *code[++pc];goto nop;}
intg: exec_operand(opr_intg ,op_intg); //#define exec_opnodie(op,num) {op();++count[num];goto *code[++pc];}
intl: exec_operand(opr_intl ,op_intl); #define exec_opnodie(op,num) {op();goto *code[++pc];}
offset: exec_operand(opr_offset ,op_offset);
loadg: exec_operand(opr_loadg ,op_loadg); intg: exec_opnodie(opr_intg ,op_intg);
loadl: exec_operand(opr_loadl ,op_loadl); intl: exec_opnodie(opr_intl ,op_intl);
offset: exec_opnodie(opr_offset ,op_offset);
loadg: exec_opnodie(opr_loadg ,op_loadg);
loadl: exec_opnodie(opr_loadl ,op_loadl);
pnum: exec_operand(opr_pnum ,op_pnum); pnum: exec_operand(opr_pnum ,op_pnum);
pone: exec_operand(opr_pone ,op_pone); pone: exec_operand(opr_pone ,op_pone);
pzero: exec_operand(opr_pzero ,op_pzero); pzero: exec_operand(opr_pzero ,op_pzero);
@ -943,53 +946,53 @@ pstr: exec_operand(opr_pstr ,op_pstr);
newv: exec_operand(opr_newv ,op_newv); newv: exec_operand(opr_newv ,op_newv);
newh: exec_operand(opr_newh ,op_newh); newh: exec_operand(opr_newh ,op_newh);
newf: exec_operand(opr_newf ,op_newf); newf: exec_operand(opr_newf ,op_newf);
happ: exec_operand(opr_happ ,op_happ); happ: exec_opnodie(opr_happ ,op_happ);
para: exec_operand(opr_para ,op_para); para: exec_opnodie(opr_para ,op_para);
defpara: exec_operand(opr_defpara ,op_defpara); defpara: exec_opnodie(opr_defpara ,op_defpara);
dynpara: exec_operand(opr_dynpara ,op_dynpara); dynpara: exec_opnodie(opr_dynpara ,op_dynpara);
unot: exec_operand(opr_unot ,op_unot); unot: exec_operand(opr_unot ,op_unot);
usub: exec_operand(opr_usub ,op_usub); usub: exec_opnodie(opr_usub ,op_usub);
add: exec_operand(opr_add ,op_add); add: exec_opnodie(opr_add ,op_add);
sub: exec_operand(opr_sub ,op_sub); sub: exec_opnodie(opr_sub ,op_sub);
mul: exec_operand(opr_mul ,op_mul); mul: exec_opnodie(opr_mul ,op_mul);
div: exec_operand(opr_div ,op_div); div: exec_opnodie(opr_div ,op_div);
lnk: exec_operand(opr_lnk ,op_lnk); lnk: exec_opnodie(opr_lnk ,op_lnk);
addc: exec_operand(opr_addc ,op_addc); addc: exec_opnodie(opr_addc ,op_addc);
subc: exec_operand(opr_subc ,op_subc); subc: exec_opnodie(opr_subc ,op_subc);
mulc: exec_operand(opr_mulc ,op_mulc); mulc: exec_opnodie(opr_mulc ,op_mulc);
divc: exec_operand(opr_divc ,op_divc); divc: exec_opnodie(opr_divc ,op_divc);
lnkc: exec_operand(opr_lnkc ,op_lnkc); lnkc: exec_opnodie(opr_lnkc ,op_lnkc);
addeq: exec_operand(opr_addeq ,op_addeq); addeq: exec_opnodie(opr_addeq ,op_addeq);
subeq: exec_operand(opr_subeq ,op_subeq); subeq: exec_opnodie(opr_subeq ,op_subeq);
muleq: exec_operand(opr_muleq ,op_muleq); muleq: exec_opnodie(opr_muleq ,op_muleq);
diveq: exec_operand(opr_diveq ,op_diveq); diveq: exec_opnodie(opr_diveq ,op_diveq);
lnkeq: exec_operand(opr_lnkeq ,op_lnkeq); lnkeq: exec_opnodie(opr_lnkeq ,op_lnkeq);
addeqc: exec_operand(opr_addeqc ,op_addeqc); addeqc: exec_opnodie(opr_addeqc ,op_addeqc);
subeqc: exec_operand(opr_subeqc ,op_subeqc); subeqc: exec_opnodie(opr_subeqc ,op_subeqc);
muleqc: exec_operand(opr_muleqc ,op_muleqc); muleqc: exec_opnodie(opr_muleqc ,op_muleqc);
diveqc: exec_operand(opr_diveqc ,op_diveqc); diveqc: exec_opnodie(opr_diveqc ,op_diveqc);
lnkeqc: exec_operand(opr_lnkeqc ,op_lnkeqc); lnkeqc: exec_opnodie(opr_lnkeqc ,op_lnkeqc);
meq: exec_operand(opr_meq ,op_meq); meq: exec_opnodie(opr_meq ,op_meq);
eq: exec_operand(opr_eq ,op_eq); eq: exec_opnodie(opr_eq ,op_eq);
neq: exec_operand(opr_neq ,op_neq); neq: exec_opnodie(opr_neq ,op_neq);
less: exec_operand(opr_less ,op_less); less: exec_opnodie(opr_less ,op_less);
leq: exec_operand(opr_leq ,op_leq); leq: exec_opnodie(opr_leq ,op_leq);
grt: exec_operand(opr_grt ,op_grt); grt: exec_opnodie(opr_grt ,op_grt);
geq: exec_operand(opr_geq ,op_geq); geq: exec_opnodie(opr_geq ,op_geq);
lessc: exec_operand(opr_lessc ,op_lessc); lessc: exec_opnodie(opr_lessc ,op_lessc);
leqc: exec_operand(opr_leqc ,op_leqc); leqc: exec_opnodie(opr_leqc ,op_leqc);
grtc: exec_operand(opr_grtc ,op_grtc); grtc: exec_opnodie(opr_grtc ,op_grtc);
geqc: exec_operand(opr_geqc ,op_geqc); geqc: exec_opnodie(opr_geqc ,op_geqc);
pop: exec_operand(opr_pop ,op_pop); pop: exec_opnodie(opr_pop ,op_pop);
jmp: exec_operand(opr_jmp ,op_jmp); jmp: exec_opnodie(opr_jmp ,op_jmp);
jt: exec_operand(opr_jt ,op_jt); jt: exec_opnodie(opr_jt ,op_jt);
jf: exec_operand(opr_jf ,op_jf); jf: exec_opnodie(opr_jf ,op_jf);
counter: exec_operand(opr_counter ,op_cnt); counter: exec_operand(opr_counter ,op_cnt);
cntpop: exec_operand(opr_cntpop ,op_cntpop); cntpop: exec_opnodie(opr_cntpop ,op_cntpop);
findex: exec_operand(opr_findex ,op_findex); findex: exec_opnodie(opr_findex ,op_findex);
feach: exec_operand(opr_feach ,op_feach); feach: exec_opnodie(opr_feach ,op_feach);
callg: exec_operand(opr_callg ,op_callg); callg: exec_opnodie(opr_callg ,op_callg);
calll: exec_operand(opr_calll ,op_calll); calll: exec_opnodie(opr_calll ,op_calll);
callv: exec_operand(opr_callv ,op_callv); callv: exec_operand(opr_callv ,op_callv);
callvi: exec_operand(opr_callvi ,op_callvi); callvi: exec_operand(opr_callvi ,op_callvi);
callh: exec_operand(opr_callh ,op_callh); callh: exec_operand(opr_callh ,op_callh);
@ -997,13 +1000,13 @@ callfv: exec_operand(opr_callfv ,op_callfv);
callfh: exec_operand(opr_callfh ,op_callfh); callfh: exec_operand(opr_callfh ,op_callfh);
callb: exec_operand(opr_callb ,op_callb); callb: exec_operand(opr_callb ,op_callb);
slcbegin:exec_operand(opr_slcbegin,op_slcbegin); slcbegin:exec_operand(opr_slcbegin,op_slcbegin);
slcend: exec_operand(opr_slcend ,op_slcend); slcend: exec_opnodie(opr_slcend ,op_slcend);
slc: exec_operand(opr_slc ,op_slc); slc: exec_operand(opr_slc ,op_slc);
slc2: exec_operand(opr_slc2 ,op_slc2); slc2: exec_operand(opr_slc2 ,op_slc2);
mcallg: exec_operand(opr_mcallg ,op_mcallg); mcallg: exec_opnodie(opr_mcallg ,op_mcallg);
mcalll: exec_operand(opr_mcalll ,op_mcalll); mcalll: exec_opnodie(opr_mcalll ,op_mcalll);
mcallv: exec_operand(opr_mcallv ,op_mcallv); mcallv: exec_operand(opr_mcallv ,op_mcallv);
mcallh: exec_operand(opr_mcallh ,op_mcallh); mcallh: exec_operand(opr_mcallh ,op_mcallh);
ret: exec_operand(opr_ret ,op_ret); ret: exec_opnodie(opr_ret ,op_ret);
} }
#endif #endif