From bf8286d910d871f75c59ab77f2696c0a0252f8ec Mon Sep 17 00:00:00 2001 From: Valk Richard Li <48872266+ValKmjolnir@users.noreply.github.com> Date: Tue, 26 Nov 2019 21:13:12 +0800 Subject: [PATCH] add new functions --- balloon/abstract_syntax_tree.cpp | 73 +++++++++++++++++++++++++++++++- balloon/abstract_syntax_tree.h | 18 ++++++-- balloon/balloon.h | 1 + balloon/balloon_lexer.h | 9 ++++ balloon/lib/basics.nas | 22 ++++++++-- balloon/lib/io.nas | 5 ++- balloon/lib/math.nas | 3 ++ balloon/main.cpp | 2 +- 8 files changed, 123 insertions(+), 10 deletions(-) diff --git a/balloon/abstract_syntax_tree.cpp b/balloon/abstract_syntax_tree.cpp index bc55e08..af2e963 100644 --- a/balloon/abstract_syntax_tree.cpp +++ b/balloon/abstract_syntax_tree.cpp @@ -4,8 +4,9 @@ int exit_type=0; -std::stack ret_stack; // for function ret use +std::stack ret_stack; // for function ret use(especially the recursion) int recursion_depth=0; // avoid deep recursion to sigsegv +std::string str_for_input; // avoid stack overflow var abstract_syntax_tree::calculation() { @@ -889,6 +890,11 @@ var abstract_syntax_tree::run_func(std::list parameter,var self_func) } var ret; + // ret is used to return function's value + // ret must be pushed into stack:ret_stack + // ret_stack is used for recursion + // before each function ends,a var will be poped from stack + // and the ret will be set as this poped var. scope.add_new_block_scope(); scope.add_new_local_scope(); @@ -986,6 +992,71 @@ var abstract_syntax_tree::run_func(std::list parameter,var self_func) ret.set_number(0); ret_stack.push(ret); } + else if(self_func.get_name()=="int") + { + if(!parameter.empty()) + { + std::list::iterator i=parameter.begin(); + if(i->get_type()==__var_number) + { + int temp; + temp=(int)(i->get_number()); + ret.set_type(__var_number); + ret.set_number((double)temp); + } + else + { + exit_type=__error_value_type; + std::cout<<">>[Runtime-error] line "<line<<": incorrect value type.must use a number."<>[Runtime-error] line "<line<<": lack parameter(s)."<::iterator i=parameter.begin(); + if(i->get_type()==__var_string && check_number(i->get_string())) + { + std::string str=i->get_string(); + ret.set_type(__var_number); + // use this->set_number to help trans the str to number + this->set_number(str); + ret.set_number(this->number); + } + else + { + exit_type=__error_value_type; + std::cout<<">>[Runtime-error] line "<line<<": incorrect value type.must use a string that can be put into a number."<>[Runtime-error] line "<line<<": lack parameter(s)."<>str_for_input; + ret.set_string(str_for_input); + ret_stack.push(ret); + } else { for(;para_name!=para.children.end();++para_name,++para_value) diff --git a/balloon/abstract_syntax_tree.h b/balloon/abstract_syntax_tree.h index 1eee1aa..8c80caa 100644 --- a/balloon/abstract_syntax_tree.h +++ b/balloon/abstract_syntax_tree.h @@ -101,10 +101,16 @@ class abstract_syntax_tree } void set_number(std::string _str) { - if(_str=="nil") + bool is_negative=false; + if(_str.length()>1 && _str[0]=='-') { - number=0; - return; + // this statements only used in input + // but in parse this statements are useless + std::string temp=""; + for(int i=1;i<_str.length();++i) + temp+=_str[i]; + _str=temp; + is_negative=true; } if((int)_str.length()>2 && (_str[1]=='x' || _str[1]=='o')) { @@ -128,6 +134,8 @@ class abstract_syntax_tree pw*=8; } number=num; + if(is_negative) + number*=-1; return; } int dot_place=-1; @@ -146,6 +154,8 @@ class abstract_syntax_tree number+=(_str[i]-'0')*pw; pw*=10; } + if(is_negative) + number*=-1; } else { @@ -162,6 +172,8 @@ class abstract_syntax_tree number+=(_str[i]-'0')*pw; pw*=10; } + if(is_negative) + number*=-1; } return; } diff --git a/balloon/balloon.h b/balloon/balloon.h index ff407d2..91325ce 100644 --- a/balloon/balloon.h +++ b/balloon/balloon.h @@ -51,5 +51,6 @@ void alert_sound() int exit_type; // record the state of runtime std::stack ret_stack; // for function ret use int recursion_depth; // avoid too deep recursion + std::string str_for_input // global value str to avoid stack overflow */ #endif diff --git a/balloon/balloon_lexer.h b/balloon/balloon_lexer.h index d286a2f..fd9d92d 100644 --- a/balloon/balloon_lexer.h +++ b/balloon/balloon_lexer.h @@ -25,6 +25,15 @@ int is_reserve_word(std::string str) */ bool check_number(std::string str) { + if(str.length()>1 && str[0]=='-') + { + // this statements only used in input + // but in lexer this statements are useless + std::string temp=""; + for(int i=1;i> "; - std::getline(std::cin,command); + std::cin>>command; if(command=="help") { std::cout<<">> Balloon interpreter by ValKmjolnir"<