This commit is contained in:
Valk Richard Li 2020-11-11 00:26:46 +08:00
parent 5c253bac88
commit 405172b317
2 changed files with 30 additions and 43 deletions

View File

@ -232,6 +232,8 @@ void nasal_vector::print()
{ {
int size=elems.size(); int size=elems.size();
std::cout<<"["; std::cout<<"[";
if(!size)
std::cout<<"]";
for(int i=0;i<size;++i) for(int i=0;i<size;++i)
{ {
nasal_scalar& tmp=nasal_vm.gc_get(nasal_vm.mem_get(elems[i])); nasal_scalar& tmp=nasal_vm.gc_get(nasal_vm.mem_get(elems[i]));
@ -389,6 +391,8 @@ int nasal_hash::get_keys()
void nasal_hash::print() void nasal_hash::print()
{ {
std::cout<<"{"; std::cout<<"{";
if(!elems.size())
std::cout<<"}";
for(std::map<std::string,int>::iterator i=elems.begin();i!=elems.end();++i) for(std::map<std::string,int>::iterator i=elems.begin();i!=elems.end();++i)
{ {
std::cout<<i->first<<":"; std::cout<<i->first<<":";

View File

@ -23,6 +23,7 @@ private:
// if error occurred,this value will add 1 // if error occurred,this value will add 1
int error; int error;
void die(int,std::string);
// generate vector and return gc place of this vector // generate vector and return gc place of this vector
int vector_generation(nasal_ast&,int); int vector_generation(nasal_ast&,int);
@ -123,6 +124,12 @@ nasal_runtime::~nasal_runtime()
this->builtin_func_hashmap.clear(); this->builtin_func_hashmap.clear();
return; return;
} }
void nasal_runtime::die(int line,std::string info)
{
++error;
std::cout<<">> [runtime] line "<<line<<": "+info<<".\n";
return;
}
void nasal_runtime::load_builtin_function() void nasal_runtime::load_builtin_function()
{ {
struct FUNC_TABLE struct FUNC_TABLE
@ -197,7 +204,7 @@ void nasal_runtime::run()
time_t total_run_time=end_time-begin_time; time_t total_run_time=end_time-begin_time;
if(total_run_time>=1) if(total_run_time>=1)
std::cout<<">> [runtime] process exited after "<<total_run_time<<"s "<<(returned_statement==rt_exit_without_error?".\n":"with errors.\n"); std::cout<<">> [runtime] process exited after "<<total_run_time<<"s.\n";
return; return;
} }
@ -254,14 +261,15 @@ int nasal_runtime::main_progress()
int process_returned_value_addr=-1; int process_returned_value_addr=-1;
for(int i=0;i<expr_number;++i) for(int i=0;i<expr_number;++i)
{ {
int node_type=root.get_children()[i].get_type(); nasal_ast& node=root.get_children()[i];
int node_type=node.get_type();
switch(node_type) switch(node_type)
{ {
case ast_definition:definition(root.get_children()[i],-1);break; case ast_definition:definition(node,-1);break;
case ast_multi_assign:multi_assignment(root.get_children()[i],-1);break; case ast_multi_assign:multi_assignment(node,-1);break;
case ast_conditional:ret_state=conditional_progress(root.get_children()[i],-1,false);break; case ast_conditional:ret_state=conditional_progress(node,-1,false);break;
case ast_while:case ast_for:case ast_forindex:case ast_foreach: case ast_while:case ast_for:case ast_forindex:case ast_foreach:
ret_state=loop_progress(root.get_children()[i],-1,false);break; ret_state=loop_progress(node,-1,false);break;
case ast_nil:case ast_number:case ast_string:case ast_function:break; case ast_nil:case ast_number:case ast_string:case ast_function:break;
case ast_identifier: case ast_identifier:
case ast_vector:case ast_hash: case ast_vector:case ast_hash:
@ -269,14 +277,7 @@ int nasal_runtime::main_progress()
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_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_unary_sub:case ast_unary_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_trinocular:nasal_vm.del_reference(calculation(root.get_children()[i],-1));break; case ast_trinocular:nasal_vm.del_reference(calculation(node,-1));break;
}
switch(ret_state)
{
case rt_break:std::cout<<">> [runtime] main: cannot use break in main progress.\n";++error;break;
case rt_continue:std::cout<<">> [runtime] main: cannot use continue in main progress.\n";++error;break;
case rt_return:std::cout<<">> [runtime] main: cannot use return in main progress.\n";++error;break;
case rt_error:std::cout<<">> [runtime] main: error occurred when executing main progress.\n";++error;break;
} }
if(error) if(error)
{ {
@ -337,17 +338,9 @@ int nasal_runtime::block_progress(nasal_ast& node,int local_scope_addr,bool allo
} }
} }
else else
{ die(tmp_node.get_line(),"cannot use return here");
std::cout<<">> [runtime] block_progress: return expression is not allowed here.\n";
++error;
}
break; break;
} }
if(ret_state==rt_error)
{
std::cout<<">> [runtime] block_progress: error occurred when executing sub-progress.\n";
++error;
}
if(error || ret_state==rt_break || ret_state==rt_continue || ret_state==rt_return) if(error || ret_state==rt_break || ret_state==rt_continue || ret_state==rt_return)
break; break;
} }
@ -370,7 +363,7 @@ int nasal_runtime::before_for_loop(nasal_ast& node,int local_scope_addr)
case ast_unary_sub:case ast_unary_not: case ast_unary_sub:case ast_unary_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_trinocular:nasal_vm.del_reference(calculation(node,local_scope_addr));break; case ast_trinocular:nasal_vm.del_reference(calculation(node,local_scope_addr));break;
default:std::cout<<">> [runtime] before_for_loop: cannot use this expression before for-loop.\n";++error;break; default:die(node.get_line(),"cannot use this expression before for-loop");break;
} }
if(error) if(error)
return rt_error; return rt_error;
@ -391,7 +384,7 @@ int nasal_runtime::after_each_for_loop(nasal_ast& node,int local_scope_addr)
case ast_unary_sub:case ast_unary_not: case ast_unary_sub:case ast_unary_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_trinocular:nasal_vm.del_reference(calculation(node,local_scope_addr));break; case ast_trinocular:nasal_vm.del_reference(calculation(node,local_scope_addr));break;
default:std::cout<<">> [runtime] after_each_for_loop: cannot use this expression after each for-loop.\n";++error;break; default:die(node.get_line(),"cannot use this expression after each for-loop");break;
} }
if(error) if(error)
return rt_error; return rt_error;
@ -444,8 +437,7 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr,bool allow
int vector_value_addr=calculation(vector_node,local_scope_addr); int vector_value_addr=calculation(vector_node,local_scope_addr);
if(vector_value_addr<0 || nasal_vm.gc_get(vector_value_addr).get_type()!=vm_vector) if(vector_value_addr<0 || nasal_vm.gc_get(vector_value_addr).get_type()!=vm_vector)
{ {
std::cout<<">> [runtime] loop_progress: "<<(loop_type==ast_forindex? "forindex":"foreach")<<" gets a value that is not a vector.\n"; die(vector_node.get_line(),"must use vector in forindex/foreach");
++error;
return rt_error; return rt_error;
} }
// create a new local scope to store iterator if local_scope_addr=-1 // create a new local scope to store iterator if local_scope_addr=-1
@ -475,8 +467,7 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr,bool allow
mem_addr=call_scalar_mem(iter_node,local_scope_addr); mem_addr=call_scalar_mem(iter_node,local_scope_addr);
if(mem_addr<0) if(mem_addr<0)
{ {
std::cout<<">> [runtime] loop_progress: get null iterator.\n"; die(iter_node.get_line(),"get null iterator");
++error;
return rt_error; return rt_error;
} }
// ref_vector's size may change when running,so this loop will check size each time // ref_vector's size may change when running,so this loop will check size each time
@ -554,12 +545,8 @@ bool nasal_runtime::check_condition(int value_addr)
if(value_addr<0) if(value_addr<0)
return false; return false;
int type=nasal_vm.gc_get(value_addr).get_type(); int type=nasal_vm.gc_get(value_addr).get_type();
if(type==vm_vector || type==vm_hash || type==vm_function || type==vm_closure) if(type==vm_vector || type==vm_hash || type==vm_function)
{
std::cout<<">> [runtime] check_condition: error value type when checking condition.\n";
++error;
return false; return false;
}
else if(type==vm_string) else if(type==vm_string)
{ {
std::string str=nasal_vm.gc_get(value_addr).get_string(); std::string str=nasal_vm.gc_get(value_addr).get_string();
@ -625,10 +612,9 @@ int nasal_runtime::call_scalar(nasal_ast& node,int local_scope_addr)
if(value_address<0) if(value_address<0)
{ {
if(builtin_func_hashmap.find(val_name)!=builtin_func_hashmap.end()) if(builtin_func_hashmap.find(val_name)!=builtin_func_hashmap.end())
std::cout<<">> [runtime] call_scalar: call "<<val_name<<" failed.\n"; die(node.get_children()[0].get_line(),"call "+val_name+" failed");
else else
std::cout<<">> [runtime] call_scalar: cannot find value named \""<<val_name<<"\".\n"; die(node.get_children()[0].get_line()," cannot find \""+val_name+"\"");
++error;
return -1; return -1;
} }
nasal_vm.add_reference(value_address); nasal_vm.add_reference(value_address);
@ -672,8 +658,7 @@ int nasal_runtime::call_vector(nasal_ast& node,int base_value_addr,int local_sco
int base_value_type=nasal_vm.gc_get(base_value_addr).get_type(); int base_value_type=nasal_vm.gc_get(base_value_addr).get_type();
if(base_value_type!=vm_vector && base_value_type!=vm_hash && base_value_type!=vm_string) if(base_value_type!=vm_vector && base_value_type!=vm_hash && base_value_type!=vm_string)
{ {
std::cout<<">> [runtime] call_vector: incorrect value type,expected a vector/hash/string.\n"; die(node.get_line(),"cannot find elements by index in nil/number/function");
++error;
return -1; return -1;
} }
int call_size=node.get_children().size(); int call_size=node.get_children().size();
@ -695,14 +680,12 @@ int nasal_runtime::call_vector(nasal_ast& node,int base_value_addr,int local_sco
int begin_index=0,end_index=0; int begin_index=0,end_index=0;
if(begin_value_type!=vm_nil && begin_value_type!=vm_number && begin_value_type!=vm_string) if(begin_value_type!=vm_nil && begin_value_type!=vm_number && begin_value_type!=vm_string)
{ {
std::cout<<">> [runtime] call_vector: begin index is not a number/numerable string.\n"; die(subvec_node.get_children()[0].get_line(),"begin index must be nil/number/string");
++error;
return -1; return -1;
} }
if(end_value_type!=vm_nil && end_value_type!=vm_number && end_value_type!=vm_string) if(end_value_type!=vm_nil && end_value_type!=vm_number && end_value_type!=vm_string)
{ {
std::cout<<">> [runtime] call_vector: end index is not a number/numerable string.\n"; die(subvec_node.get_children()[1].get_line(),"end index must be nil/number/string");
++error;
return -1; return -1;
} }
if(begin_value_type==vm_string) if(begin_value_type==vm_string)