This commit is contained in:
Valk Richard Li 2020-03-12 17:56:24 +08:00 committed by GitHub
parent 954f3bab63
commit e8ed4d6e58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 349 additions and 15 deletions

View File

@ -191,6 +191,7 @@ void nasal_parse::check_semi()
return;
else if(this_token.type==__right_brace)
{
// this make func{return 0} as correct
this->push_token();
return;
}
@ -310,10 +311,16 @@ bool nasal_parse::check_function_end(abstract_syntax_tree& tmp)
{
if(!tmp.get_children().empty())
{
if(tmp.get_children().back().get_node_type()==__function)
return true;
// func{}()
// function
// parameters
// block <- if the last child is __normal_statement_block,then don't need semi check
// call_function
if(tmp.get_children().back().get_node_type()==__function &&
tmp.get_children().back().get_children().back().get_node_type()==__normal_statement_block)
return true;// func{}() should have a ';'
else
return check_function_end(tmp.get_children().back());
return check_function_end(tmp.get_children().back());// var a=b=c=d=e=f=g=func{}
}
return false;
}
@ -528,6 +535,8 @@ abstract_syntax_tree nasal_parse::block_generate()
print_parse_error(error_token_in_block,this_token.line,this_token.type);
break;
}
// why the last statement can avoid semi check()?
// see more details in function: check_semi()
if(need_semi_check)
check_semi();
this->get_token();

View File

