From 6abca8c12f517c3104c67ee688438431afd4727a Mon Sep 17 00:00:00 2001 From: Valk Richard Li <48872266+ValKmjolnir@users.noreply.github.com> Date: Wed, 18 Mar 2020 01:40:19 +0800 Subject: [PATCH] update --- version2.0/nasal_gc.h | 46 +------------------- version2.0/nasal_runtime.h | 86 ++++++++++++++++++++++++++++++++------ 2 files changed, 74 insertions(+), 58 deletions(-) diff --git a/version2.0/nasal_gc.h b/version2.0/nasal_gc.h index f831db2..4165378 100644 --- a/version2.0/nasal_gc.h +++ b/version2.0/nasal_gc.h @@ -16,13 +16,10 @@ class nasal_function // parent_hash_addr is used to store the address of the hash which has this nasal_function // because nasal_function needs this address to adjust the identifier called 'me' in local_scope // 'me' is the identifier which points to the hash which has this nasal_function - int parent_hash_addr; public: - nasal_function(); void set_clear(); void set_local_scope(std::list >&); void set_statement_block(abstract_syntax_tree&); - void set_parent_hash_addr(int); std::list >& get_local_scope(); abstract_syntax_tree& get_statement_block(); void deep_copy(nasal_function&); @@ -240,11 +237,7 @@ gc_manager nasal_gc; // this object is used in "nasal_runtime.h" // because there must be only one gc when running a program(one process) -nasal_function::nasal_function() -{ - parent_hash_addr=-1; - return; -} + void nasal_function::set_clear() { for(std::list >::iterator iter=local_scope.begin();iter!=local_scope.end();++iter) @@ -252,7 +245,6 @@ void nasal_function::set_clear() nasal_gc.reference_delete(i->second); local_scope.clear(); function_root.set_clear(); - parent_hash_addr=-1; return; } void nasal_function::set_local_scope(std::list >& tmp_scope) @@ -268,35 +260,6 @@ void nasal_function::set_statement_block(abstract_syntax_tree& func_block) function_root=func_block; return; } -void nasal_function::set_parent_hash_addr(int addr) -{ - // in normal cases this function is often called after this->set_local_scope(...) - // because creating a new nasal function needs local_scope(closure) and abstract syntax tree. - // then the nasal function will be given to an identifier. - // after checking the identifier and making sure it is a hash, - // call this function and set 'me' to this addr if exists. - // if 'me' does not exist,then add a new identifeir named 'me' and give it the addr. - // also 'me' can be changed in hash function by ways like "var me=1;" - parent_hash_addr=addr; - bool has_identifier_me=false; - for(std::list >::iterator iter=local_scope.begin();iter!=local_scope.end();++iter) - for(std::map::iterator i=iter->begin();i!=iter->end();++i) - if(i->first=="me") - { - has_identifier_me=true; - i->second=parent_hash_addr; - } - if(!has_identifier_me) - { - if(local_scope.empty()) - { - std::map new_scope; - local_scope.push_back(new_scope); - } - local_scope.back()["me"]=parent_hash_addr; - } - return; -} std::list >& nasal_function::get_local_scope() { return local_scope; @@ -448,11 +411,7 @@ int nasal_hash::get_hash_member(std::string member_name) void nasal_hash::hash_push(std::string member_name,int addr) { if(nas_hash.find(member_name)==nas_hash.end()) - { nas_hash[member_name]=addr; - if(nasal_gc.place_check(addr) && nasal_gc.get_scalar(addr).get_type()==scalar_function) - nasal_gc.get_scalar(addr).get_function().set_parent_hash_addr(this->get_self_addr()); - } return; } void nasal_hash::hash_pop(std::string member_name) @@ -489,10 +448,7 @@ void nasal_hash::deep_copy(nasal_hash& tmp) nasal_gc.get_scalar(new_addr).get_hash().deep_copy(nasal_gc.get_scalar(i->second).get_hash()); } else if(tmp_type==scalar_function) - { - nasal_gc.get_scalar(new_addr).get_function().set_parent_hash_addr(this->self_addr); nasal_gc.get_scalar(new_addr).get_function().deep_copy(nasal_gc.get_scalar(i->second).get_function()); - } nas_hash[i->first]=new_addr; } return; diff --git a/version2.0/nasal_runtime.h b/version2.0/nasal_runtime.h index d9ef3fa..9094ad0 100644 --- a/version2.0/nasal_runtime.h +++ b/version2.0/nasal_runtime.h @@ -18,6 +18,8 @@ class nasal_runtime __incorrect_head_of_func, __undefined_identifier, __multi_assign_incorrect_value_number, + __invalid_vector_member, + __invalid_hash_member, __memory_overflow, __not_callable_vector, __not_callable_hash, @@ -35,7 +37,7 @@ class nasal_runtime int calculation (std::list >&,abstract_syntax_tree&); int* get_identifier_addr(std::list >&,abstract_syntax_tree&); int call_identifier (std::list >&,abstract_syntax_tree&); - void definition (std::map&,abstract_syntax_tree&); + 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&); @@ -68,6 +70,10 @@ void nasal_runtime::error_interrupt(const int type,const int line) std::cout<<"undefined identifier."< >& local_ { int addr=nasal_gc.gc_alloc(); nasal_gc.get_scalar(addr).set_type(scalar_hash); + // self address must be set here + // if not,then 'me' in function-type member will not get a correct address nasal_gc.get_scalar(addr).get_hash().set_self_addr(addr); std::list::iterator call_node=node.get_children().end(); for(std::list::iterator i=node.get_children().begin();i!=node.get_children().end();++i) @@ -153,6 +161,9 @@ int nasal_runtime::hash_generation(std::list >& local_ } else { + // note:how does nasal_function change the address of me when a hash calls it? + // because before calling this function,hash gives the address if itself as a parameter to the function, + // and this parameter's name is 'me' std::string member_name=i->get_children().front().get_var_string(); int var_type=i->get_children().back().get_node_type(); if(var_type==__number) @@ -164,12 +175,7 @@ int nasal_runtime::hash_generation(std::list >& local_ else if(var_type==__hash) nasal_gc.get_scalar(addr).get_hash().hash_push(member_name,hash_generation(local_scope,*i)); else if(var_type==__function) - { - // hash's function must get a parent_hash_addr - // this address will be given to identifier 'me' nasal_gc.get_scalar(addr).get_hash().hash_push(member_name,function_generation(local_scope,i->get_children().back())); - nasal_gc.get_scalar(nasal_gc.get_scalar(addr).get_hash().get_hash_member(member_name)).get_function().set_parent_hash_addr(addr); - } else if(var_type==__add_operator || var_type==__sub_operator || var_type==__mul_operator || var_type==__div_operator || var_type==__link_operator || var_type==__cmp_equal || var_type==__cmp_less || var_type==__cmp_more || var_type==__cmp_not_equal || var_type==__cmp_less_or_equal || var_type==__cmp_more_or_equal || var_type==__and_operator || var_type==__or_operator || var_type==__ques_mark || @@ -188,7 +194,11 @@ int nasal_runtime::function_generation(std::list >& lo int addr=nasal_gc.gc_alloc(); nasal_gc.get_scalar(addr).set_type(scalar_function); nasal_gc.get_scalar(addr).get_function().set_local_scope(local_scope); - // set + // function + // parameters + // block + // calls... + std::list::iterator i=node.get_children().begin(); return addr; } @@ -529,7 +539,12 @@ int nasal_runtime::calculation(std::list >& local_scop { std::vector data_addrs; for(std::list::iterator i=node.get_children().back().get_children().begin();i!=node.get_children().back().get_children().end();++i) - data_addrs.push_back(calculation(local_scope,*i)); + { + int new_addr=calculation(local_scope,*i); + if(new_addr<0) + return -1; + data_addrs.push_back(new_addr); + } if(data_addrs.size()!=assigned_addrs.size()) { error_interrupt(__multi_assign_incorrect_value_number,node.get_children().back().get_node_line()); @@ -576,6 +591,8 @@ int nasal_runtime::calculation(std::list >& local_scop else { int data_addr=calculation(local_scope,node.get_children().back()); + if(data_addr<0) + return -1; if(nasal_gc.get_scalar(data_addr).get_type()!=scalar_vector) { error_interrupt(__error_value_type,node.get_children().back().get_node_line()); @@ -592,7 +609,7 @@ int nasal_runtime::calculation(std::list >& local_scop int vector_member_addr=nasal_gc.get_scalar(data_addr).get_vector().get_elem(i); if(vector_member_addr<0) { - error_interrupt(__memory_overflow,node.get_children().back().get_node_line()); + error_interrupt(__invalid_vector_member,node.get_children().back().get_node_line()); return -1; } switch(nasal_gc.get_scalar(vector_member_addr).get_type()) @@ -636,6 +653,8 @@ int nasal_runtime::calculation(std::list >& local_scop if(!assigned_addr) return -1; int data_addr=calculation(local_scope,node.get_children().back()); + if(data_addr<0) + return -1; int new_data_addr=-1; nasal_gc.reference_delete(*assigned_addr); switch(nasal_gc.get_scalar(data_addr).get_type()) @@ -1083,7 +1102,7 @@ int nasal_runtime::call_identifier(std::list >& local_ } return addr; } -void nasal_runtime::definition(std::map& local_scope,abstract_syntax_tree& node) +void nasal_runtime::definition(std::list >&local_scope,std::map& now_scope,abstract_syntax_tree& node) { if(node.get_children().front().get_node_type()==__multi_id) { @@ -1091,7 +1110,42 @@ void nasal_runtime::definition(std::map& local_scope,abstract_s } 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; + int new_data_addr=-1; + switch(nasal_gc.get_scalar(data_addr).get_type()) + { + case scalar_nil: + new_data_addr=nasal_gc.gc_alloc(); + nasal_gc.get_scalar(new_data_addr).set_type(scalar_nil); + break; + case scalar_number: + new_data_addr=nasal_gc.gc_alloc(); + nasal_gc.get_scalar(new_data_addr).set_type(scalar_number); + nasal_gc.get_scalar(new_data_addr).get_number().deep_copy(nasal_gc.get_scalar(data_addr).get_number()); + break; + case scalar_string: + new_data_addr=nasal_gc.gc_alloc(); + nasal_gc.get_scalar(new_data_addr).set_type(scalar_string); + nasal_gc.get_scalar(new_data_addr).get_string().deep_copy(nasal_gc.get_scalar(data_addr).get_string()); + break; + case scalar_function: + new_data_addr=nasal_gc.gc_alloc(); + nasal_gc.get_scalar(new_data_addr).set_type(scalar_function); + nasal_gc.get_scalar(new_data_addr).get_function().deep_copy(nasal_gc.get_scalar(data_addr).get_function()); + break; + case scalar_vector: + case scalar_hash: + new_data_addr=data_addr; + nasal_gc.reference_add(new_data_addr); + break; + } + nasal_gc.reference_delete(data_addr); + now_scope[id_name]=new_data_addr; } return; } @@ -1116,6 +1170,9 @@ void nasal_runtime::loop_expr(std::list >& local_scope { ; } + for(std::map::iterator i=local_scope.back().begin();i!=local_scope.back().end();++i) + nasal_gc.reference_delete(i->second); + local_scope.pop_back(); return; } void nasal_runtime::conditional(std::list >& local_scope,abstract_syntax_tree& node) @@ -1132,6 +1189,9 @@ void nasal_runtime::conditional(std::list >& local_sco else ; } + for(std::map::iterator i=local_scope.back().begin();i!=local_scope.back().end();++i) + nasal_gc.reference_delete(i->second); + local_scope.pop_back(); return; } @@ -1170,7 +1230,7 @@ int nasal_runtime::func_proc(std::list >& local_scope, node_type==__equal || node_type==__add_equal || node_type==__sub_equal || node_type==__div_equal || node_type==__mul_equal || node_type==__link_equal) this->calculation(local_scope,*iter); else if(node_type==__definition) - this->definition(local_scope.back(),*iter); + this->definition(local_scope,local_scope.back(),*iter); else if(node_type==__conditional) this->conditional(local_scope,*iter); else if((node_type==__while) || (node_type==__for) || (node_type==__foreach) || (node_type==__forindex)) @@ -1217,7 +1277,7 @@ void nasal_runtime::main_proc(abstract_syntax_tree& root) node_type==__equal || node_type==__add_equal || node_type==__sub_equal || node_type==__div_equal || node_type==__mul_equal || node_type==__link_equal) this->calculation(main_local_scope,*iter); else if(node_type==__definition) - this->definition(global_scope,*iter); + this->definition(main_local_scope,global_scope,*iter); else if(node_type==__conditional) this->conditional(main_local_scope,*iter); else if((node_type==__while) || (node_type==__for) || (node_type==__foreach) || (node_type==__forindex))