add new functions
This commit is contained in:
parent
1d8408c13d
commit
bf8286d910
|
@ -4,8 +4,9 @@
|
|||
|
||||
|
||||
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
|
||||
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<var> 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<var> parameter,var self_func)
|
|||
ret.set_number(0);
|
||||
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
|
||||
{
|
||||
for(;para_name!=para.children.end();++para_name,++para_value)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -51,5 +51,6 @@ void alert_sound()
|
|||
int exit_type; // record the state of runtime
|
||||
std::stack<var> 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
|
||||
|
|
|
@ -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<str.length();++i)
|
||||
temp+=str[i];
|
||||
str=temp;
|
||||
}
|
||||
if(str.length()==1)
|
||||
return true;
|
||||
else if(str.length()==2 && '0'<str[0] && str[0]<='9' && '0'<=str[1] && str[1]<='9')
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
# this file includes functions:
|
||||
# append
|
||||
# subvec
|
||||
# this file includes basic operation functions:
|
||||
# append
|
||||
# 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...)
|
||||
{
|
||||
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 new_vector=[];
|
||||
|
@ -16,7 +22,15 @@ var subvec=func(vector,begin,length)
|
|||
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)
|
||||
{
|
||||
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);
|
||||
};
|
|
@ -1,13 +1,16 @@
|
|||
|
||||
# the function print is written by Cpp: std::cout
|
||||
# the function input is written by Cpp: std::cin
|
||||
# so the code is fake XD but the definitions are of great use
|
||||
# the definitions are set to avoid redefinition
|
||||
# made by github user: ValKmjolnir
|
||||
|
||||
# print function use dynamic parameters
|
||||
var print=func(args...)
|
||||
{
|
||||
return __call_cpp_ostream_std_cout(args);
|
||||
};
|
||||
|
||||
# the return type of input is __var_string
|
||||
var input=func()
|
||||
{
|
||||
return __call_cpp_istream_std_cin();
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# made by github user: ValKmjolnir
|
||||
|
||||
var pi=3.14159265358979;
|
||||
var ln_2=0.69314718055994530942;
|
||||
var ln_10=2.30258509299404568402;
|
||||
|
@ -41,6 +43,7 @@ var pow=func(__x,__num)
|
|||
else{return exp(__num*ln(__x));}
|
||||
};
|
||||
|
||||
# sigmoid function is a normal function used in neural networks
|
||||
var sigmoid=func(__x)
|
||||
{
|
||||
return 1.0/(1+exp(-__x));
|
||||
|
|
|
@ -12,7 +12,7 @@ int main()
|
|||
while(1)
|
||||
{
|
||||
std::cout<<">> ";
|
||||
std::getline(std::cin,command);
|
||||
std::cin>>command;
|
||||
if(command=="help")
|
||||
{
|
||||
std::cout<<">> Balloon interpreter by ValKmjolnir"<<std::endl;
|
||||
|
|
Loading…
Reference in New Issue