From 2dc9f0c560a80ab5ade64ff2d8bc051ab528118d Mon Sep 17 00:00:00 2001 From: Valk Richard Li <48872266+ValKmjolnir@users.noreply.github.com> Date: Mon, 9 Mar 2020 01:38:23 +0800 Subject: [PATCH] update --- version2.0/nasal_gc.h | 94 ++++++++++++++++++---- version2.0/nasal_runtime.h | 160 +++++++++++++++++++++++++++++-------- 2 files changed, 203 insertions(+), 51 deletions(-) diff --git a/version2.0/nasal_gc.h b/version2.0/nasal_gc.h index d536d3e..f8ecd59 100644 --- a/version2.0/nasal_gc.h +++ b/version2.0/nasal_gc.h @@ -20,6 +20,7 @@ class nasal_function 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(); @@ -72,6 +73,7 @@ class nasal_hash void set_self_addr(int); void set_clear(); int get_self_addr(); + int get_hash_member(std::string); void hash_push(std::string,int); void hash_pop(std::string); void deep_copy(nasal_hash&); @@ -99,10 +101,11 @@ class nasal_scalar struct gc_unit { - // collected: If gc collected this item,it'll be set to true.Otherwise it is false. + // collected: If gc collected this item,it'll be set to true.Otherwise it is false. // elem: Item that this unit stores // refcnt: Reference counter bool collected; + bool is_const; nasal_scalar elem; int refcnt; gc_unit() @@ -150,12 +153,14 @@ class gc_manager } nasal_scalar& get_scalar(int addr) { + // get the reference of the scalar return memory[addr].elem; } bool place_check(const int place) { // check if this place is in memory // and this place is uncollected + // this function is often used when an identifier is calling a space in memory return (place >& tmp_scope) +{ + local_scope=tmp_scope; + for(std::list >::iterator iter=local_scope.begin();iter!=local_scope.end();++iter) + for(std::map::iterator i=iter->begin();i!=iter->end();++i) + nasal_gc.reference_add(i->second); + return; +} void nasal_function::set_statement_block(abstract_syntax_tree& func_block) { function_root=func_block; @@ -248,7 +261,31 @@ void nasal_function::set_statement_block(abstract_syntax_tree& func_block) } 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() @@ -265,27 +302,13 @@ void nasal_function::deep_copy(nasal_function& tmp) for(std::list >::iterator iter=local_scope.begin();iter!=local_scope.end();++iter) for(std::map::iterator i=iter->begin();i!=iter->end();++i) nasal_gc.reference_delete(i->second); + // when copying a local scope,one thing that must be noticed is that + // each identifier in local_scope shares the same address with tmp.local_scope // copy all the values in tmp's scope local_scope=tmp.local_scope; 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") nasal_gc.reference_add(i->second); - // change the 'me' address to this function's parent_hash_addr - if(!local_scope.empty()) - { - std::list >::iterator begin_iter=local_scope.begin(); - if(begin_iter->find("me")!=begin_iter->end()) - { - if(parent_hash_addr>=0) - { - (*begin_iter)["me"]=parent_hash_addr; - nasal_gc.reference_add(parent_hash_addr); - } - else - begin_iter->erase("me"); - } - } // copy abstract_syntax_tree function_root=tmp.function_root; return; @@ -401,6 +424,12 @@ int nasal_hash::get_self_addr() { return self_addr; } +int nasal_hash::get_hash_member(std::string member_name) +{ + if(nas_hash.find(member_name)!=nas_hash.end()) + return nas_hash[member_name]; + return -1; +} void nasal_hash::hash_push(std::string member_name,int addr) { if(nas_hash.find(member_name)==nas_hash.end()) @@ -467,27 +496,58 @@ void nasal_scalar::set_type(int tmp_type) } int nasal_scalar::get_type() { + // get scalar type return type; } nasal_number& nasal_scalar::get_number() { + // get nasal_number return var_number; } nasal_string& nasal_scalar::get_string() { + // get nasal_string return var_string; } nasal_vector& nasal_scalar::get_vector() { + // get nasal_vector return var_vector; } nasal_hash& nasal_scalar::get_hash() { + // get nasal_hash return var_hash; } nasal_function& nasal_scalar::get_function() { + // get nasal_function return var_func; } #endif + +/* +code: var i=1; +int addr=nasal_gc.gc_alloc(); +nasal_gc.get_scalar(addr).set_type(scalar_number); +nasal_gc.get_scalar(addr).set_number(1); + +code: var i='hello'; +int addr=nasal_gc.gc_alloc(); +nasal_gc.get_scalar(addr).set_type(scalar_string); +nasal_gc.get_scalar(addr).set_string("hello"); + +code: var i=[]; +int addr=vector_generation(); +nasal_gc.get_scalar(addr).set_type(scalar_vector); + +code: var i={}; +int addr=hash_generation(); +nasal_gc.get_scalar(addr).set_type(scalar_hash); +nasal_gc.get_scalar(addr).get_hash().set_self_addr(addr); + +code: var i=func{return 0;} +// copy local_scope if needed +// copy abstract_syntax_tree +*/ \ No newline at end of file diff --git a/version2.0/nasal_runtime.h b/version2.0/nasal_runtime.h index 582508a..dc92753 100644 --- a/version2.0/nasal_runtime.h +++ b/version2.0/nasal_runtime.h @@ -7,6 +7,7 @@ class nasal_runtime // global scope is a hash_map // main_local_scope is used in main block // when calling a loop or conditional expression + // when adding a new identifier into scope,you need to check if this identifier is already in the scope. std::map global_scope; std::list > main_local_scope; @@ -17,16 +18,20 @@ class nasal_runtime __incorrect_head_of_func, __stack_overflow, }; - void error_interrupt (const int); - void vector_generation (std::list >&,abstract_syntax_tree&); - void hash_generation (std::list >&,abstract_syntax_tree&); - void calculation (std::list >&,abstract_syntax_tree&); - void call_identifier (std::list >&,abstract_syntax_tree&); - void assignment (std::list >&,abstract_syntax_tree&); - void definition (std::list >&,abstract_syntax_tree&); - void loop_expr (std::list >&,abstract_syntax_tree&); - void conditional (std::list >&,abstract_syntax_tree&); - void func_proc (std::list >&,abstract_syntax_tree&); + int runtime_error_exit_mark; + void error_interrupt (const int); + int number_generation (abstract_syntax_tree&); + int string_generation (abstract_syntax_tree&); + int vector_generation (std::list >&,abstract_syntax_tree&); + int hash_generation (std::list >&,abstract_syntax_tree&); + int function_generation(std::list >&,abstract_syntax_tree&); + int calculation (std::list >&,abstract_syntax_tree&); + int call_identifier (std::list >&,abstract_syntax_tree&); + void assignment (std::list >&,abstract_syntax_tree&); + void definition (std::list >&,abstract_syntax_tree&); + void loop_expr (std::list >&,abstract_syntax_tree&); + void conditional (std::list >&,abstract_syntax_tree&); + void func_proc (std::list >&,abstract_syntax_tree&); public: nasal_runtime() { @@ -49,33 +54,117 @@ void nasal_runtime::error_interrupt(const int type) switch (type) { case __incorrect_head_of_tree: - std::cout< >& local_scope,abstract_syntax_tree& node) +int nasal_runtime::number_generation(abstract_syntax_tree& node) { - return; + int addr=nasal_gc.gc_alloc(); + nasal_gc.get_scalar(addr).set_type(scalar_number); + nasal_gc.get_scalar(addr).get_number().set_number(node.get_var_number()); + return addr; } -void nasal_runtime::hash_generation(std::list >& local_scope,abstract_syntax_tree& node) +int nasal_runtime::string_generation(abstract_syntax_tree& node) { - return; + int addr=nasal_gc.gc_alloc(); + nasal_gc.get_scalar(addr).set_type(scalar_string); + nasal_gc.get_scalar(addr).get_string().set_string(node.get_var_string()); + return addr; } -void nasal_runtime::calculation(std::list >& local_scope,abstract_syntax_tree& node) +int nasal_runtime::vector_generation(std::list >& local_scope,abstract_syntax_tree& node) { - return; + int addr=nasal_gc.gc_alloc(); + nasal_gc.get_scalar(addr).set_type(scalar_vector); + for(std::list::iterator i=node.get_children().begin();i!=node.get_children().end();++i) + { + int var_type=i->get_node_type(); + if(var_type==__number) + nasal_gc.get_scalar(addr).get_vector().vec_push(number_generation(*i)); + else if(var_type==__string) + nasal_gc.get_scalar(addr).get_vector().vec_push(string_generation(*i)); + else if(var_type==__vector) + nasal_gc.get_scalar(addr).get_vector().vec_push(vector_generation(local_scope,*i)); + else if(var_type==__hash) + nasal_gc.get_scalar(addr).get_vector().vec_push(hash_generation(local_scope,*i)); + else if(var_type==__function) + nasal_gc.get_scalar(addr).get_vector().vec_push(function_generation(local_scope,*i)); + else if(var_type==__id) + nasal_gc.get_scalar(addr).get_vector().vec_push(call_identifier(local_scope,*i)); + else + { + ; + } + } + return addr; } -void nasal_runtime::call_identifier(std::list >& local_scope,abstract_syntax_tree& node) +int nasal_runtime::hash_generation(std::list >& local_scope,abstract_syntax_tree& node) +{ + int addr=nasal_gc.gc_alloc(); + nasal_gc.get_scalar(addr).set_type(scalar_hash); + nasal_gc.get_scalar(addr).get_hash().set_self_addr(addr); + for(std::list::iterator i=node.get_children().begin();i!=node.get_children().end();++i) + { + if(i->get_node_type()!=__hash_member) + break; + else + { + 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) + ; + else if(var_type==__string) + ; + else if(var_type==__vector) + ; + else if(var_type==__hash) + ; + 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 + { + ; + } + } + } + return addr; +} +int nasal_runtime::function_generation(std::list >& local_scope,abstract_syntax_tree& node) +{ + 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); + nasal_gc.get_scalar(addr).get_function().set_statement_block(node); + return addr; +} +int nasal_runtime::calculation(std::list >& local_scope,abstract_syntax_tree& node) +{ + int operator_type=node.get_node_type(); + if(operator_type==__add_operator) + { + node.get_children().front(); + node.get_children().back(); + } + return -1; +} +int nasal_runtime::call_identifier(std::list >& local_scope,abstract_syntax_tree& node) { if(local_scope.empty()) ; - return; + return -1; } void nasal_runtime::assignment(std::list >& local_scope,abstract_syntax_tree& node) { @@ -131,21 +220,20 @@ void nasal_runtime::func_proc(std::list >& local_scope else if(node_type==__hash) this->hash_generation(local_scope,*iter); else if(node_type==__function) - { - ; - } + this->function_generation(local_scope,*iter); else if(node_type==__add_operator || node_type==__sub_operator || node_type==__mul_operator || node_type==__div_operator || node_type==__link_operator || node_type==__cmp_equal || node_type==__cmp_less || node_type==__cmp_more || node_type==__cmp_not_equal || node_type==__cmp_less_or_equal || node_type==__cmp_more_or_equal || - node_type==__and_operator || node_type==__or_operator || node_type==__ques_mark) + node_type==__and_operator || node_type==__or_operator || node_type==__ques_mark || + 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==__equal || node_type==__add_equal || node_type==__sub_equal || node_type==__div_equal || node_type==__mul_equal || node_type==__link_equal) - this->assignment(local_scope,*iter); else if(node_type==__definition) this->definition(local_scope,*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)) this->loop_expr(local_scope,*iter); + if(runtime_error_exit_mark>=0) + break; } return; } @@ -154,8 +242,13 @@ void nasal_runtime::main_proc(abstract_syntax_tree& root) { time_t begin_time,end_time; begin_time=std::time(NULL); + + // initializing global scope and nasal_gc + // runtime_error_exit_mark is set to -1,if runtime_error_exit_mark >=0,this means an error occurred global_scope.clear(); nasal_gc.gc_init(); + runtime_error_exit_mark=-1; + if(root.get_node_type()!=__root) { error_interrupt(__incorrect_head_of_tree); @@ -174,21 +267,20 @@ void nasal_runtime::main_proc(abstract_syntax_tree& root) else if(node_type==__hash) this->hash_generation(main_local_scope,*iter); else if(node_type==__function) - { - ; - } + this->function_generation(main_local_scope,*iter); else if(node_type==__add_operator || node_type==__sub_operator || node_type==__mul_operator || node_type==__div_operator || node_type==__link_operator || node_type==__cmp_equal || node_type==__cmp_less || node_type==__cmp_more || node_type==__cmp_not_equal || node_type==__cmp_less_or_equal || node_type==__cmp_more_or_equal || - node_type==__and_operator || node_type==__or_operator || node_type==__ques_mark) + node_type==__and_operator || node_type==__or_operator || node_type==__ques_mark || + 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==__equal || node_type==__add_equal || node_type==__sub_equal || node_type==__div_equal || node_type==__mul_equal || node_type==__link_equal) - this->assignment(main_local_scope,*iter); else if(node_type==__definition) this->definition(main_local_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)) this->loop_expr(main_local_scope,*iter); + if(runtime_error_exit_mark>=0) + break; } end_time=std::time(NULL);