This commit is contained in:
Valk Richard Li 2021-02-13 11:09:31 +08:00
parent 7329c70492
commit 944f713ee9
4 changed files with 97 additions and 75 deletions

View File

@ -5,7 +5,7 @@ nasal_parse parse;
nasal_import import;
std::string inputfile="null";
nasal_codegen code_generator;
nasal_vm bytevm;
nasal_vm vm;
void help()
{
@ -120,7 +120,7 @@ void execute()
return;
}
code_generator.main_progress(import.get_root());
bytevm.run(
vm.run(
code_generator.get_string_table(),
code_generator.get_number_table(),
code_generator.get_exec_code()

View File

@ -128,11 +128,11 @@ struct opcode
class nasal_codegen
{
private:
std::map<double,int> number_table;
std::map<std::string,int> string_table;
std::vector<double> number_result_table;
std::vector<std::string> string_result_table;
std::vector<opcode> exec_code;
std::map<double,int> number_table;
std::map<std::string,int> string_table;
std::vector<double> number_result_table;
std::vector<std::string> string_result_table;
std::vector<opcode> exec_code;
std::list<std::vector<int> > continue_ptr;
std::list<std::vector<int> > break_ptr;
int error;
@ -323,9 +323,9 @@ void nasal_codegen::call_gen(nasal_ast& ast)
nasal_ast& tmp=ast.get_children()[i];
switch(tmp.get_type())
{
case ast_call_hash:call_hash(tmp);break;
case ast_call_vec: call_vec(tmp); break;
case ast_call_func:call_func(tmp);break;
case ast_callh:call_hash(tmp);break;
case ast_callv: call_vec(tmp); break;
case ast_callf:call_func(tmp);break;
}
}
return;
@ -404,9 +404,9 @@ void nasal_codegen::mem_call(nasal_ast& ast)
for(int i=1;i<child_size;++i)
{
nasal_ast& tmp=ast.get_children()[i];
if(tmp.get_type()==ast_call_hash)
if(tmp.get_type()==ast_callh)
mem_call_hash(tmp);
else if(tmp.get_type()==ast_call_vec)
else if(tmp.get_type()==ast_callv)
mem_call_vec(tmp);
}
return;
@ -588,11 +588,11 @@ void nasal_codegen::for_gen(nasal_ast& ast)
case ast_nil:case ast_num:case ast_str:case ast_func:break;
case ast_vec:case ast_hash:
case ast_call:
case ast_equal:case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
case ast_unary_sub:case ast_unary_not:
case ast_equal:case ast_addeq:case ast_subeq:case ast_multeq:case ast_diveq:case ast_lnkeq:
case ast_neg:case ast_not:
case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link:
case ast_cmp_equal:case ast_cmp_not_equal:case ast_leq:case ast_less:case ast_geq:case ast_grt:
case ast_trinocular:calculation_gen(ast.get_children()[0]);pop_gen();break;
case ast_cmpeq:case ast_neq:case ast_leq:case ast_less:case ast_geq:case ast_grt:
case ast_trino:calculation_gen(ast.get_children()[0]);pop_gen();break;
}
int jmp_place=exec_code.size();
if(ast.get_children()[1].get_type()==ast_null)
@ -612,11 +612,11 @@ void nasal_codegen::for_gen(nasal_ast& ast)
case ast_nil:case ast_num:case ast_str:case ast_func:break;
case ast_vec:case ast_hash:
case ast_call:
case ast_equal:case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
case ast_unary_sub:case ast_unary_not:
case ast_equal:case ast_addeq:case ast_subeq:case ast_multeq:case ast_diveq:case ast_lnkeq:
case ast_neg:case ast_not:
case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link:
case ast_cmp_equal:case ast_cmp_not_equal:case ast_leq:case ast_less:case ast_geq:case ast_grt:
case ast_trinocular:calculation_gen(ast.get_children()[2]);pop_gen();break;
case ast_cmpeq:case ast_neq:case ast_leq:case ast_less:case ast_geq:case ast_grt:
case ast_trino:calculation_gen(ast.get_children()[2]);pop_gen();break;
}
gen(op_jmp,jmp_place);
exec_code[label_exit].index=exec_code.size();
@ -747,11 +747,11 @@ void nasal_codegen::calculation_gen(nasal_ast& ast)
mem_call(ast.get_children()[0]);
gen(op_meq,0);
break;
// ast_add_equal(22)~ast_link_equal(26) op_addeq(23)~op_lnkeq(27)
case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
// 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_lnkeq:
calculation_gen(ast.get_children()[1]);
mem_call(ast.get_children()[0]);
gen(ast.get_type()-ast_add_equal+op_addeq,0);
gen(ast.get_type()-ast_addeq+op_addeq,0);
break;
case ast_or:or_gen(ast);break;
case ast_and:and_gen(ast);break;
@ -761,18 +761,18 @@ void nasal_codegen::calculation_gen(nasal_ast& ast)
calculation_gen(ast.get_children()[1]);
gen(ast.get_type()-ast_add+op_add,0);
break;
// ast_cmp_equal(27)~ast_geq(32) op_eq(29)~op_geq(34)
case ast_cmp_equal:case ast_cmp_not_equal:case ast_less:case ast_leq:case ast_grt:case ast_geq:
// ast_cmpeq(27)~ast_geq(32) op_eq(29)~op_geq(34)
case ast_cmpeq:case ast_neq:case ast_less:case ast_leq:case ast_grt:case ast_geq:
calculation_gen(ast.get_children()[0]);
calculation_gen(ast.get_children()[1]);
gen(ast.get_type()-ast_cmp_equal+op_eq,0);
gen(ast.get_type()-ast_cmpeq+op_eq,0);
break;
case ast_trinocular:trino_gen(ast);break;
case ast_unary_sub:
case ast_trino:trino_gen(ast);break;
case ast_neg:
calculation_gen(ast.get_children()[0]);
gen(op_usub,0);
break;
case ast_unary_not:
case ast_not:
calculation_gen(ast.get_children()[0]);
gen(op_unot,0);
break;
@ -809,27 +809,27 @@ void nasal_codegen::block_gen(nasal_ast& ast)
case ast_hash:
case ast_call:
case ast_equal:
case ast_add_equal:
case ast_sub_equal:
case ast_mult_equal:
case ast_div_equal:
case ast_link_equal:
case ast_unary_sub:
case ast_unary_not:
case ast_addeq:
case ast_subeq:
case ast_multeq:
case ast_diveq:
case ast_lnkeq:
case ast_neg:
case ast_not:
case ast_add:
case ast_sub:
case ast_mult:
case ast_div:
case ast_link:
case ast_cmp_equal:
case ast_cmp_not_equal:
case ast_cmpeq:
case ast_neq:
case ast_leq:
case ast_less:
case ast_geq:
case ast_grt:
case ast_or:
case ast_and:
case ast_trinocular:calculation_gen(tmp);pop_gen();break;
case ast_trino:calculation_gen(tmp);pop_gen();break;
case ast_return:return_gen(tmp);break;
}
}
@ -872,27 +872,27 @@ void nasal_codegen::main_progress(nasal_ast& ast)
case ast_hash:
case ast_call:
case ast_equal:
case ast_add_equal:
case ast_sub_equal:
case ast_mult_equal:
case ast_div_equal:
case ast_link_equal:
case ast_unary_sub:
case ast_unary_not:
case ast_addeq:
case ast_subeq:
case ast_multeq:
case ast_diveq:
case ast_lnkeq:
case ast_neg:
case ast_not:
case ast_add:
case ast_sub:
case ast_mult:
case ast_div:
case ast_link:
case ast_cmp_equal:
case ast_cmp_not_equal:
case ast_cmpeq:
case ast_neq:
case ast_leq:
case ast_less:
case ast_geq:
case ast_grt:
case ast_or:
case ast_and:
case ast_trinocular:calculation_gen(tmp);pop_gen();break;
case ast_trino:calculation_gen(tmp);pop_gen();break;
}
}
gen(op_nop,0);

