update
This commit is contained in:
parent
7329c70492
commit
944f713ee9
4
main.cpp
4
main.cpp
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue