diff --git a/balloon/abstract_syntax_tree.cpp b/balloon/abstract_syntax_tree.cpp index e6dc5fb..272d23e 100644 --- a/balloon/abstract_syntax_tree.cpp +++ b/balloon/abstract_syntax_tree.cpp @@ -5,6 +5,7 @@ int exit_type=0; std::stack ret_stack;// for function ret use +std::list parameter;// for function call use var abstract_syntax_tree::calculation() { @@ -39,7 +40,7 @@ var abstract_syntax_tree::calculation() } else if(this->type==__function) { - temp.set_type(__function); + temp.set_type(__var_function); temp.set_function(*this); return temp; } @@ -384,7 +385,9 @@ var abstract_syntax_tree::calculation() else { exit_type=__error_value_type; - std::cout<<">>[Runtime-error] line "<>[Runtime-error] line "<type); + std::cout<<"\' occurred when doing calculation."<type==__call_function && temp.get_type()==__var_function) + { + parameter.clear(); + for(std::list::iterator j=i->children.begin();j!=i->children.end();++j) + parameter.push_back(j->calculation()); temp=temp.get_function().run_func(); + } else { exit_type=__error_value_type; @@ -460,6 +468,7 @@ var abstract_syntax_tree::call_identifier() std::cout<<": incorrect type \'"; print_scalar(temp.get_type()); std::cout<<"\'."<::iterator i=children.begin();i!=children.end();++i) - { - new_var=i->get_value(); - temp.append_array(new_var); - } - } - else if(type==__hash) - { - var new_var; - for(std::list::iterator i=children.begin();i!=children.end();++i) - { - new_var=i->children.begin()->get_value(); - new_var.set_name(i->name); - temp.append_array(new_var); - } - } - else if(type==__function) - temp.set_function(*this); + var* addr=&error_var; + if(scope.search_var(name)) + addr=scope.get_addr(name); else { - std::cout<<">>[Runtime-error] line "<>[Runtime-error] line "<::iterator i=children.begin();i!=children.end();++i) + { + if(i->type==__call_array && addr->get_type()==__var_array) + { + var place=i->children.front().calculation(); + if(place.get_type()==__var_number) + addr=addr->get_array_member_addr((int)place.get_number()); + else + { + exit_type=__error_value_type; + std::cout<<">>[Runtime-error] line "<type); + std::cout<<": incorrect type \'"; + print_scalar(addr->get_type()); + std::cout<<"\'."<type==__call_hash && addr->get_type()==__var_hash) + { + addr=addr->get_hash_member_addr(i->name); + if(addr->get_type()==__null_type) + { + exit_type=__get_value_failure; + std::cout<<">>[Runtime-error] line "<name<<"\'."<type==__call_function && addr->get_type()==__var_function) + { + exit_type=__error_value_type; + std::cout<<">>[Runtime-error] line "<>[Runtime-error] line "<type); + std::cout<<": incorrect type \'"; + print_scalar(addr->get_type()); + std::cout<<"\'."<get_name(); + *addr=temp; + addr->set_name(tname); + } + else if(type==__add_equal || type==__sub_equal || type==__mul_equal || type==__div_equal) + { + if(addr->get_type()==__var_number && temp.get_type()==__var_number) + { + switch(type) + { + case __add_equal:addr->set_number(addr->get_number()+temp.get_number());break; + case __sub_equal:addr->set_number(addr->get_number()-temp.get_number());break; + case __mul_equal:addr->set_number(addr->get_number()*temp.get_number());break; + case __div_equal:addr->set_number(addr->get_number()/temp.get_number());break; + } + if(std::isnan(addr->get_number()) || std::isinf(addr->get_number())) + { + exit_type=__sigfpe_arithmetic_exception; + std::cout<<">>[Runtime-error] line "<>[Runtime-error] line "<get_type()); + std::cout<<"\' and \'"; + print_scalar(temp.get_type()); + std::cout<<"\' but this operator "; + print_detail_token(type); + std::cout<<" must use \'number\' and \'number\'."<get_type()==__var_string && temp.get_type()==__string) + addr->set_string(addr->get_string()+temp.get_string()); + else + { + exit_type=__error_value_type; + std::cout<<">>[Runtime-error] line "<get_type()); + std::cout<<"\' and \'"; + print_scalar(temp.get_type()); + std::cout<<"\' but this operator ~ must use \'string\' and \'string\'."<type==__equal || i->type==__add_equal || i->type==__sub_equal || i->type==__mul_equal || i->type==__div_equal || i->type==__link_equal) - { - ; - } + i->assignment(); else if(i->type==__add_operator || i->type==__sub_operator || i->type==__mul_operator || i->type==__div_operator || i->type==__link_operator || i->type==__or_operator || i->type==__and_operator || i->type==__nor_operator) { var t=i->calculation(); @@ -599,7 +694,7 @@ void abstract_syntax_tree::run_root() break; } end_time=time(NULL); - std::cout<<"--------------------------------------------------------------------------------------"<>[Runtime] process exited after "<::iterator para_name=para.children.begin(); + std::list::iterator para_value=parameter.begin(); + + for(;para_name!=para.children.end();++para_name,++para_value) + { + if(para_value==parameter.end() && para_name!=para.children.end()) + { + exit_type=__lack_parameter; + std::cout<<">>[Runtime-error] line "<name); + scope.add_new_var(new_var); + } + if(exit_type==__process_exited_successfully) + { + int _t=blk.run_block(); + if(_t!=__return) + ret_stack.push(error_var); + } + + else + ret_stack.push(error_var); //get return scope.pop_last_block_scope(); ret=ret_stack.top(); ret_stack.pop(); + return ret; } @@ -702,9 +825,7 @@ int abstract_syntax_tree::run_block() std::cout<type==__equal || i->type==__add_equal || i->type==__sub_equal || i->type==__mul_equal || i->type==__div_equal || i->type==__link_equal) - { - ; - } + i->assignment(); else if(i->type==__add_operator || i->type==__sub_operator || i->type==__mul_operator || i->type==__div_operator || i->type==__link_operator || i->type==__or_operator || i->type==__and_operator || i->type==__nor_operator) { var t=i->calculation(); @@ -742,7 +863,7 @@ int abstract_syntax_tree::run_block() var temp; temp.set_type(__null_type); if(!(i->children.empty())) - temp=i->calculation(); + temp=i->children.front().calculation(); ret_stack.push(temp); return __return; } diff --git a/balloon/abstract_syntax_tree.h b/balloon/abstract_syntax_tree.h index 93cefb0..6ba54e8 100644 --- a/balloon/abstract_syntax_tree.h +++ b/balloon/abstract_syntax_tree.h @@ -203,7 +203,8 @@ class abstract_syntax_tree var call_identifier(); var array_generation(); var hash_generation(); - var get_value(); + var* get_var_addr(); + var assignment(); void run_root(); int run_loop(); int run_ifelse(); diff --git a/balloon/balloon_scope.h b/balloon/balloon_scope.h index b779078..aeb09c9 100644 --- a/balloon/balloon_scope.h +++ b/balloon/balloon_scope.h @@ -72,6 +72,37 @@ class balloon_scope } return error_var; } + var* get_addr(std::string name) + { + var* addr=NULL; + if(!scope_list.empty()) + { + std::list >::iterator i=scope_list.back().end(); + --i; + // get the last scope block(std::list >) + for(;;--i) + { + for(std::list::iterator j=i->begin();j!=i->end();++j) + if(j->get_name()==name) + { + addr=&(*j); + return addr; + } + if(i==scope_list.back().begin()) + break; + } + } + if(!global.empty()) + { + for(std::list::iterator i=global.begin();i!=global.end();++i) + if(i->get_name()==name) + { + addr=&(*i); + return addr; + } + } + return &error_var; + } void add_new_block_scope() { std::list > new_list; diff --git a/balloon/balloon_type.h b/balloon/balloon_type.h index d1b14db..ff282a9 100644 --- a/balloon/balloon_type.h +++ b/balloon/balloon_type.h @@ -148,7 +148,8 @@ enum runtime_error_type __error_command_use, __sigfpe_arithmetic_exception, __sigsegv_segmentation_error, - __terminal_interrupt + __terminal_interrupt, + __lack_parameter, }; void print_exit_type(int type) @@ -162,9 +163,10 @@ void print_exit_type(int type) case __find_var_failure: context="find_var_failure";break; case __error_value_type: context="value_type_error";break; case __error_command_use: context="command_use_error(continue/break/return)";break; - case __sigfpe_arithmetic_exception: context="SIGFPE";break; - case __sigsegv_segmentation_error: context="SIGSEGV";break; + case __sigfpe_arithmetic_exception: context="SIGFPE_arithmetic_exception";break; + case __sigsegv_segmentation_error: context="SIGSEGV_segmentation_error";break; case __terminal_interrupt: context="interrupt";break; + case __lack_parameter: context="lack_parameter(s)";break; default: context="unknown";break; } std::cout<>[Runtime-error] overflow when searching member "<<_place<<" but the max size of array \'"<::iterator i=balloon_array.begin();i!=balloon_array.end();++i,++cnt) + if(cnt==_place) + { + addr=&(*i); + return addr; + } + std::cout<<">>[Runtime-error] overflow when searching member "<<_place<<" but the max size of array \'"<::iterator i=balloon_hash.begin();i!=balloon_hash.end();++i) @@ -179,6 +200,19 @@ var& var::get_hash_member(std::string _name) return error_var; } +var* var::get_hash_member_addr(std::string _name) +{ + var* addr=NULL; + for(std::list::iterator i=balloon_hash.begin();i!=balloon_hash.end();++i) + if(i->name==_name) + { + addr=&(*i); + return addr; + } + std::cout<<">>[Runtime-error] hash \'"<