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

View File

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

View File

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

View File

@ -50,6 +50,7 @@ private:
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 reset();
void die(int,std::string); void die(int,std::string);
void match(int);
bool check_multi_def(); bool check_multi_def();
bool check_multi_scalar(); bool check_multi_scalar();
bool check_function_end(nasal_ast&); bool check_function_end(nasal_ast&);
@ -165,6 +166,30 @@ void nasal_parse::die(int line,std::string info)
return; 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() bool nasal_parse::check_multi_def()
{ {
return ptr+1<tok_list_size && tok_list[ptr+1].type==tok_var; 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_definition &&
type!=ast_equal && type!=ast_equal &&
type!=ast_add_equal && type!=ast_addeq &&
type!=ast_sub_equal && type!=ast_subeq &&
type!=ast_mult_equal && type!=ast_multeq &&
type!=ast_div_equal && type!=ast_diveq &&
type!=ast_link_equal type!=ast_lnkeq
) )
) )
return false; return false;
@ -258,9 +283,9 @@ void nasal_parse::check_memory_reachable(nasal_ast& node)
for(int i=0;i<size;++i) for(int i=0;i<size;++i)
{ {
nasal_ast& tmp=node.get_children()[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"); 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"); 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 nasal_parse::vec_gen()
{ {
nasal_ast node(tok_list[ptr].line,ast_vec); nasal_ast node(tok_list[ptr].line,ast_vec);
++ptr; match(tok_lbracket);
while(ptr<tok_list_size && tok_list[ptr].type!=tok_rbracket) while(ptr<tok_list_size && tok_list[ptr].type!=tok_rbracket)
{ {
node.add_child(calc()); node.add_child(calc());
@ -323,7 +348,7 @@ nasal_ast nasal_parse::vec_gen()
nasal_ast nasal_parse::hash_gen() nasal_ast nasal_parse::hash_gen()
{ {
nasal_ast node(tok_list[ptr].line,ast_hash); nasal_ast node(tok_list[ptr].line,ast_hash);
++ptr; match(tok_lbrace);
while (ptr<tok_list_size && tok_list[ptr].type!=tok_rbrace) while (ptr<tok_list_size && tok_list[ptr].type!=tok_rbrace)
{ {
node.add_child(hmem_gen()); node.add_child(hmem_gen());
@ -348,19 +373,16 @@ nasal_ast nasal_parse::hmem_gen()
} }
nasal_ast node(tok_list[ptr].line,ast_hashmember); nasal_ast node(tok_list[ptr].line,ast_hashmember);
node.add_child(tok_list[ptr].type==tok_id?id_gen():str_gen()); 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; ++ptr;
match(tok_colon);
node.add_child(calc()); node.add_child(calc());
return node; return node;
} }
nasal_ast nasal_parse::func_gen() nasal_ast nasal_parse::func_gen()
{ {
nasal_ast node(tok_list[ptr].line,ast_func); 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"); die(error_line,"expected argument(s)/expression block");
return node; return node;
@ -561,7 +583,7 @@ nasal_ast nasal_parse::calc()
if(ptr<tok_list_size && tok_list[ptr].type==tok_quesmark) if(ptr<tok_list_size && tok_list[ptr].type==tok_quesmark)
{ {
// trinocular calculation // trinocular calculation
nasal_ast tmp(tok_list[ptr].line,ast_trinocular); nasal_ast tmp(tok_list[ptr].line,ast_trino);
tmp.add_child(node); tmp.add_child(node);
++ptr; ++ptr;
tmp.add_child(calc()); 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 the left expression to confirm it is available to get memory
check_memory_reachable(node); 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); nasal_ast tmp(tok_list[ptr].line,tok_list[ptr].type-tok_eq+ast_equal);
tmp.add_child(node); tmp.add_child(node);
++ptr; ++ptr;
@ -628,8 +650,8 @@ nasal_ast nasal_parse::cmp_expr()
node=additive_expr(); node=additive_expr();
while(++ptr<tok_list_size && tok_cmpeq<=tok_list[ptr].type && tok_list[ptr].type<=tok_geq) 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 // 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_cmp_equal); nasal_ast tmp(tok_list[ptr].line,tok_list[ptr].type-tok_cmpeq+ast_cmpeq);
tmp.add_child(node); tmp.add_child(node);
if(++ptr<tok_list_size) if(++ptr<tok_list_size)
tmp.add_child(additive_expr()); tmp.add_child(additive_expr());
@ -701,8 +723,8 @@ nasal_ast nasal_parse::unary()
nasal_ast node(tok_list[ptr].line); nasal_ast node(tok_list[ptr].line);
switch(tok_list[ptr].type) switch(tok_list[ptr].type)
{ {
case tok_sub:node.set_type(ast_unary_sub);break; case tok_sub:node.set_type(ast_neg);break;
case tok_not:node.set_type(ast_unary_not);break; case tok_not:node.set_type(ast_not);break;
} }
if(++ptr<tok_list_size) if(++ptr<tok_list_size)
node.add_child((tok_list[ptr].type==tok_sub || tok_list[ptr].type==tok_not)?unary():scalar()); 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) if(node.get_children()[0].get_type()==ast_num)
{ {
double num=node.get_children()[0].get_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_type(ast_num);
node.set_num(num); node.set_num(num);
node.get_children().clear(); node.get_children().clear();
@ -788,7 +810,7 @@ nasal_ast nasal_parse::call_scalar()
} }
nasal_ast nasal_parse::call_hash() 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) if(++ptr<tok_list_size && tok_list[ptr].type==tok_id)
node.set_str(tok_list[ptr].str); node.set_str(tok_list[ptr].str);
else else
@ -797,7 +819,7 @@ nasal_ast nasal_parse::call_hash()
} }
nasal_ast nasal_parse::call_vec() 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; ++ptr;
while(ptr<tok_list_size && tok_list[ptr].type!=tok_rbracket) 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 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(); bool special_call=check_special_call();
++ptr; ++ptr;
while(ptr<tok_list_size && tok_list[ptr].type!=tok_rcurve) while(ptr<tok_list_size && tok_list[ptr].type!=tok_rcurve)