add new functions

This commit is contained in:
Valk Richard Li 2019-11-26 21:13:12 +08:00 committed by GitHub
parent 1d8408c13d
commit bf8286d910
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 123 additions and 10 deletions

View File

@ -4,8 +4,9 @@
int exit_type=0; int exit_type=0;
std::stack<var> ret_stack; // for function ret use std::stack<var> ret_stack; // for function ret use(especially the recursion)
int recursion_depth=0; // avoid deep recursion to sigsegv int recursion_depth=0; // avoid deep recursion to sigsegv
std::string str_for_input; // avoid stack overflow
var abstract_syntax_tree::calculation() var abstract_syntax_tree::calculation()
{ {
@ -889,6 +890,11 @@ var abstract_syntax_tree::run_func(std::list<var> parameter,var self_func)
} }
var ret; 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_block_scope();
scope.add_new_local_scope(); scope.add_new_local_scope();
@ -986,6 +992,71 @@ var abstract_syntax_tree::run_func(std::list<var> parameter,var self_func)
ret.set_number(0); ret.set_number(0);
ret_stack.push(ret); ret_stack.push(ret);
} }
else if(self_func.get_name()=="int")
{
if(!parameter.empty())
{
std::list<var>::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 "<<this->line<<": incorrect value type.must use a number."<<std::endl;
}
}
else
{
exit_type=__lack_parameter;
std::cout<<">>[Runtime-error] line "<<this->line<<": lack parameter(s)."<<std::endl;
}
// this must be added when running a function
if(exit_type!=__process_exited_successfully)
ret.set_type(__null_type);
ret_stack.push(ret);
}
else if(self_func.get_name()=="num")
{
if(!parameter.empty())
{
std::list<var>::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 "<<this->line<<": incorrect value type.must use a string that can be put into a number."<<std::endl;
}
}
else
{
exit_type=__lack_parameter;
std::cout<<">>[Runtime-error] line "<<this->line<<": lack parameter(s)."<<std::endl;
}
// this must be added when running a function
if(exit_type!=__process_exited_successfully)
ret.set_type(__null_type);
ret_stack.push(ret);
}
else if(self_func.get_name()=="input")
{
ret.set_type(__var_string);
str_for_input="";
std::cin>>str_for_input;
ret.set_string(str_for_input);
ret_stack.push(ret);
}
else else
{ {
for(;para_name!=para.children.end();++para_name,++para_value) for(;para_name!=para.children.end();++para_name,++para_value)

View File

@ -101,10 +101,16 @@ class abstract_syntax_tree
} }
void set_number(std::string _str) void set_number(std::string _str)
{ {
if(_str=="nil") bool is_negative=false;
if(_str.length()>1 && _str[0]=='-')
{ {
number=0; // this statements only used in input
return; // 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')) if((int)_str.length()>2 && (_str[1]=='x' || _str[1]=='o'))
{ {
@ -128,6 +134,8 @@ class abstract_syntax_tree
pw*=8; pw*=8;
} }
number=num; number=num;
if(is_negative)
number*=-1;
return; return;
} }
int dot_place=-1; int dot_place=-1;
@ -146,6 +154,8 @@ class abstract_syntax_tree
number+=(_str[i]-'0')*pw; number+=(_str[i]-'0')*pw;
pw*=10; pw*=10;
} }
if(is_negative)
number*=-1;
} }
else else
{ {
@ -162,6 +172,8 @@ class abstract_syntax_tree
number+=(_str[i]-'0')*pw; number+=(_str[i]-'0')*pw;
pw*=10; pw*=10;
} }
if(is_negative)
number*=-1;
} }
return; return;
} }

View File

@ -51,5 +51,6 @@ void alert_sound()
int exit_type; // record the state of runtime int exit_type; // record the state of runtime
std::stack<var> ret_stack; // for function ret use std::stack<var> ret_stack; // for function ret use
int recursion_depth; // avoid too deep recursion int recursion_depth; // avoid too deep recursion
std::string str_for_input // global value str to avoid stack overflow
*/ */
#endif #endif

View File

@ -25,6 +25,15 @@ int is_reserve_word(std::string str)
*/ */
bool check_number(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<str.length();++i)
temp+=str[i];
str=temp;
}
if(str.length()==1) if(str.length()==1)
return true; return true;
else if(str.length()==2 && '0'<str[0] && str[0]<='9' && '0'<=str[1] && str[1]<='9') else if(str.length()==2 && '0'<str[0] && str[0]<='9' && '0'<=str[1] && str[1]<='9')

View File

@ -1,11 +1,17 @@
# this file includes functions: # this file includes basic operation functions:
# append # append
# subvec # subvec
# int
# num
# made by github user: ValKmjolnir
# append is used to add a new var into an array/vector
var append=func(vector,elements...) var append=func(vector,elements...)
{ {
return __call_special_inline_function(vector,elements); return __call_special_inline_function(vector,elements);
}; };
# subvec is used to get a new array from an exist array
var subvec=func(vector,begin,length) var subvec=func(vector,begin,length)
{ {
var new_vector=[]; var new_vector=[];
@ -16,7 +22,15 @@ var subvec=func(vector,begin,length)
return new_vector; return new_vector;
}; };
# int function is used to transfer double var into int var
# the normal type of number in balloon script is double
var int=func(value) var int=func(value)
{ {
return __call_Cpp_int(value); return __Cpp_inline_var_to_int(value);
};
# num function is used to translate a string into a number
var num=func(value)
{
return __call_Cpp_type_trans_num(value);
}; };

View File

@ -1,13 +1,16 @@
# the function print is written by Cpp: std::cout # the function print is written by Cpp: std::cout
# the function input is written by Cpp: std::cin # the function input is written by Cpp: std::cin
# so the code is fake XD but the definitions are of great use # so the code is fake XD but the definitions are of great use
# the definitions are set to avoid redefinition # the definitions are set to avoid redefinition
# made by github user: ValKmjolnir
# print function use dynamic parameters
var print=func(args...) var print=func(args...)
{ {
return __call_cpp_ostream_std_cout(args); return __call_cpp_ostream_std_cout(args);
}; };
# the return type of input is __var_string
var input=func() var input=func()
{ {
return __call_cpp_istream_std_cin(); return __call_cpp_istream_std_cin();

View File

@ -1,3 +1,5 @@
# made by github user: ValKmjolnir
var pi=3.14159265358979; var pi=3.14159265358979;
var ln_2=0.69314718055994530942; var ln_2=0.69314718055994530942;
var ln_10=2.30258509299404568402; var ln_10=2.30258509299404568402;
@ -41,6 +43,7 @@ var pow=func(__x,__num)
else{return exp(__num*ln(__x));} else{return exp(__num*ln(__x));}
}; };
# sigmoid function is a normal function used in neural networks
var sigmoid=func(__x) var sigmoid=func(__x)
{ {
return 1.0/(1+exp(-__x)); return 1.0/(1+exp(-__x));

View File

@ -12,7 +12,7 @@ int main()
while(1) while(1)
{ {
std::cout<<">> "; std::cout<<">> ";
std::getline(std::cin,command); std::cin>>command;
if(command=="help") if(command=="help")
{ {
std::cout<<">> Balloon interpreter by ValKmjolnir"<<std::endl; std::cout<<">> Balloon interpreter by ValKmjolnir"<<std::endl;