From 35b05f8171161b256ba88ced95cabae4ebf30fef Mon Sep 17 00:00:00 2001 From: Valk Richard Li <48872266+ValKmjolnir@users.noreply.github.com> Date: Sat, 21 Mar 2020 15:10:44 +0800 Subject: [PATCH] update --- version2.0/nasal_gc.h | 21 +++ version2.0/nasal_runtime.h | 253 +++++++++++++++++++++++++++++++++---- 2 files changed, 248 insertions(+), 26 deletions(-) diff --git a/version2.0/nasal_gc.h b/version2.0/nasal_gc.h index f876cfc..8f92b16 100644 --- a/version2.0/nasal_gc.h +++ b/version2.0/nasal_gc.h @@ -57,6 +57,7 @@ class nasal_vector public: void set_clear(); void vec_push(int); + int* get_elem_addr(int); int get_elem(int); int vec_pop(); int get_size(); @@ -74,6 +75,7 @@ class nasal_hash void set_self_addr(int); void set_clear(); int get_self_addr(); + int* get_hash_member_addr(std::string); int get_hash_member(std::string); void hash_push(std::string,int); void hash_pop(std::string); @@ -353,6 +355,16 @@ void nasal_vector::vec_push(int addr) nas_array.push_back(addr); return; } +int* nasal_vector::get_elem_addr(int addr) +{ + // 0 ~ size-1 -size ~ -1 + int bound=nas_array.size(); + if(-bound<=addr && addr<0) + return &nas_array[bound+addr]; + else if(0<=addr && addr global_scope; std::list > main_local_scope; + + // enum of state type + enum state_stack_member_type + { + __state_error, + __state_continue=1, + __state_break, + __state_return, + }; + // state stack is used when loop/conditional expr running + std::stack state_stack; // see detail of each enum type in function error_interrupt(const int) enum runtime_error_type { __incorrect_head_of_tree, - __incorrect_head_of_func, __undefined_identifier, __multi_assign_incorrect_value_number, __multi_define_incorrect_value_number, @@ -32,6 +42,8 @@ class nasal_runtime __special_call_vector_negative_value, __special_call_vector_too_large_value, __normal_call_vector_too_large_value, + __error_call_type_when_getting_address, + __forindex_foreach_not_vector, __stack_overflow, }; int runtime_error_exit_mark; @@ -47,7 +59,7 @@ class nasal_runtime void definition (std::list >&,std::map&,abstract_syntax_tree&); void loop_expr (std::list >&,abstract_syntax_tree&); void conditional (std::list >&,abstract_syntax_tree&); - int func_proc (std::list >&,abstract_syntax_tree&,abstract_syntax_tree&); + int func_proc (std::list >&,abstract_syntax_tree&,abstract_syntax_tree&,int); public: nasal_runtime() { @@ -71,8 +83,6 @@ void nasal_runtime::error_interrupt(const int type,const int line) { case __incorrect_head_of_tree: std::cout<<"lib hasn\'t been loaded."< >& local_scop int* nasal_runtime::get_identifier_addr(std::list >& local_scope,abstract_syntax_tree& node) { int* ret_addr=NULL; + std::string tmp_id_name=node.get_var_name(); + if(global_scope.find(tmp_id_name)!=global_scope.end()) + ret_addr=&global_scope[tmp_id_name]; + for(std::list >::iterator iter=local_scope.begin();iter!=local_scope.end();++iter) + if(iter->find(tmp_id_name)!=iter->end()) + ret_addr=&(*iter)[tmp_id_name]; + if(!ret_addr) + { + error_interrupt(__undefined_identifier,node.get_node_line()); + return NULL; + } + for(std::list::iterator iter=node.get_children().begin();iter!=node.get_children().end();++iter) + { + // call vector/special call hash/subvec + // the special type of calling hash like a["name"] is also generated as calling vector + if(iter->get_node_type()==__call_vector) + { + // check the scalar type of called identifier here + int called_type=nasal_gc.get_scalar(*ret_addr).get_type(); + if(called_type!=scalar_vector && called_type!=scalar_hash) + { + error_interrupt(__error_value_type,iter->get_node_line()); + return NULL; + } + if(iter->get_children().front().get_node_type()==__sub_vector) + { + error_interrupt(__error_call_type_when_getting_address,iter->get_children().front().get_node_line()); + return NULL; + }// end sub-vector + else + { + int data_addr=calculation(local_scope,iter->get_children().front()); + if(data_addr<0) + return NULL; + if(nasal_gc.get_scalar(data_addr).get_type()!=scalar_number && nasal_gc.get_scalar(data_addr).get_type()!=scalar_string) + { + error_interrupt(__error_value_type_when_calling_vector,iter->get_children().front().get_node_line()); + return NULL; + } + if(called_type==scalar_vector) + { + double place_num=0; + if(nasal_gc.get_scalar(data_addr).get_type()==scalar_string) + { + if(check_numerable_string(nasal_gc.get_scalar(data_addr).get_string().get_string())) + place_num=(int)trans_string_to_number(nasal_gc.get_scalar(data_addr).get_string().get_string()); + else + { + error_interrupt(__not_numerable_str,iter->get_children().front().get_node_line()); + return NULL; + } + } + if(place_num>2147483647 || place_num<-2147483648) + { + error_interrupt(__normal_call_vector_too_large_value,iter->get_children().front().get_node_line()); + return NULL; + } + ret_addr=nasal_gc.get_scalar(*ret_addr).get_vector().get_elem_addr((int)place_num); + if(!ret_addr) + { + error_interrupt(__invalid_vector_member,iter->get_children().front().get_children().front().get_node_line()); + return NULL; + } + } + else if(called_type==scalar_hash) + { + if(nasal_gc.get_scalar(data_addr).get_type()!=scalar_string) + { + error_interrupt(__error_value_type_when_calling_hash,iter->get_children().front().get_node_line()); + return NULL; + } + ret_addr=nasal_gc.get_scalar(*ret_addr).get_hash().get_hash_member_addr(nasal_gc.get_scalar(data_addr).get_string().get_string()); + if(!ret_addr) + { + error_interrupt(__invalid_hash_member,iter->get_children().front().get_node_line()); + return NULL; + } + } + nasal_gc.reference_delete(data_addr); + } + }// end call vector + // call hash identifier.identifier + else if(iter->get_node_type()==__call_hash) + { + if(nasal_gc.get_scalar(*ret_addr).get_type()!=scalar_hash) + { + error_interrupt(__not_callable_hash,iter->get_node_line()); + return NULL; + } + ret_addr=nasal_gc.get_scalar(*ret_addr).get_hash().get_hash_member_addr(iter->get_var_name()); + if(!ret_addr) + { + error_interrupt(__invalid_hash_member,iter->get_node_line()); + return NULL; + } + }// end call hash + else + { + error_interrupt(__error_call_type_when_getting_address,iter->get_node_line()); + return NULL; + } + } return ret_addr; } int nasal_runtime::call_identifier(std::list >& local_scope,abstract_syntax_tree& node) @@ -1116,6 +1234,7 @@ int nasal_runtime::call_identifier(std::list >& local_ error_interrupt(__undefined_identifier,node.get_node_line()); return -1; } + //addr refcnt+1 nasal_gc.reference_add(addr); int last_hash_addr=-1; for(std::list::iterator iter=node.get_children().begin();iter!=node.get_children().end();++iter) @@ -1229,6 +1348,10 @@ int nasal_runtime::call_identifier(std::list >& local_ end_num=nasal_gc.get_scalar(addr).get_vector().get_size(); else end_num=(int)nasal_gc.get_scalar(num2_addr).get_number().get_number(); + if(num1_addr>=0) + nasal_gc.reference_delete(num1_addr); + if(num2_addr>=0) + nasal_gc.reference_delete(num2_addr); std::vector subvec_result; for(int i=begin_num;i >& local_ }// end sub-vector else { + // normal vector/hash calling int data_addr=calculation(local_scope,iter->get_children().front()); if(data_addr<0) return -1; @@ -1300,7 +1424,7 @@ int nasal_runtime::call_identifier(std::list >& local_ return -1; } } - if(place_num>2147483647) + if(place_num>2147483647 || place_num<-2147483648) { error_interrupt(__normal_call_vector_too_large_value,iter->get_children().front().get_node_line()); return -1; @@ -1332,10 +1456,10 @@ int nasal_runtime::call_identifier(std::list >& local_ nasal_gc.reference_add(addr); nasal_gc.reference_delete(tmp_addr); } + nasal_gc.reference_delete(data_addr); } }// end call vector - // call hash - // identifier.identifier + // call hash identifier.identifier else if(iter->get_node_type()==__call_hash) { if(nasal_gc.get_scalar(addr).get_type()!=scalar_hash) @@ -1350,8 +1474,7 @@ int nasal_runtime::call_identifier(std::list >& local_ return -1; } }// end call hash - // call function - // identifier(...) + // call function identifier(...) else if(iter->get_node_type()==__call_function) { if(nasal_gc.get_scalar(addr).get_type()!=scalar_function) @@ -1359,7 +1482,14 @@ int nasal_runtime::call_identifier(std::list >& local_ error_interrupt(__not_callable_function,iter->get_node_line()); return -1; } - ; + int tmp_addr=addr; + addr=func_proc( + nasal_gc.get_scalar(addr).get_function().get_local_scope(), + nasal_gc.get_scalar(addr).get_function().get_parameter_list(), + nasal_gc.get_scalar(addr).get_function().get_statement_block(), + last_hash_addr); + if(addr<0) + return -1; } } // after calculation or assignment/definition,reference counter of this address will -1 @@ -1484,8 +1614,6 @@ void nasal_runtime::definition(std::list >&local_scope else { std::string id_name=node.get_children().front().get_var_name(); - if(now_scope.find(id_name)!=now_scope.end()) - nasal_gc.reference_delete(now_scope[id_name]); int data_addr=calculation(local_scope,node.get_children().back()); if(data_addr<0) return; @@ -1518,6 +1646,8 @@ void nasal_runtime::definition(std::list >&local_scope break; } nasal_gc.reference_delete(data_addr); + if(now_scope.find(id_name)!=now_scope.end()) + nasal_gc.reference_delete(now_scope[id_name]); now_scope[id_name]=new_data_addr; } return; @@ -1529,19 +1659,59 @@ void nasal_runtime::loop_expr(std::list >& local_scope int loop_type=node.get_node_type(); if(loop_type==__while) { - ; + int condition_data=calculation(local_scope,node.get_children().front()); + // run block } else if(loop_type==__foreach) { - ; + std::list::iterator i=node.get_children().begin(); + int* addr=NULL;// definition + ++i; + int vec_addr=calculation(local_scope,*i); + if(vec_addr<0) + { + state_stack.push(__state_error); + return; + } + if(nasal_gc.get_scalar(vec_addr).get_type()!=scalar_vector) + { + error_interrupt(__forindex_foreach_not_vector,i->get_node_line()); + state_stack.push(__state_error); + return; + } + ++i; + // run block } else if(loop_type==__forindex) { - ; + std::list::iterator i=node.get_children().begin(); + int* addr=NULL;// definition + ++i; + int vec_addr=calculation(local_scope,*i); + if(vec_addr<0) + { + state_stack.push(__state_error); + return; + } + if(nasal_gc.get_scalar(vec_addr).get_type()!=scalar_vector) + { + error_interrupt(__forindex_foreach_not_vector,i->get_node_line()); + state_stack.push(__state_error); + return; + } + ++i; + // run block } else if(loop_type==__for) { - ; + std::list::iterator i=node.get_children().begin(); + // definition + ++i; + // conditional + ++i; + // step + ++i; + // run block } for(std::map::iterator i=local_scope.back().begin();i!=local_scope.back().end();++i) nasal_gc.reference_delete(i->second); @@ -1555,12 +1725,44 @@ void nasal_runtime::conditional(std::list >& local_sco for(std::list::iterator i=node.get_children().begin();i!=node.get_children().end();++i) { int condition_node_type=i->get_node_type(); - if(condition_node_type==__if) - ; - else if(condition_node_type==__elsif) - ; + if(condition_node_type==__if || condition_node_type==__elsif) + { + int condition_data=calculation(local_scope,i->get_children().front()); + if(condition_data<0) + { + state_stack.push(__state_error); + return; + } + if((nasal_gc.get_scalar(condition_data).get_type()==scalar_number + && nasal_gc.get_scalar(condition_data).get_number().get_number()!=0)) + { + ; + } + else if(nasal_gc.get_scalar(condition_data).get_type()==scalar_string) + { + if(!check_numerable_string(nasal_gc.get_scalar(condition_data).get_string().get_string())) + { + error_interrupt(__not_numerable_str,i->get_children().front().get_node_line()); + state_stack.push(__state_error); + return; + } + if(trans_string_to_number(nasal_gc.get_scalar(condition_data).get_string().get_string())) + { + ; + } + } + else + { + error_interrupt(__error_value_type,i->get_children().front().get_node_line()); + state_stack.push(__state_error); + return; + } + } else + { ; + break; + } } for(std::map::iterator i=local_scope.back().begin();i!=local_scope.back().end();++i) nasal_gc.reference_delete(i->second); @@ -1568,15 +1770,12 @@ void nasal_runtime::conditional(std::list >& local_sco return; } -int nasal_runtime::func_proc(std::list >& local_scope,abstract_syntax_tree& parameter_list,abstract_syntax_tree& func_root) +int nasal_runtime::func_proc(std::list >& local_scope,abstract_syntax_tree& parameter_list,abstract_syntax_tree& func_root,int called_hash_addr) { - if(func_root.get_node_type()!=__function) - { - error_interrupt(__incorrect_head_of_func,func_root.get_node_line()); - return -1; - } std::map new_scope; local_scope.push_back(new_scope); + if(called_hash_addr>=0) + local_scope.back()["me"]=called_hash_addr; // loading parameters for(std::list::iterator iter=parameter_list.get_children().begin();iter!=parameter_list.get_children().end();++iter) { @@ -1624,6 +1823,8 @@ void nasal_runtime::main_proc(abstract_syntax_tree& root) global_scope.clear(); nasal_gc.gc_init(); runtime_error_exit_mark=-1; + while(!state_stack.empty()) + state_stack.pop(); if(root.get_node_type()!=__root) {