View File

@ -45,7 +45,7 @@ bool nasal_import::check_import(nasal_ast& node)
return false;
if(ref_vec[0].get_str()!="import")
return false;
if(ref_vec[1].get_type()!=ast_call_func)
if(ref_vec[1].get_type()!=ast_callf)
return false;
if(ref_vec[1].get_children().size()!=1 || ref_vec[1].get_children()[0].get_type()!=ast_str)
return false;

View File

@ -50,6 +50,7 @@ private:
int in_loop; // count when generating loop block,used to check break/continue-expression
void reset();
void die(int,std::string);
void match(int);
bool check_multi_def();
bool check_multi_scalar();
bool check_function_end(nasal_ast&);
@ -165,6 +166,30 @@ void nasal_parse::die(int line,std::string info)
return;
}
void nasal_parse::match(int type)
{
if(ptr>=tok_list_size || tok_list[ptr].type!=type)
{
std::string s="";
for(int i=0;token_table[i].str;++i)
if(token_table[i].tok_type==type)
{
s=token_table[i].str;
break;
}
if(type==tok_num)
die(error_line,"expect a number");
else if(type==tok_str)
die(error_line,"expect a string");
else if(type==tok_id)
die(error_line,"expect an identifier");
else
die(error_line,"expect \'"+s+"\'");
}
++ptr;
return;
}
bool nasal_parse::check_multi_def()
{
return ptr+1<tok_list_size && tok_list[ptr+1].type==tok_var;
@ -202,11 +227,11 @@ bool nasal_parse::check_function_end(nasal_ast& node)
(
type!=ast_definition &&
type!=ast_equal &&
type!=ast_add_equal &&
type!=ast_sub_equal &&
type!=ast_mult_equal &&
type!=ast_div_equal &&
type!=ast_link_equal
type!=ast_addeq &&
type!=ast_subeq &&
type!=ast_multeq &&
type!=ast_diveq &&
type!=ast_lnkeq
)
)
return false;
@ -258,9 +283,9 @@ void nasal_parse::check_memory_reachable(nasal_ast& node)
for(int i=0;i<size;++i)
{
nasal_ast& tmp=node.get_children()[i];
if(tmp.get_type()==ast_call_func)
if(tmp.get_type()==ast_callf)
die(tmp.get_line(),"cannot get the memory of function-returned value");
if(tmp.get_type()==ast_call_vec && (tmp.get_children().size()>1 || tmp.get_children()[0].get_type()==ast_subvec))
if(tmp.get_type()==ast_callv && (tmp.get_children().size()>1 || tmp.get_children()[0].get_type()==ast_subvec))
die(tmp.get_line(),"cannot get the memory in temporary sliced vector");
}
}
@ -305,7 +330,7 @@ nasal_ast nasal_parse::id_gen()
nasal_ast nasal_parse::vec_gen()
{
nasal_ast node(tok_list[ptr].line,ast_vec);
++ptr;
match(tok_lbracket);
while(ptr<tok_list_size && tok_list[ptr].type!=tok_rbracket)
{
node.add_child(calc());
@ -323,7 +348,7 @@ nasal_ast nasal_parse::vec_gen()
nasal_ast nasal_parse::hash_gen()
{
nasal_ast node(tok_list[ptr].line,ast_hash);
++ptr;
match(tok_lbrace);
while (ptr<tok_list_size && tok_list[ptr].type!=tok_rbrace)
{
node.add_child(hmem_gen());
@ -348,19 +373,16 @@ nasal_ast nasal_parse::hmem_gen()
}
nasal_ast node(tok_list[ptr].line,ast_hashmember);
node.add_child(tok_list[ptr].type==tok_id?id_gen():str_gen());
if(++ptr>=tok_list_size || tok_list[ptr].type!=tok_colon)
{
die(error_line,"expected \":\"");
return node;
}
++ptr;
match(tok_colon);
node.add_child(calc());
return node;
}
nasal_ast nasal_parse::func_gen()
{
nasal_ast node(tok_list[ptr].line,ast_func);
if(++ptr>=tok_list_size)
match(tok_func);
if(ptr>=tok_list_size)
{
die(error_line,"expected argument(s)/expression block");
return node;
@ -561,7 +583,7 @@ nasal_ast nasal_parse::calc()
if(ptr<tok_list_size && tok_list[ptr].type==tok_quesmark)
{
// trinocular calculation
nasal_ast tmp(tok_list[ptr].line,ast_trinocular);
nasal_ast tmp(tok_list[ptr].line,ast_trino);
tmp.add_child(node);
++ptr;
tmp.add_child(calc());
@ -578,7 +600,7 @@ nasal_ast nasal_parse::calc()
{
// check the left expression to confirm it is available to get memory
check_memory_reachable(node);
// tok_eq~tok_lnkeq is 37 to 42,ast_equal~ast_link_equal is 21~26
// tok_eq~tok_lnkeq is 37 to 42,ast_equal~ast_lnkeq is 21~26
nasal_ast tmp(tok_list[ptr].line,tok_list[ptr].type-tok_eq+ast_equal);
tmp.add_child(node);
++ptr;
@ -628,8 +650,8 @@ nasal_ast nasal_parse::cmp_expr()
node=additive_expr();
while(++ptr<tok_list_size && tok_cmpeq<=tok_list[ptr].type && tok_list[ptr].type<=tok_geq)
{
// tok_cmpeq~tok_geq is 43~48,ast_cmp_equal~ast_geq is 27~32
nasal_ast tmp(tok_list[ptr].line,tok_list[ptr].type-tok_cmpeq+ast_cmp_equal);
// tok_cmpeq~tok_geq is 43~48,ast_cmpeq~ast_geq is 27~32
nasal_ast tmp(tok_list[ptr].line,tok_list[ptr].type-tok_cmpeq+ast_cmpeq);
tmp.add_child(node);
if(++ptr<tok_list_size)
tmp.add_child(additive_expr());
@ -701,8 +723,8 @@ nasal_ast nasal_parse::unary()
nasal_ast node(tok_list[ptr].line);
switch(tok_list[ptr].type)
{
case tok_sub:node.set_type(ast_unary_sub);break;
case tok_not:node.set_type(ast_unary_not);break;
case tok_sub:node.set_type(ast_neg);break;
case tok_not:node.set_type(ast_not);break;
}
if(++ptr<tok_list_size)
node.add_child((tok_list[ptr].type==tok_sub || tok_list[ptr].type==tok_not)?unary():scalar());
@ -712,7 +734,7 @@ nasal_ast nasal_parse::unary()
if(node.get_children()[0].get_type()==ast_num)
{
double num=node.get_children()[0].get_num();
num=(node.get_type()==ast_unary_not?(!num):-num);
num=(node.get_type()==ast_not?(!num):-num);
node.set_type(ast_num);
node.set_num(num);
node.get_children().clear();
@ -788,7 +810,7 @@ nasal_ast nasal_parse::call_scalar()
}
nasal_ast nasal_parse::call_hash()
{
nasal_ast node(tok_list[ptr].line,ast_call_hash);
nasal_ast node(tok_list[ptr].line,ast_callh);
if(++ptr<tok_list_size && tok_list[ptr].type==tok_id)
node.set_str(tok_list[ptr].str);
else
@ -797,7 +819,7 @@ nasal_ast nasal_parse::call_hash()
}
nasal_ast nasal_parse::call_vec()
{
nasal_ast node(tok_list[ptr].line,ast_call_vec);
nasal_ast node(tok_list[ptr].line,ast_callv);
++ptr;
while(ptr<tok_list_size && tok_list[ptr].type!=tok_rbracket)
{
@ -815,7 +837,7 @@ nasal_ast nasal_parse::call_vec()
}
nasal_ast nasal_parse::call_func()
{
nasal_ast node(tok_list[ptr].line,ast_call_func);
nasal_ast node(tok_list[ptr].line,ast_callf);
bool special_call=check_special_call();
++ptr;
while(ptr<tok_list_size && tok_list[ptr].type!=tok_rcurve)