@ -181,7 +181,8 @@ int nasal_runtime::function_generation(std::list<std::map<std::string,int> >& lo
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);
// set
return addr;
}
int nasal_runtime::calculation(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
@ -199,7 +200,14 @@ int nasal_runtime::calculation(std::list<std::map<std::string,int> >& local_scop
else if(node_type==__function)
return function_generation(local_scope,node);
else if(node_type==__id)
return call_identifier(local_scope,node);
{
int ret=call_identifier(local_scope,node);
nasal_gc.reference_add(ret);
return ret;
// returned address is not a temporary one
// but after each calculation,the refcnt will -1
// so refcnt++ here
}
else if(node_type==__add_operator || node_type==__sub_operator || node_type==__mul_operator || node_type==__div_operator)
{
// scalar_nil cannot be used here
@ -239,7 +247,7 @@ int nasal_runtime::calculation(std::list<std::map<std::string,int> >& local_scop
num_2=trans_string_to_number(tmp_str);
else
{
error_interrupt(__not_numerable_str,node.get_node_line());
error_interrupt(__not_numerable_str,node.get_children().back().get_node_line());
return -1;
}
}
@ -251,7 +259,7 @@ int nasal_runtime::calculation(std::list<std::map<std::string,int> >& local_scop
num_1=trans_string_to_number(tmp_str);
else
{
error_interrupt(__not_numerable_str,node.get_node_line());
error_interrupt(__not_numerable_str,node.get_children().front().get_node_line());
return -1;
}
}
@ -494,23 +502,340 @@ int nasal_runtime::calculation(std::list<std::map<std::string,int> >& local_scop
{
;
}
else if(node_type==__add_equal || node_type==__sub_equal || node_type==__mul_equal || node_type==__div_equal || node_type==__link_equal)
else if(node_type==__add_equal || node_type==__sub_equal || node_type==__mul_equal || node_type==__div_equal)
{
// scalar_nil also cannot be used here
int id_addr=call_identifier(local_scope,node.get_children().front());
// += -= *= /= ~= only works on scalar_number and scalar_string
int id_addr=calculation(local_scope,node.get_children().front());
int value_addr=calculation(local_scope,node.get_children().back());
if(id_addr<0 || value_addr<0)
return -1;
int type_1=nasal_gc.get_scalar(id_addr).get_type();
int type_2=nasal_gc.get_scalar(value_addr).get_type();
if(type_1==scalar_number && type_2==scalar_number)
{
double num_1=nasal_gc.get_scalar(id_addr).get_number().get_number();
double num_2=nasal_gc.get_scalar(value_addr).get_number().get_number();
switch(node_type)
{
case __add_equal:nasal_gc.get_scalar(id_addr).get_number().set_number(num_1+num_2);break;
case __sub_equal:nasal_gc.get_scalar(id_addr).get_number().set_number(num_1-num_2);break;
case __mul_equal:nasal_gc.get_scalar(id_addr).get_number().set_number(num_1*num_2);break;
case __div_equal:nasal_gc.get_scalar(id_addr).get_number().set_number(num_1/num_2);break;
}
}
else if(type_1==scalar_number && type_2==scalar_string)
{
double num_1=nasal_gc.get_scalar(id_addr).get_number().get_number();
double num_2=0;
std::string tmp_str=nasal_gc.get_scalar(value_addr).get_string().get_string();
if(check_numerable_string(tmp_str))
num_2=trans_string_to_number(tmp_str);
else
{
error_interrupt(__not_numerable_str,node.get_children().back().get_node_line());
return -1;
}
switch(node_type)
{
case __add_equal:nasal_gc.get_scalar(id_addr).get_number().set_number(num_1+num_2);break;
case __sub_equal:nasal_gc.get_scalar(id_addr).get_number().set_number(num_1-num_2);break;
case __mul_equal:nasal_gc.get_scalar(id_addr).get_number().set_number(num_1*num_2);break;
case __div_equal:nasal_gc.get_scalar(id_addr).get_number().set_number(num_1/num_2);break;
}
}
else if(type_1==scalar_string && type_2==scalar_number)
{
double num_1=0;
double num_2=nasal_gc.get_scalar(value_addr).get_number().get_number();
std::string tmp_str=nasal_gc.get_scalar(id_addr).get_string().get_string();
if(check_numerable_string(tmp_str))
num_1=trans_string_to_number(tmp_str);
else
{
error_interrupt(__not_numerable_str,node.get_children().front().get_node_line());
return -1;
}
nasal_gc.get_scalar(id_addr).get_string().set_clear();
nasal_gc.get_scalar(id_addr).set_type(scalar_number);
switch(node_type)
{
case __add_equal:nasal_gc.get_scalar(id_addr).get_number().set_number(num_1+num_2);break;
case __sub_equal:nasal_gc.get_scalar(id_addr).get_number().set_number(num_1-num_2);break;
case __mul_equal:nasal_gc.get_scalar(id_addr).get_number().set_number(num_1*num_2);break;
case __div_equal:nasal_gc.get_scalar(id_addr).get_number().set_number(num_1/num_2);break;
}
}
else if(type_1==scalar_string && type_2==scalar_string)
{
double num_1=0;
double num_2=0;
std::string tmp_str_1=nasal_gc.get_scalar(id_addr).get_string().get_string();
std::string tmp_str_2=nasal_gc.get_scalar(value_addr).get_string().get_string();
if(check_numerable_string(tmp_str_1) && check_numerable_string(tmp_str_2))
{
num_1=trans_string_to_number(tmp_str_1);
num_2=trans_string_to_number(tmp_str_2);
}
else
{
error_interrupt(__not_numerable_str,node.get_node_line());
return -1;
}
nasal_gc.get_scalar(id_addr).get_string().set_clear();
nasal_gc.get_scalar(id_addr).set_type(scalar_number);
switch(node_type)
{
case __add_equal:nasal_gc.get_scalar(id_addr).get_number().set_number(num_1+num_2);break;
case __sub_equal:nasal_gc.get_scalar(id_addr).get_number().set_number(num_1-num_2);break;
case __mul_equal:nasal_gc.get_scalar(id_addr).get_number().set_number(num_1*num_2);break;
case __div_equal:nasal_gc.get_scalar(id_addr).get_number().set_number(num_1/num_2);break;
}
}
else
{
error_interrupt(__error_value_type,node.get_node_line());
return -1;
}
nasal_gc.reference_delete(value_addr);
return id_addr;
}
else if(node_type==__and_operator || node_type==__or_operator || node_type==__nor_operator)
else if(node_type==__link_equal)
{
// scalar_nil also cannot be used here
// += -= *= /= ~= only works on scalar_number and scalar_string
int id_addr=calculation(local_scope,node.get_children().front());
int value_addr=calculation(local_scope,node.get_children().back());
if(id_addr<0 || value_addr<0)
return -1;
int type_1=nasal_gc.get_scalar(id_addr).get_type();
int type_2=nasal_gc.get_scalar(value_addr).get_type();
double num_1,num_2;
std::string str_1,str_2;
if(type_1==scalar_number && type_2==scalar_number)
{
num_1=nasal_gc.get_scalar(id_addr).get_number().get_number();
num_2=nasal_gc.get_scalar(value_addr).get_number().get_number();
str_1=trans_number_to_string(num_1);
str_2=trans_number_to_string(num_2);
nasal_gc.get_scalar(id_addr).get_number().set_clear();
nasal_gc.get_scalar(id_addr).set_type(scalar_string);
nasal_gc.get_scalar(id_addr).get_string().set_string(str_1+str_2);
}
else if(type_1==scalar_number && type_2==scalar_string)
{
num_1=nasal_gc.get_scalar(id_addr).get_number().get_number();
str_1=trans_number_to_string(num_1);
str_2=nasal_gc.get_scalar(value_addr).get_string().get_string();
nasal_gc.get_scalar(id_addr).get_number().set_clear();
nasal_gc.get_scalar(id_addr).set_type(scalar_string);
nasal_gc.get_scalar(id_addr).get_string().set_string(str_1+str_2);
}
else if(type_1==scalar_string && type_2==scalar_number)
{
num_2=nasal_gc.get_scalar(value_addr).get_number().get_number();
str_1=nasal_gc.get_scalar(id_addr).get_string().get_string();
str_2=trans_number_to_string(num_2);
nasal_gc.get_scalar(id_addr).get_string().set_string(str_1+str_2);
}
else if(type_1==scalar_string && type_2==scalar_string)
{
str_1=nasal_gc.get_scalar(id_addr).get_string().get_string();
str_2=nasal_gc.get_scalar(value_addr).get_string().get_string();
nasal_gc.get_scalar(id_addr).get_string().set_string(str_1+str_2);
}
else
{
error_interrupt(__error_value_type,node.get_node_line());
return -1;
}
nasal_gc.reference_delete(value_addr);
return id_addr;
}
else if(node_type==__and_operator)
{
// and will return the last value that is not null
// if and gets a null,and returns 0
// vector,hash,function is not allowed here
int ret_addr=-1;
int addr=calculation(local_scope,node.get_children().front());
if(addr<0)
return -1;
int type=nasal_gc.get_scalar(addr).get_type();
if(type==scalar_number)
{
double num=nasal_gc.get_scalar(addr).get_number().get_number();
if(num==0)
{
ret_addr=nasal_gc.gc_alloc();
nasal_gc.get_scalar(ret_addr).set_type(scalar_number);
nasal_gc.get_scalar(ret_addr).get_number().set_number(0);
nasal_gc.reference_delete(addr);
return ret_addr;
}
else
nasal_gc.reference_delete(addr);
}
else if(type==scalar_string)
{
std::string str=nasal_gc.get_scalar(addr).get_string().get_string();
if(str.length()==0 || (check_numerable_string(str) && trans_string_to_number(str)==0))
{
ret_addr=nasal_gc.gc_alloc();
nasal_gc.get_scalar(ret_addr).set_type(scalar_number);
nasal_gc.get_scalar(ret_addr).get_number().set_number(0);
nasal_gc.reference_delete(addr);
return ret_addr;
}
else
nasal_gc.reference_delete(addr);
}
else
{
error_interrupt(__error_value_type,node.get_children().front().get_node_line());
return -1;
}
addr=calculation(local_scope,node.get_children().back());
if(addr<0)
return -1;
type=nasal_gc.get_scalar(addr).get_type();
if(type==scalar_number)
{
double num=nasal_gc.get_scalar(addr).get_number().get_number();
if(num==0)
{
ret_addr=nasal_gc.gc_alloc();
nasal_gc.get_scalar(ret_addr).set_type(scalar_number);
nasal_gc.get_scalar(ret_addr).get_number().set_number(0);
nasal_gc.reference_delete(addr);
return ret_addr;
}
else
ret_addr=addr;
}
else if(type==scalar_string)
{
std::string str=nasal_gc.get_scalar(addr).get_string().get_string();
if(str.length()==0 || (check_numerable_string(str) && trans_string_to_number(str)==0))
{
ret_addr=nasal_gc.gc_alloc();
nasal_gc.get_scalar(ret_addr).set_type(scalar_number);
nasal_gc.get_scalar(ret_addr).get_number().set_number(0);
nasal_gc.reference_delete(addr);
return ret_addr;
}
else
ret_addr=addr;
}
else
{
error_interrupt(__error_value_type,node.get_children().front().get_node_line());
return -1;
}
return ret_addr;
}
else if(node_type==__or_operator)
{
// or will return the first value that is not null
// and will return the last value that is not null
// if or gets all null(0,'0',nil,"0",'',""),or returns 0
// vector,hash,function is not allowed here
int ret_addr=-1;
int addr=calculation(local_scope,node.get_children().front());
if(addr<0)
return -1;
int type=nasal_gc.get_scalar(addr).get_type();
if(type==scalar_number)
{
double num=nasal_gc.get_scalar(addr).get_number().get_number();
if(num!=0)
return addr;
else
nasal_gc.reference_delete(addr);
}
else if(type==scalar_string)
{
std::string str=nasal_gc.get_scalar(addr).get_string().get_string();
if(str.length()!=0 && (!check_numerable_string(str) || !trans_string_to_number(str)==0))
return addr;
else
nasal_gc.reference_delete(addr);
}
else
{
error_interrupt(__error_value_type,node.get_children().front().get_node_line());
return -1;
}
addr=calculation(local_scope,node.get_children().back());
if(addr<0)
return -1;
type=nasal_gc.get_scalar(addr).get_type();
if(type==scalar_number)
{
double num=nasal_gc.get_scalar(addr).get_number().get_number();
if(num==0)
{
ret_addr=nasal_gc.gc_alloc();
nasal_gc.get_scalar(ret_addr).set_type(scalar_number);
nasal_gc.get_scalar(ret_addr).get_number().set_number(0);
nasal_gc.reference_delete(addr);
return ret_addr;
}
else
return addr;
}
else if(type==scalar_string)
{
std::string str=nasal_gc.get_scalar(addr).get_string().get_string();
if(str.length()==0 || (check_numerable_string(str) && trans_string_to_number(str)==0))
{
ret_addr=nasal_gc.gc_alloc();
nasal_gc.get_scalar(ret_addr).set_type(scalar_number);
nasal_gc.get_scalar(ret_addr).get_number().set_number(0);
nasal_gc.reference_delete(addr);
return ret_addr;
}
else
return addr;
}
else
{
error_interrupt(__error_value_type,node.get_children().front().get_node_line());
return -1;
}
return -1;
}
else if(node_type==__nor_operator)
{
// nor will return 0 if the value is not null
// nor will return 1 if the value is null(0,nil,'0',"0")
// if or gets all 0,or returns 0
// if and gets a 0,and returns 0
;
// nor will return 1 if the value is null(0,nil,'0',"0",'',"")
// vector,hash,function is not allowed here
int ret_addr=-1;
int addr=calculation(local_scope,node.get_children().front());
int type=nasal_gc.get_scalar(addr).get_type();
if(type==scalar_number)
{
double num=nasal_gc.get_scalar(addr).get_number().get_number();
ret_addr=nasal_gc.gc_alloc();
nasal_gc.get_scalar(ret_addr).set_type(scalar_number);
nasal_gc.get_scalar(ret_addr).get_number().set_number((double(num==0)));
}
else if(type==scalar_string)
{
std::string str=nasal_gc.get_scalar(addr).get_string().get_string();
ret_addr=nasal_gc.gc_alloc();
nasal_gc.get_scalar(ret_addr).set_type(scalar_number);
if(str.length()==0 || (check_numerable_string(str) && trans_string_to_number(str)==0))
nasal_gc.get_scalar(ret_addr).get_number().set_number(1);
else
nasal_gc.get_scalar(ret_addr).get_number().set_number(0);
}
else
{
error_interrupt(__error_value_type,node.get_children().front().get_node_line());
return -1;
}
nasal_gc.reference_delete(addr);
return ret_addr;
}
return -1;
}