update
This commit is contained in:
parent
682e2b3701
commit
a55c6aae1b
|
@ -370,15 +370,9 @@ int nasal_vector::get_elem(int addr)
|
||||||
// 0 ~ size-1 -size ~ -1
|
// 0 ~ size-1 -size ~ -1
|
||||||
int bound=nas_array.size();
|
int bound=nas_array.size();
|
||||||
if(-bound<=addr && addr<0)
|
if(-bound<=addr && addr<0)
|
||||||
{
|
|
||||||
nasal_gc.reference_add(nas_array[bound+addr]);
|
|
||||||
return nas_array[bound+addr];
|
return nas_array[bound+addr];
|
||||||
}
|
|
||||||
else if(0<=addr && addr<bound)
|
else if(0<=addr && addr<bound)
|
||||||
{
|
|
||||||
nasal_gc.reference_add(nas_array[addr]);
|
|
||||||
return nas_array[addr];
|
return nas_array[addr];
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int nasal_vector::vec_pop()
|
int nasal_vector::vec_pop()
|
||||||
|
@ -446,10 +440,7 @@ int* nasal_hash::get_hash_member_addr(std::string member_name)
|
||||||
int nasal_hash::get_hash_member(std::string member_name)
|
int nasal_hash::get_hash_member(std::string member_name)
|
||||||
{
|
{
|
||||||
if(nas_hash.find(member_name)!=nas_hash.end())
|
if(nas_hash.find(member_name)!=nas_hash.end())
|
||||||
{
|
|
||||||
nasal_gc.reference_add(nas_hash[member_name]);
|
|
||||||
return nas_hash[member_name];
|
return nas_hash[member_name];
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
void nasal_hash::hash_push(std::string member_name,int addr)
|
void nasal_hash::hash_push(std::string member_name,int addr)
|
||||||
|
|
|
@ -31,12 +31,14 @@ class nasal_parse
|
||||||
|
|
||||||
error_begin_token_of_scalar, // in scalar_generate()
|
error_begin_token_of_scalar, // in scalar_generate()
|
||||||
|
|
||||||
|
need_default_parameter, // parameters must have a default value if detected there is a default parameter before.
|
||||||
default_dynamic_parameter, // default parameter should not be dynamic
|
default_dynamic_parameter, // default parameter should not be dynamic
|
||||||
parameter_lack_part, // parameter lack a ')' or identifier
|
parameter_lack_part, // parameter lack a ')' or identifier
|
||||||
parameter_lack_curve, // parameter lack a ',' or ')'
|
parameter_lack_curve, // parameter lack a ',' or ')'
|
||||||
|
|
||||||
special_call_func_lack_id,
|
special_call_func_lack_id,
|
||||||
special_call_func_lack_colon,
|
special_call_func_lack_colon,
|
||||||
|
normal_call_func_has_colon, // when calling a function,normal way and special way cannot be used together
|
||||||
call_func_lack_comma, // lack comma when giving parameters to a function
|
call_func_lack_comma, // lack comma when giving parameters to a function
|
||||||
call_hash_lack_id, // lack identifier when calling a hash
|
call_hash_lack_id, // lack identifier when calling a hash
|
||||||
call_vector_wrong_comma, // wrong use of comma like this: id[0,4:6,7,] (the last comma is incorrect here)
|
call_vector_wrong_comma, // wrong use of comma like this: id[0,4:6,7,] (the last comma is incorrect here)
|
||||||
|
@ -181,124 +183,128 @@ void nasal_parse::get_token_list(std::list<token>& detail_token_stream)
|
||||||
|
|
||||||
void nasal_parse::print_parse_error(int error_type,int line,int error_token_type=__stack_end)
|
void nasal_parse::print_parse_error(int error_type,int line,int error_token_type=__stack_end)
|
||||||
{
|
{
|
||||||
std::string error_info_head=">> [Parse] line ";
|
std::cout<<">> [Parse] line "<<line<<": ";
|
||||||
switch(error_type)
|
switch(error_type)
|
||||||
{
|
{
|
||||||
case parse_unknown_error:
|
case parse_unknown_error:
|
||||||
std::cout<<error_info_head<<line<<": unknown parse error.(token id: "<<error_token_type<<")."<<std::endl;break;
|
std::cout<<"unknown parse error.(token id: "<<error_token_type<<")."<<std::endl;break;
|
||||||
case error_token_in_main:
|
case error_token_in_main:
|
||||||
std::cout<<error_info_head<<line<<": statements should not begin with \'";
|
std::cout<<"statements should not begin with \'";
|
||||||
print_parse_token(error_token_type);
|
print_parse_token(error_token_type);
|
||||||
std::cout<<"\' in main scope."<<std::endl;
|
std::cout<<"\' in main scope."<<std::endl;
|
||||||
break;
|
break;
|
||||||
case error_token_in_block:
|
case error_token_in_block:
|
||||||
std::cout<<error_info_head<<line<<": statements should not begin with \'";
|
std::cout<<"statements should not begin with \'";
|
||||||
print_parse_token(error_token_type);
|
print_parse_token(error_token_type);
|
||||||
std::cout<<"\' in block scope."<<std::endl;
|
std::cout<<"\' in block scope."<<std::endl;
|
||||||
break;
|
break;
|
||||||
case lack_semi:
|
case lack_semi:
|
||||||
std::cout<<error_info_head<<line<<": expect a \';\' at the end of the statement."<<std::endl;break;
|
std::cout<<"expect a \';\' at the end of the statement."<<std::endl;break;
|
||||||
case lack_id:
|
case lack_id:
|
||||||
std::cout<<error_info_head<<line<<": expect an identifier here."<<std::endl;break;
|
std::cout<<"expect an identifier here."<<std::endl;break;
|
||||||
case lack_left_curve:
|
case lack_left_curve:
|
||||||
std::cout<<error_info_head<<line<<": expect a \'(\' here."<<std::endl;break;
|
std::cout<<"expect a \'(\' here."<<std::endl;break;
|
||||||
case lack_right_curve:
|
case lack_right_curve:
|
||||||
std::cout<<error_info_head<<line<<": expect a \')\' here."<<std::endl;break;
|
std::cout<<"expect a \')\' here."<<std::endl;break;
|
||||||
case lack_right_brace:
|
case lack_right_brace:
|
||||||
std::cout<<error_info_head<<line<<": expect a \'}\' here."<<std::endl;break;
|
std::cout<<"expect a \'}\' here."<<std::endl;break;
|
||||||
case definition_lack_id:
|
case definition_lack_id:
|
||||||
std::cout<<error_info_head<<line<<": expect identifier(s) after \'var\'."<<std::endl;break;
|
std::cout<<"expect identifier(s) after \'var\'."<<std::endl;break;
|
||||||
case definition_lack_equal:
|
case definition_lack_equal:
|
||||||
std::cout<<error_info_head<<line<<": expect a \'=\' here but get \'";
|
std::cout<<"expect a \'=\' here but get \'";
|
||||||
print_parse_token(error_token_type);
|
print_parse_token(error_token_type);
|
||||||
std::cout<<"\' when generating definition."<<std::endl;
|
std::cout<<"\' when generating definition."<<std::endl;
|
||||||
break;
|
break;
|
||||||
case assignment_begin_error:
|
case assignment_begin_error:
|
||||||
std::cout<<error_info_head<<line<<": assignment should begin with one identifier_call."<<std::endl;
|
std::cout<<"assignment should begin with one identifier_call."<<std::endl;
|
||||||
break;
|
break;
|
||||||
case multi_definition_need_curve:
|
case multi_definition_need_curve:
|
||||||
std::cout<<error_info_head<<line<<": expect a \')\' here but get \'";
|
std::cout<<"expect a \')\' here but get \'";
|
||||||
print_parse_token(error_token_type);
|
print_parse_token(error_token_type);
|
||||||
std::cout<<"\' ."<<std::endl;
|
std::cout<<"\' ."<<std::endl;
|
||||||
break;
|
break;
|
||||||
case multi_assignment_need_curve:
|
case multi_assignment_need_curve:
|
||||||
std::cout<<error_info_head<<line<<": expect a \')\' here but get \'";
|
std::cout<<"expect a \')\' here but get \'";
|
||||||
print_parse_token(error_token_type);
|
print_parse_token(error_token_type);
|
||||||
std::cout<<"\' ."<<std::endl;
|
std::cout<<"\' ."<<std::endl;
|
||||||
break;
|
break;
|
||||||
case multi_assignment_need_equal:
|
case multi_assignment_need_equal:
|
||||||
std::cout<<error_info_head<<line<<": expect a \'=\' here but get \'";
|
std::cout<<"expect a \'=\' here but get \'";
|
||||||
print_parse_token(error_token_type);
|
print_parse_token(error_token_type);
|
||||||
std::cout<<"\' ."<<std::endl;
|
std::cout<<"\' ."<<std::endl;
|
||||||
break;
|
break;
|
||||||
case error_begin_token_of_scalar:
|
case error_begin_token_of_scalar:
|
||||||
std::cout<<error_info_head<<line<<": expect a scalar here but get \'";
|
std::cout<<"expect a scalar here but get \'";
|
||||||
print_parse_token(error_token_type);
|
print_parse_token(error_token_type);
|
||||||
std::cout<<"\' ."<<std::endl;
|
std::cout<<"\' ."<<std::endl;
|
||||||
break;
|
break;
|
||||||
|
case need_default_parameter:
|
||||||
|
std::cout<<"parameters after a default parameter must have their own default values."<<std::endl;break;
|
||||||
case default_dynamic_parameter:
|
case default_dynamic_parameter:
|
||||||
std::cout<<error_info_head<<line<<": dynamic parameter should not have a default value."<<std::endl;break;
|
std::cout<<"dynamic parameter should not have a default value."<<std::endl;break;
|
||||||
case parameter_lack_part:
|
case parameter_lack_part:
|
||||||
std::cout<<error_info_head<<line<<": expect a \')\' or identifier here when generating parameter_list."<<std::endl;break;
|
std::cout<<"expect a \')\' or identifier here when generating parameter_list."<<std::endl;break;
|
||||||
case parameter_lack_curve:
|
case parameter_lack_curve:
|
||||||
std::cout<<error_info_head<<line<<": expect a \')\' or \',\' here when generating parameter_list."<<std::endl;break;
|
std::cout<<"expect a \')\' or \',\' here when generating parameter_list."<<std::endl;break;
|
||||||
case special_call_func_lack_id:
|
case special_call_func_lack_id:
|
||||||
std::cout<<error_info_head<<line<<": expect an identifier here but get \'";
|
std::cout<<"expect an identifier here but get \'";
|
||||||
print_parse_token(error_token_type);
|
print_parse_token(error_token_type);
|
||||||
std::cout<<"\' when calling functions."<<std::endl;
|
std::cout<<"\' when calling functions."<<std::endl;
|
||||||
break;
|
break;
|
||||||
case special_call_func_lack_colon:
|
case special_call_func_lack_colon:
|
||||||
std::cout<<error_info_head<<line<<": expect an \':\' here but get \'";
|
std::cout<<"expect an \':\' here but get \'";
|
||||||
print_parse_token(error_token_type);
|
print_parse_token(error_token_type);
|
||||||
std::cout<<"\' when calling functions."<<std::endl;
|
std::cout<<"\' when calling functions."<<std::endl;
|
||||||
break;
|
break;
|
||||||
|
case normal_call_func_has_colon:
|
||||||
|
std::cout<<"normal and special ways of calling a function are not allowed to be used together."<<std::endl;break;
|
||||||
case call_func_lack_comma:
|
case call_func_lack_comma:
|
||||||
std::cout<<error_info_head<<line<<": expect a \',\' when calling a function but get \'";
|
std::cout<<"expect a \',\' when calling a function but get \'";
|
||||||
print_parse_token(error_token_type);
|
print_parse_token(error_token_type);
|
||||||
std::cout<<"\' ."<<std::endl;
|
std::cout<<"\' ."<<std::endl;
|
||||||
break;
|
break;
|
||||||
case call_hash_lack_id:
|
case call_hash_lack_id:
|
||||||
std::cout<<error_info_head<<line<<": expect an identifier after \'.\' ."<<std::endl;break;
|
std::cout<<"expect an identifier after \'.\' ."<<std::endl;break;
|
||||||
case call_vector_wrong_comma:
|
case call_vector_wrong_comma:
|
||||||
std::cout<<error_info_head<<line<<": expect a scalar after \',\' but get \']\' ."<<std::endl;
|
std::cout<<"expect a scalar after \',\' but get \']\' ."<<std::endl;
|
||||||
break;
|
break;
|
||||||
case call_vector_lack_bracket:
|
case call_vector_lack_bracket:
|
||||||
std::cout<<error_info_head<<line<<": expect a \']\' here but get \'";
|
std::cout<<"expect a \']\' here but get \'";
|
||||||
print_parse_token(error_token_type);
|
print_parse_token(error_token_type);
|
||||||
std::cout<<"\' ."<<std::endl;
|
std::cout<<"\' ."<<std::endl;
|
||||||
break;
|
break;
|
||||||
case call_vector_wrong_token:
|
case call_vector_wrong_token:
|
||||||
std::cout<<error_info_head<<line<<": expect \':\' or ',' or ']' here but get \'";
|
std::cout<<"expect \':\' or ',' or ']' here but get \'";
|
||||||
print_parse_token(error_token_type);
|
print_parse_token(error_token_type);
|
||||||
std::cout<<"\' ."<<std::endl;
|
std::cout<<"\' ."<<std::endl;
|
||||||
break;
|
break;
|
||||||
case vector_gen_lack_end:
|
case vector_gen_lack_end:
|
||||||
std::cout<<error_info_head<<line<<": expect a \',\' or \')\' here but get \'";
|
std::cout<<"expect a \',\' or \')\' here but get \'";
|
||||||
print_parse_token(error_token_type);
|
print_parse_token(error_token_type);
|
||||||
std::cout<<"\' ."<<std::endl;
|
std::cout<<"\' ."<<std::endl;
|
||||||
break;
|
break;
|
||||||
case hash_gen_lack_id:
|
case hash_gen_lack_id:
|
||||||
std::cout<<error_info_head<<line<<": expect an identifier or string here but get \'";
|
std::cout<<"expect an identifier or string here but get \'";
|
||||||
print_parse_token(error_token_type);
|
print_parse_token(error_token_type);
|
||||||
std::cout<<"\' ."<<std::endl;
|
std::cout<<"\' ."<<std::endl;
|
||||||
break;
|
break;
|
||||||
case hash_gen_lack_colon:
|
case hash_gen_lack_colon:
|
||||||
std::cout<<error_info_head<<line<<": expect a \':\' here but get \'";
|
std::cout<<"expect a \':\' here but get \'";
|
||||||
print_parse_token(error_token_type);
|
print_parse_token(error_token_type);
|
||||||
std::cout<<"\' ."<<std::endl;
|
std::cout<<"\' ."<<std::endl;
|
||||||
break;
|
break;
|
||||||
case hash_gen_lack_end:
|
case hash_gen_lack_end:
|
||||||
std::cout<<error_info_head<<line<<": expect a \',\' or \'}\' here but get \'";
|
std::cout<<"expect a \',\' or \'}\' here but get \'";
|
||||||
print_parse_token(error_token_type);
|
print_parse_token(error_token_type);
|
||||||
std::cout<<"\' ."<<std::endl;
|
std::cout<<"\' ."<<std::endl;
|
||||||
break;
|
break;
|
||||||
case ternary_operator_lack_colon:
|
case ternary_operator_lack_colon:
|
||||||
std::cout<<error_info_head<<line<<": expect a \':\' here but get \'";
|
std::cout<<"expect a \':\' here but get \'";
|
||||||
print_parse_token(error_token_type);
|
print_parse_token(error_token_type);
|
||||||
std::cout<<"\' ."<<std::endl;
|
std::cout<<"\' ."<<std::endl;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
std::cout<<error_info_head<<line<<": unknown parse error.(token id: "<<error_token_type<<")."<<std::endl;break;
|
std::cout<<"unknown parse error.(token id: "<<error_token_type<<")."<<std::endl;break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1052,6 +1058,8 @@ abstract_syntax_tree nasal_parse::scalar_generate()
|
||||||
if(this_token.type!=__right_curve)
|
if(this_token.type!=__right_curve)
|
||||||
{
|
{
|
||||||
bool scalar_para=true;
|
bool scalar_para=true;
|
||||||
|
// scalar_para is used to record that parameters is in normal format like f(1,2,3,4)
|
||||||
|
// if scalar_para is false ,this means parameters is in special format like f(a:1,b:2)
|
||||||
if(this_token.type==__id)
|
if(this_token.type==__id)
|
||||||
{
|
{
|
||||||
this->get_token();
|
this->get_token();
|
||||||
|
@ -1117,7 +1125,10 @@ abstract_syntax_tree nasal_parse::scalar_generate()
|
||||||
if((this_token.type!=__comma) && (this_token.type!=__right_curve))
|
if((this_token.type!=__comma) && (this_token.type!=__right_curve))
|
||||||
{
|
{
|
||||||
++error;
|
++error;
|
||||||
print_parse_error(call_func_lack_comma,this_token.line,this_token.type);
|
if(this_token.type==__colon)
|
||||||
|
print_parse_error(normal_call_func_has_colon,this_token.line,this_token.type);
|
||||||
|
else
|
||||||
|
print_parse_error(call_func_lack_comma,this_token.line,this_token.type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(this_token.type==__comma)
|
if(this_token.type==__comma)
|
||||||
|
@ -1316,6 +1327,7 @@ abstract_syntax_tree nasal_parse::function_generate()
|
||||||
this->get_token();
|
this->get_token();
|
||||||
if(this_token.type==__left_curve)
|
if(this_token.type==__left_curve)
|
||||||
{
|
{
|
||||||
|
bool has_default_para=false;
|
||||||
while(this_token.type!=__right_curve)
|
while(this_token.type!=__right_curve)
|
||||||
{
|
{
|
||||||
// check identifier
|
// check identifier
|
||||||
|
@ -1348,8 +1360,15 @@ abstract_syntax_tree nasal_parse::function_generate()
|
||||||
|
|
||||||
// check equal operator
|
// check equal operator
|
||||||
this->get_token();
|
this->get_token();
|
||||||
|
if(has_default_para && this_token.type!=__equal)
|
||||||
|
{
|
||||||
|
++error;
|
||||||
|
print_parse_error(need_default_parameter,this_token.line,this_token.type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
if(this_token.type==__equal)
|
if(this_token.type==__equal)
|
||||||
{
|
{
|
||||||
|
has_default_para=true;
|
||||||
if(parameter_type==__id)
|
if(parameter_type==__id)
|
||||||
{
|
{
|
||||||
abstract_syntax_tree default_parameter;
|
abstract_syntax_tree default_parameter;
|
||||||
|
@ -1692,10 +1711,8 @@ abstract_syntax_tree nasal_parse::loop_expr()
|
||||||
print_parse_error(lack_right_curve,this_token.line,this_token.type);
|
print_parse_error(lack_right_curve,this_token.line,this_token.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if(this_token.type==__forindex || this_token.type==__foreach)
|
||||||
{
|
{
|
||||||
// forindex
|
|
||||||
// foreach
|
|
||||||
this->get_token();// '('
|
this->get_token();// '('
|
||||||
if(this_token.type!=__left_curve)
|
if(this_token.type!=__left_curve)
|
||||||
{
|
{
|
||||||
|
@ -1704,20 +1721,39 @@ abstract_syntax_tree nasal_parse::loop_expr()
|
||||||
}
|
}
|
||||||
this->get_token();// 'var'
|
this->get_token();// 'var'
|
||||||
if(this_token.type!=__var)
|
if(this_token.type!=__var)
|
||||||
this->push_token();
|
|
||||||
this->get_token();// id
|
|
||||||
if(this_token.type!=__id)
|
|
||||||
{
|
{
|
||||||
++error;
|
// if checked not the 'var' then checking if this token is an identifier
|
||||||
print_parse_error(lack_id,this_token.line);
|
if(this_token.type!=__id)
|
||||||
|
{
|
||||||
|
++error;
|
||||||
|
print_parse_error(lack_id,this_token.line);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->push_token();
|
||||||
|
loop_main_node.add_children(scalar_generate());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
abstract_syntax_tree id_node;
|
abstract_syntax_tree new_definition_node;
|
||||||
id_node.set_node_line(this_token.line);
|
new_definition_node.set_node_line(this_token.line);
|
||||||
id_node.set_node_type(__id);
|
new_definition_node.set_node_type(__definition);
|
||||||
id_node.set_var_name(this_token.str);
|
this->get_token();
|
||||||
loop_main_node.add_children(id_node);
|
if(this_token.type!=__id)
|
||||||
|
{
|
||||||
|
++error;
|
||||||
|
print_parse_error(lack_id,this_token.line);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
abstract_syntax_tree new_id_node;
|
||||||
|
new_id_node.set_node_line(this_token.line);
|
||||||
|
new_id_node.set_node_type(__id);
|
||||||
|
new_id_node.set_var_name(this_token.str);
|
||||||
|
new_definition_node.add_children(new_id_node);
|
||||||
|
}
|
||||||
|
loop_main_node.add_children(new_definition_node);
|
||||||
}
|
}
|
||||||
this->get_token();// ';'
|
this->get_token();// ';'
|
||||||
if(this_token.type!=__semi)
|
if(this_token.type!=__semi)
|
||||||
|
|
|
@ -42,6 +42,7 @@ class nasal_runtime
|
||||||
__special_call_vector_too_large_value,
|
__special_call_vector_too_large_value,
|
||||||
__normal_call_vector_too_large_value,
|
__normal_call_vector_too_large_value,
|
||||||
__error_call_type_when_getting_address,
|
__error_call_type_when_getting_address,
|
||||||
|
__call_function_lack_para,
|
||||||
__forindex_foreach_not_vector,
|
__forindex_foreach_not_vector,
|
||||||
__break_not_used_in_loop,
|
__break_not_used_in_loop,
|
||||||
__continue_not_used_in_loop,
|
__continue_not_used_in_loop,
|
||||||
|
@ -58,12 +59,13 @@ class nasal_runtime
|
||||||
bool check_condition (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
bool check_condition (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||||
int calculation (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
int calculation (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||||
int* get_identifier_addr(std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
int* get_identifier_addr(std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||||
|
int call_scalar (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||||
int call_identifier (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
int call_identifier (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||||
void definition (std::list<std::map<std::string,int> >&,std::map<std::string,int>&,abstract_syntax_tree&);
|
void definition (std::list<std::map<std::string,int> >&,std::map<std::string,int>&,abstract_syntax_tree&);
|
||||||
int loop_expr (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
int loop_expr (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||||
int conditional (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
int conditional (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||||
int block_proc (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
int block_proc (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||||
int func_proc (std::list<std::map<std::string,int> >&,abstract_syntax_tree&,abstract_syntax_tree&,int);
|
int func_proc (std::list<std::map<std::string,int> >&,abstract_syntax_tree&,abstract_syntax_tree&,abstract_syntax_tree&,int);
|
||||||
public:
|
public:
|
||||||
nasal_runtime()
|
nasal_runtime()
|
||||||
{
|
{
|
||||||
|
@ -121,6 +123,8 @@ void nasal_runtime::error_interrupt(const int type,const int line)
|
||||||
std::cout<<"the number used to call the vector is too large(over 0x7fffffff)."<<std::endl;break;
|
std::cout<<"the number used to call the vector is too large(over 0x7fffffff)."<<std::endl;break;
|
||||||
case __error_call_type_when_getting_address:
|
case __error_call_type_when_getting_address:
|
||||||
std::cout<<"this type of calling identifier is not allowed here."<<std::endl;break;
|
std::cout<<"this type of calling identifier is not allowed here."<<std::endl;break;
|
||||||
|
case __call_function_lack_para:
|
||||||
|
std::cout<<"lack parameter(s) when calling a function."<<std::endl;break;
|
||||||
case __forindex_foreach_not_vector:
|
case __forindex_foreach_not_vector:
|
||||||
std::cout<<"forindex and foreach need vector here."<<std::endl;break;
|
std::cout<<"forindex and foreach need vector here."<<std::endl;break;
|
||||||
case __break_not_used_in_loop:
|
case __break_not_used_in_loop:
|
||||||
|
@ -183,13 +187,261 @@ int nasal_runtime::vector_generation(std::list<std::map<std::string,int> >& loca
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int last_hash_addr=-1;
|
||||||
for(;call_node!=node.get_children().end();++call_node)
|
for(;call_node!=node.get_children().end();++call_node)
|
||||||
{
|
{
|
||||||
switch(call_node->get_node_type())
|
if(nasal_gc.get_scalar(addr).get_type()==scalar_hash)
|
||||||
|
last_hash_addr=addr;
|
||||||
|
// call vector/special call hash/subvec
|
||||||
|
// the special type of calling hash like a["name"] is also generated as calling vector
|
||||||
|
if(call_node->get_node_type()==__call_vector)
|
||||||
{
|
{
|
||||||
case __call_vector:break;
|
// check the scalar type of called identifier here
|
||||||
case __call_hash:break;
|
int called_type=nasal_gc.get_scalar(addr).get_type();
|
||||||
case __call_function:break;
|
if(called_type!=scalar_vector && called_type!=scalar_hash)
|
||||||
|
{
|
||||||
|
error_interrupt(__error_value_type,call_node->get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(call_node->get_children().front().get_node_type()==__sub_vector)
|
||||||
|
{
|
||||||
|
if(called_type==scalar_hash)
|
||||||
|
{
|
||||||
|
error_interrupt(__not_callable_vector,call_node->get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int num1_addr=-1;
|
||||||
|
int num2_addr=-1;
|
||||||
|
// identifier[num1:];
|
||||||
|
if(call_node->get_children().front().get_children().size()==1)
|
||||||
|
{
|
||||||
|
num1_addr=calculation(local_scope,call_node->get_children().front().get_children().front());
|
||||||
|
if(num1_addr<0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// identifier[num1:num2];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
num1_addr=calculation(local_scope,call_node->get_children().front().get_children().front());
|
||||||
|
num2_addr=calculation(local_scope,call_node->get_children().front().get_children().back());
|
||||||
|
if(num1_addr<0 || num2_addr<0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(nasal_gc.get_scalar(num1_addr).get_type()!=scalar_number
|
||||||
|
&& nasal_gc.get_scalar(num1_addr).get_type()!=scalar_string)
|
||||||
|
{
|
||||||
|
error_interrupt(__error_value_type_when_calling_vector,call_node->get_children().front().get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(num2_addr>=0
|
||||||
|
&& (nasal_gc.get_scalar(num2_addr).get_type()!=scalar_number
|
||||||
|
&& nasal_gc.get_scalar(num2_addr).get_type()!=scalar_string
|
||||||
|
&& nasal_gc.get_scalar(num2_addr).get_type()!=scalar_nil))
|
||||||
|
{
|
||||||
|
error_interrupt(__error_value_type_when_calling_vector,call_node->get_children().front().get_children().back().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(nasal_gc.get_scalar(num1_addr).get_type()==scalar_string)
|
||||||
|
{
|
||||||
|
if(check_numerable_string(nasal_gc.get_scalar(num1_addr).get_string().get_string()))
|
||||||
|
{
|
||||||
|
double tmp_num=trans_string_to_number(nasal_gc.get_scalar(num1_addr).get_string().get_string());
|
||||||
|
if(tmp_num<0)
|
||||||
|
{
|
||||||
|
error_interrupt(__special_call_vector_negative_value,call_node->get_children().front().get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
nasal_gc.reference_delete(num1_addr);
|
||||||
|
num1_addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(num1_addr).set_type(scalar_number);
|
||||||
|
nasal_gc.get_scalar(num1_addr).get_number().set_number(tmp_num);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error_interrupt(__not_numerable_str,call_node->get_children().front().get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(num2_addr>=0 && nasal_gc.get_scalar(num2_addr).get_type()==scalar_string)
|
||||||
|
{
|
||||||
|
if(check_numerable_string(nasal_gc.get_scalar(num2_addr).get_string().get_string()))
|
||||||
|
{
|
||||||
|
double tmp_num=trans_string_to_number(nasal_gc.get_scalar(num2_addr).get_string().get_string());
|
||||||
|
if(tmp_num<0)
|
||||||
|
{
|
||||||
|
error_interrupt(__special_call_vector_negative_value,call_node->get_children().front().get_children().back().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
nasal_gc.reference_delete(num2_addr);
|
||||||
|
num2_addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(num2_addr).set_type(scalar_number);
|
||||||
|
nasal_gc.get_scalar(num2_addr).get_number().set_number(tmp_num);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error_interrupt(__not_numerable_str,call_node->get_children().front().get_children().back().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(nasal_gc.get_scalar(num1_addr).get_number().get_number()>2147483647)
|
||||||
|
{
|
||||||
|
error_interrupt(__special_call_vector_too_large_value,call_node->get_children().front().get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(num2_addr>=0 && nasal_gc.get_scalar(num2_addr).get_number().get_number()>2147483647)
|
||||||
|
{
|
||||||
|
error_interrupt(__special_call_vector_too_large_value,call_node->get_children().front().get_children().back().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int begin_num=(int)nasal_gc.get_scalar(num1_addr).get_number().get_number();
|
||||||
|
int end_num=0;
|
||||||
|
if(num2_addr<0 || nasal_gc.get_scalar(num2_addr).get_type()==scalar_nil)
|
||||||
|
end_num=nasal_gc.get_scalar(addr).get_vector().get_size();
|
||||||
|
else
|
||||||
|
end_num=(int)nasal_gc.get_scalar(num2_addr).get_number().get_number();
|
||||||
|
if(num1_addr>=0)
|
||||||
|
nasal_gc.reference_delete(num1_addr);
|
||||||
|
if(num2_addr>=0)
|
||||||
|
nasal_gc.reference_delete(num2_addr);
|
||||||
|
std::vector<int> subvec_result;
|
||||||
|
for(int i=begin_num;i<end_num;++i)
|
||||||
|
{
|
||||||
|
// addr used here
|
||||||
|
int tmp_data_addr=nasal_gc.get_scalar(addr).get_vector().get_elem(i);
|
||||||
|
int new_addr=-1;
|
||||||
|
if(tmp_data_addr<0)
|
||||||
|
{
|
||||||
|
error_interrupt(__invalid_vector_member,call_node->get_children().front().get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
switch(nasal_gc.get_scalar(tmp_data_addr).get_type())
|
||||||
|
{
|
||||||
|
case scalar_nil:
|
||||||
|
new_addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(new_addr).set_type(scalar_nil);
|
||||||
|
break;
|
||||||
|
case scalar_number:
|
||||||
|
new_addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(new_addr).set_type(scalar_number);
|
||||||
|
nasal_gc.get_scalar(new_addr).get_number().deep_copy(nasal_gc.get_scalar(tmp_data_addr).get_number());
|
||||||
|
break;
|
||||||
|
case scalar_string:
|
||||||
|
new_addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(new_addr).set_type(scalar_string);
|
||||||
|
nasal_gc.get_scalar(new_addr).get_string().deep_copy(nasal_gc.get_scalar(tmp_data_addr).get_string());
|
||||||
|
break;
|
||||||
|
case scalar_function:
|
||||||
|
new_addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(new_addr).set_type(scalar_function);
|
||||||
|
nasal_gc.get_scalar(new_addr).get_function().deep_copy(nasal_gc.get_scalar(tmp_data_addr).get_function());
|
||||||
|
break;
|
||||||
|
case scalar_vector:
|
||||||
|
case scalar_hash:
|
||||||
|
new_addr=tmp_data_addr;
|
||||||
|
nasal_gc.reference_add(new_addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nasal_gc.reference_delete(tmp_data_addr);
|
||||||
|
subvec_result.push_back(new_addr);
|
||||||
|
}
|
||||||
|
int tmp_addr=addr;
|
||||||
|
addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(addr).set_type(scalar_vector);
|
||||||
|
for(int i=0;i<subvec_result.size();++i)
|
||||||
|
nasal_gc.get_scalar(addr).get_vector().vec_push(subvec_result[i]);
|
||||||
|
nasal_gc.reference_delete(tmp_addr);
|
||||||
|
}// end sub-vector
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// normal vector/hash calling
|
||||||
|
int data_addr=calculation(local_scope,call_node->get_children().front());
|
||||||
|
if(data_addr<0)
|
||||||
|
return -1;
|
||||||
|
if(nasal_gc.get_scalar(data_addr).get_type()!=scalar_number && nasal_gc.get_scalar(data_addr).get_type()!=scalar_string)
|
||||||
|
{
|
||||||
|
error_interrupt(__error_value_type_when_calling_vector,call_node->get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(called_type==scalar_vector)
|
||||||
|
{
|
||||||
|
double place_num=0;
|
||||||
|
if(nasal_gc.get_scalar(data_addr).get_type()==scalar_string)
|
||||||
|
{
|
||||||
|
if(check_numerable_string(nasal_gc.get_scalar(data_addr).get_string().get_string()))
|
||||||
|
place_num=(int)trans_string_to_number(nasal_gc.get_scalar(data_addr).get_string().get_string());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error_interrupt(__not_numerable_str,call_node->get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(place_num>2147483647 || place_num<-2147483648)
|
||||||
|
{
|
||||||
|
error_interrupt(__normal_call_vector_too_large_value,call_node->get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int tmp_addr=addr;
|
||||||
|
addr=nasal_gc.get_scalar(addr).get_vector().get_elem((int)place_num);
|
||||||
|
if(addr<0)
|
||||||
|
{
|
||||||
|
error_interrupt(__invalid_vector_member,call_node->get_children().front().get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
nasal_gc.reference_add(addr);
|
||||||
|
nasal_gc.reference_delete(tmp_addr);
|
||||||
|
}
|
||||||
|
else if(called_type==scalar_hash)
|
||||||
|
{
|
||||||
|
if(nasal_gc.get_scalar(data_addr).get_type()!=scalar_string)
|
||||||
|
{
|
||||||
|
error_interrupt(__error_value_type_when_calling_hash,call_node->get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int tmp_addr=addr;
|
||||||
|
addr=nasal_gc.get_scalar(addr).get_hash().get_hash_member(nasal_gc.get_scalar(data_addr).get_string().get_string());
|
||||||
|
if(addr<0)
|
||||||
|
{
|
||||||
|
error_interrupt(__invalid_hash_member,call_node->get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
nasal_gc.reference_add(addr);
|
||||||
|
nasal_gc.reference_delete(tmp_addr);
|
||||||
|
}
|
||||||
|
nasal_gc.reference_delete(data_addr);
|
||||||
|
}
|
||||||
|
}// end call vector
|
||||||
|
// call hash identifier.identifier
|
||||||
|
else if(call_node->get_node_type()==__call_hash)
|
||||||
|
{
|
||||||
|
if(nasal_gc.get_scalar(addr).get_type()!=scalar_hash)
|
||||||
|
{
|
||||||
|
error_interrupt(__not_callable_hash,call_node->get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
addr=nasal_gc.get_scalar(addr).get_hash().get_hash_member(call_node->get_var_name());
|
||||||
|
if(addr<0)
|
||||||
|
{
|
||||||
|
error_interrupt(__invalid_hash_member,call_node->get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}// end call hash
|
||||||
|
// call function identifier(...)
|
||||||
|
else if(call_node->get_node_type()==__call_function)
|
||||||
|
{
|
||||||
|
if(nasal_gc.get_scalar(addr).get_type()!=scalar_function)
|
||||||
|
{
|
||||||
|
error_interrupt(__not_callable_function,call_node->get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int tmp_addr=addr;
|
||||||
|
addr=func_proc(
|
||||||
|
nasal_gc.get_scalar(addr).get_function().get_local_scope(),
|
||||||
|
nasal_gc.get_scalar(addr).get_function().get_parameter_list(),
|
||||||
|
nasal_gc.get_scalar(addr).get_function().get_statement_block(),
|
||||||
|
*call_node,
|
||||||
|
last_hash_addr);
|
||||||
|
if(addr<0)
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return addr;
|
return addr;
|
||||||
|
@ -233,9 +485,262 @@ int nasal_runtime::hash_generation(std::list<std::map<std::string,int> >& local_
|
||||||
nasal_gc.get_scalar(addr).get_hash().hash_push(member_name,calculation(local_scope,*i));
|
nasal_gc.get_scalar(addr).get_hash().hash_push(member_name,calculation(local_scope,*i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int last_hash_addr=-1;
|
||||||
for(;call_node!=node.get_children().end();++call_node)
|
for(;call_node!=node.get_children().end();++call_node)
|
||||||
{
|
{
|
||||||
;
|
if(nasal_gc.get_scalar(addr).get_type()==scalar_hash)
|
||||||
|
last_hash_addr=addr;
|
||||||
|
// call vector/special call hash/subvec
|
||||||
|
// the special type of calling hash like a["name"] is also generated as calling vector
|
||||||
|
if(call_node->get_node_type()==__call_vector)
|
||||||
|
{
|
||||||
|
// check the scalar type of called identifier here
|
||||||
|
int called_type=nasal_gc.get_scalar(addr).get_type();
|
||||||
|
if(called_type!=scalar_vector && called_type!=scalar_hash)
|
||||||
|
{
|
||||||
|
error_interrupt(__error_value_type,call_node->get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(call_node->get_children().front().get_node_type()==__sub_vector)
|
||||||
|
{
|
||||||
|
if(called_type==scalar_hash)
|
||||||
|
{
|
||||||
|
error_interrupt(__not_callable_vector,call_node->get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int num1_addr=-1;
|
||||||
|
int num2_addr=-1;
|
||||||
|
// identifier[num1:];
|
||||||
|
if(call_node->get_children().front().get_children().size()==1)
|
||||||
|
{
|
||||||
|
num1_addr=calculation(local_scope,call_node->get_children().front().get_children().front());
|
||||||
|
if(num1_addr<0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// identifier[num1:num2];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
num1_addr=calculation(local_scope,call_node->get_children().front().get_children().front());
|
||||||
|
num2_addr=calculation(local_scope,call_node->get_children().front().get_children().back());
|
||||||
|
if(num1_addr<0 || num2_addr<0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(nasal_gc.get_scalar(num1_addr).get_type()!=scalar_number
|
||||||
|
&& nasal_gc.get_scalar(num1_addr).get_type()!=scalar_string)
|
||||||
|
{
|
||||||
|
error_interrupt(__error_value_type_when_calling_vector,call_node->get_children().front().get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(num2_addr>=0
|
||||||
|
&& (nasal_gc.get_scalar(num2_addr).get_type()!=scalar_number
|
||||||
|
&& nasal_gc.get_scalar(num2_addr).get_type()!=scalar_string
|
||||||
|
&& nasal_gc.get_scalar(num2_addr).get_type()!=scalar_nil))
|
||||||
|
{
|
||||||
|
error_interrupt(__error_value_type_when_calling_vector,call_node->get_children().front().get_children().back().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(nasal_gc.get_scalar(num1_addr).get_type()==scalar_string)
|
||||||
|
{
|
||||||
|
if(check_numerable_string(nasal_gc.get_scalar(num1_addr).get_string().get_string()))
|
||||||
|
{
|
||||||
|
double tmp_num=trans_string_to_number(nasal_gc.get_scalar(num1_addr).get_string().get_string());
|
||||||
|
if(tmp_num<0)
|
||||||
|
{
|
||||||
|
error_interrupt(__special_call_vector_negative_value,call_node->get_children().front().get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
nasal_gc.reference_delete(num1_addr);
|
||||||
|
num1_addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(num1_addr).set_type(scalar_number);
|
||||||
|
nasal_gc.get_scalar(num1_addr).get_number().set_number(tmp_num);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error_interrupt(__not_numerable_str,call_node->get_children().front().get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(num2_addr>=0 && nasal_gc.get_scalar(num2_addr).get_type()==scalar_string)
|
||||||
|
{
|
||||||
|
if(check_numerable_string(nasal_gc.get_scalar(num2_addr).get_string().get_string()))
|
||||||
|
{
|
||||||
|
double tmp_num=trans_string_to_number(nasal_gc.get_scalar(num2_addr).get_string().get_string());
|
||||||
|
if(tmp_num<0)
|
||||||
|
{
|
||||||
|
error_interrupt(__special_call_vector_negative_value,call_node->get_children().front().get_children().back().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
nasal_gc.reference_delete(num2_addr);
|
||||||
|
num2_addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(num2_addr).set_type(scalar_number);
|
||||||
|
nasal_gc.get_scalar(num2_addr).get_number().set_number(tmp_num);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error_interrupt(__not_numerable_str,call_node->get_children().front().get_children().back().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(nasal_gc.get_scalar(num1_addr).get_number().get_number()>2147483647)
|
||||||
|
{
|
||||||
|
error_interrupt(__special_call_vector_too_large_value,call_node->get_children().front().get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(num2_addr>=0 && nasal_gc.get_scalar(num2_addr).get_number().get_number()>2147483647)
|
||||||
|
{
|
||||||
|
error_interrupt(__special_call_vector_too_large_value,call_node->get_children().front().get_children().back().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int begin_num=(int)nasal_gc.get_scalar(num1_addr).get_number().get_number();
|
||||||
|
int end_num=0;
|
||||||
|
if(num2_addr<0 || nasal_gc.get_scalar(num2_addr).get_type()==scalar_nil)
|
||||||
|
end_num=nasal_gc.get_scalar(addr).get_vector().get_size();
|
||||||
|
else
|
||||||
|
end_num=(int)nasal_gc.get_scalar(num2_addr).get_number().get_number();
|
||||||
|
if(num1_addr>=0)
|
||||||
|
nasal_gc.reference_delete(num1_addr);
|
||||||
|
if(num2_addr>=0)
|
||||||
|
nasal_gc.reference_delete(num2_addr);
|
||||||
|
std::vector<int> subvec_result;
|
||||||
|
for(int i=begin_num;i<end_num;++i)
|
||||||
|
{
|
||||||
|
// addr used here
|
||||||
|
int tmp_data_addr=nasal_gc.get_scalar(addr).get_vector().get_elem(i);
|
||||||
|
int new_addr=-1;
|
||||||
|
if(tmp_data_addr<0)
|
||||||
|
{
|
||||||
|
error_interrupt(__invalid_vector_member,call_node->get_children().front().get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
switch(nasal_gc.get_scalar(tmp_data_addr).get_type())
|
||||||
|
{
|
||||||
|
case scalar_nil:
|
||||||
|
new_addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(new_addr).set_type(scalar_nil);
|
||||||
|
break;
|
||||||
|
case scalar_number:
|
||||||
|
new_addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(new_addr).set_type(scalar_number);
|
||||||
|
nasal_gc.get_scalar(new_addr).get_number().deep_copy(nasal_gc.get_scalar(tmp_data_addr).get_number());
|
||||||
|
break;
|
||||||
|
case scalar_string:
|
||||||
|
new_addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(new_addr).set_type(scalar_string);
|
||||||
|
nasal_gc.get_scalar(new_addr).get_string().deep_copy(nasal_gc.get_scalar(tmp_data_addr).get_string());
|
||||||
|
break;
|
||||||
|
case scalar_function:
|
||||||
|
new_addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(new_addr).set_type(scalar_function);
|
||||||
|
nasal_gc.get_scalar(new_addr).get_function().deep_copy(nasal_gc.get_scalar(tmp_data_addr).get_function());
|
||||||
|
break;
|
||||||
|
case scalar_vector:
|
||||||
|
case scalar_hash:
|
||||||
|
new_addr=tmp_data_addr;
|
||||||
|
nasal_gc.reference_add(new_addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nasal_gc.reference_delete(tmp_data_addr);
|
||||||
|
subvec_result.push_back(new_addr);
|
||||||
|
}
|
||||||
|
int tmp_addr=addr;
|
||||||
|
addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(addr).set_type(scalar_vector);
|
||||||
|
for(int i=0;i<subvec_result.size();++i)
|
||||||
|
nasal_gc.get_scalar(addr).get_vector().vec_push(subvec_result[i]);
|
||||||
|
nasal_gc.reference_delete(tmp_addr);
|
||||||
|
}// end sub-vector
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// normal vector/hash calling
|
||||||
|
int data_addr=calculation(local_scope,call_node->get_children().front());
|
||||||
|
if(data_addr<0)
|
||||||
|
return -1;
|
||||||
|
if(nasal_gc.get_scalar(data_addr).get_type()!=scalar_number && nasal_gc.get_scalar(data_addr).get_type()!=scalar_string)
|
||||||
|
{
|
||||||
|
error_interrupt(__error_value_type_when_calling_vector,call_node->get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(called_type==scalar_vector)
|
||||||
|
{
|
||||||
|
double place_num=0;
|
||||||
|
if(nasal_gc.get_scalar(data_addr).get_type()==scalar_string)
|
||||||
|
{
|
||||||
|
if(check_numerable_string(nasal_gc.get_scalar(data_addr).get_string().get_string()))
|
||||||
|
place_num=(int)trans_string_to_number(nasal_gc.get_scalar(data_addr).get_string().get_string());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error_interrupt(__not_numerable_str,call_node->get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(place_num>2147483647 || place_num<-2147483648)
|
||||||
|
{
|
||||||
|
error_interrupt(__normal_call_vector_too_large_value,call_node->get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int tmp_addr=addr;
|
||||||
|
addr=nasal_gc.get_scalar(addr).get_vector().get_elem((int)place_num);
|
||||||
|
if(addr<0)
|
||||||
|
{
|
||||||
|
error_interrupt(__invalid_vector_member,call_node->get_children().front().get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
nasal_gc.reference_add(addr);
|
||||||
|
nasal_gc.reference_delete(tmp_addr);
|
||||||
|
}
|
||||||
|
else if(called_type==scalar_hash)
|
||||||
|
{
|
||||||
|
if(nasal_gc.get_scalar(data_addr).get_type()!=scalar_string)
|
||||||
|
{
|
||||||
|
error_interrupt(__error_value_type_when_calling_hash,call_node->get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int tmp_addr=addr;
|
||||||
|
addr=nasal_gc.get_scalar(addr).get_hash().get_hash_member(nasal_gc.get_scalar(data_addr).get_string().get_string());
|
||||||
|
if(addr<0)
|
||||||
|
{
|
||||||
|
error_interrupt(__invalid_hash_member,call_node->get_children().front().get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
nasal_gc.reference_add(addr);
|
||||||
|
nasal_gc.reference_delete(tmp_addr);
|
||||||
|
}
|
||||||
|
nasal_gc.reference_delete(data_addr);
|
||||||
|
}
|
||||||
|
}// end call vector
|
||||||
|
// call hash identifier.identifier
|
||||||
|
else if(call_node->get_node_type()==__call_hash)
|
||||||
|
{
|
||||||
|
if(nasal_gc.get_scalar(addr).get_type()!=scalar_hash)
|
||||||
|
{
|
||||||
|
error_interrupt(__not_callable_hash,call_node->get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
addr=nasal_gc.get_scalar(addr).get_hash().get_hash_member(call_node->get_var_name());
|
||||||
|
if(addr<0)
|
||||||
|
{
|
||||||
|
error_interrupt(__invalid_hash_member,call_node->get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}// end call hash
|
||||||
|
// call function identifier(...)
|
||||||
|
else if(call_node->get_node_type()==__call_function)
|
||||||
|
{
|
||||||
|
if(nasal_gc.get_scalar(addr).get_type()!=scalar_function)
|
||||||
|
{
|
||||||
|
error_interrupt(__not_callable_function,call_node->get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int tmp_addr=addr;
|
||||||
|
addr=func_proc(
|
||||||
|
nasal_gc.get_scalar(addr).get_function().get_local_scope(),
|
||||||
|
nasal_gc.get_scalar(addr).get_function().get_parameter_list(),
|
||||||
|
nasal_gc.get_scalar(addr).get_function().get_statement_block(),
|
||||||
|
*call_node,
|
||||||
|
last_hash_addr);
|
||||||
|
if(addr<0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
@ -1224,6 +1729,12 @@ int* nasal_runtime::get_identifier_addr(std::list<std::map<std::string,int> >& l
|
||||||
}
|
}
|
||||||
return ret_addr;
|
return ret_addr;
|
||||||
}
|
}
|
||||||
|
int nasal_runtime::call_scalar(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
||||||
|
{
|
||||||
|
int addr=-1;
|
||||||
|
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
int nasal_runtime::call_identifier(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
int nasal_runtime::call_identifier(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
||||||
{
|
{
|
||||||
int addr=-1;
|
int addr=-1;
|
||||||
|
@ -1491,6 +2002,7 @@ int nasal_runtime::call_identifier(std::list<std::map<std::string,int> >& local_
|
||||||
nasal_gc.get_scalar(addr).get_function().get_local_scope(),
|
nasal_gc.get_scalar(addr).get_function().get_local_scope(),
|
||||||
nasal_gc.get_scalar(addr).get_function().get_parameter_list(),
|
nasal_gc.get_scalar(addr).get_function().get_parameter_list(),
|
||||||
nasal_gc.get_scalar(addr).get_function().get_statement_block(),
|
nasal_gc.get_scalar(addr).get_function().get_statement_block(),
|
||||||
|
*iter,
|
||||||
last_hash_addr);
|
last_hash_addr);
|
||||||
if(addr<0)
|
if(addr<0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1680,8 +2192,30 @@ int nasal_runtime::loop_expr(std::list<std::map<std::string,int> >& local_scope,
|
||||||
}
|
}
|
||||||
else if(loop_type==__foreach)
|
else if(loop_type==__foreach)
|
||||||
{
|
{
|
||||||
|
// foreach(i;vector)
|
||||||
|
// foreach gives elements in the vector to the identifier 'i' and the 'i' will take part in calculation
|
||||||
std::list<abstract_syntax_tree>::iterator iter=node.get_children().begin();
|
std::list<abstract_syntax_tree>::iterator iter=node.get_children().begin();
|
||||||
int* addr=NULL;// definition
|
int* addr=NULL;// definition/assignment
|
||||||
|
if(iter->get_node_type()==__definition)
|
||||||
|
{
|
||||||
|
std::string identifier_name=iter->get_children().front().get_var_name();
|
||||||
|
int new_identifier_addr=nasal_gc.gc_alloc();
|
||||||
|
local_scope.back()[identifier_name]=new_identifier_addr;
|
||||||
|
nasal_gc.get_scalar(new_identifier_addr).set_type(scalar_nil);
|
||||||
|
addr=&(local_scope.back()[identifier_name]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addr=get_identifier_addr(local_scope,*iter);
|
||||||
|
if(addr && *addr>=0)
|
||||||
|
{
|
||||||
|
nasal_gc.reference_delete(*addr);
|
||||||
|
*addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(*addr).set_type(scalar_nil);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!addr)
|
||||||
|
return __state_error;
|
||||||
++iter;
|
++iter;
|
||||||
int vec_addr=calculation(local_scope,*iter);
|
int vec_addr=calculation(local_scope,*iter);
|
||||||
if(vec_addr<0)
|
if(vec_addr<0)
|
||||||
|
@ -1694,7 +2228,35 @@ int nasal_runtime::loop_expr(std::list<std::map<std::string,int> >& local_scope,
|
||||||
++iter;
|
++iter;
|
||||||
for(int i=0;i<nasal_gc.get_scalar(vec_addr).get_vector().get_size();++i)
|
for(int i=0;i<nasal_gc.get_scalar(vec_addr).get_vector().get_size();++i)
|
||||||
{
|
{
|
||||||
;
|
int now_step_elem_addr=nasal_gc.get_scalar(vec_addr).get_vector().get_elem(i);
|
||||||
|
nasal_gc.reference_delete(*addr);
|
||||||
|
switch(nasal_gc.get_scalar(now_step_elem_addr).get_type())
|
||||||
|
{
|
||||||
|
case scalar_nil:
|
||||||
|
*addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(*addr).set_type(scalar_nil);
|
||||||
|
break;
|
||||||
|
case scalar_number:
|
||||||
|
*addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(*addr).set_type(scalar_number);
|
||||||
|
nasal_gc.get_scalar(*addr).get_number().deep_copy(nasal_gc.get_scalar(now_step_elem_addr).get_number());
|
||||||
|
break;
|
||||||
|
case scalar_string:
|
||||||
|
*addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(*addr).set_type(scalar_string);
|
||||||
|
nasal_gc.get_scalar(*addr).get_string().deep_copy(nasal_gc.get_scalar(now_step_elem_addr).get_string());
|
||||||
|
break;
|
||||||
|
case scalar_function:
|
||||||
|
*addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(*addr).set_type(scalar_function);
|
||||||
|
nasal_gc.get_scalar(*addr).get_function().deep_copy(nasal_gc.get_scalar(now_step_elem_addr).get_function());
|
||||||
|
break;
|
||||||
|
case scalar_vector:
|
||||||
|
case scalar_hash:
|
||||||
|
*addr=now_step_elem_addr;
|
||||||
|
nasal_gc.reference_add(*addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
int state=block_proc(local_scope,*iter);
|
int state=block_proc(local_scope,*iter);
|
||||||
if(state==__state_break)
|
if(state==__state_break)
|
||||||
break;
|
break;
|
||||||
|
@ -1707,12 +2269,36 @@ int nasal_runtime::loop_expr(std::list<std::map<std::string,int> >& local_scope,
|
||||||
else if(state==__state_no_operation)
|
else if(state==__state_no_operation)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
// run block
|
|
||||||
}
|
}
|
||||||
else if(loop_type==__forindex)
|
else if(loop_type==__forindex)
|
||||||
{
|
{
|
||||||
|
// forindex(i;vector)
|
||||||
|
// forindex gives the index of elements in the vector to identifier 'i'
|
||||||
|
// and the 'i' will take part in the calculation
|
||||||
std::list<abstract_syntax_tree>::iterator iter=node.get_children().begin();
|
std::list<abstract_syntax_tree>::iterator iter=node.get_children().begin();
|
||||||
int* addr=NULL;// definition
|
int* addr=NULL;// definition/assignment
|
||||||
|
if(iter->get_node_type()==__definition)
|
||||||
|
{
|
||||||
|
std::string identifier_name=iter->get_children().front().get_var_name();
|
||||||
|
int new_identifier_addr=nasal_gc.gc_alloc();
|
||||||
|
local_scope.back()[identifier_name]=new_identifier_addr;
|
||||||
|
nasal_gc.get_scalar(new_identifier_addr).set_type(scalar_number);
|
||||||
|
nasal_gc.get_scalar(new_identifier_addr).get_number().set_number(0);
|
||||||
|
addr=&(local_scope.back()[identifier_name]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addr=get_identifier_addr(local_scope,*iter);
|
||||||
|
if(addr && *addr>=0)
|
||||||
|
{
|
||||||
|
nasal_gc.reference_delete(*addr);
|
||||||
|
*addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(*addr).set_type(scalar_number);
|
||||||
|
nasal_gc.get_scalar(*addr).get_number().set_number(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!addr)
|
||||||
|
return __state_error;
|
||||||
++iter;
|
++iter;
|
||||||
int vec_addr=calculation(local_scope,*iter);
|
int vec_addr=calculation(local_scope,*iter);
|
||||||
if(vec_addr<0)
|
if(vec_addr<0)
|
||||||
|
@ -1725,7 +2311,7 @@ int nasal_runtime::loop_expr(std::list<std::map<std::string,int> >& local_scope,
|
||||||
++iter;
|
++iter;
|
||||||
for(int i=0;i<nasal_gc.get_scalar(vec_addr).get_vector().get_size();++i)
|
for(int i=0;i<nasal_gc.get_scalar(vec_addr).get_vector().get_size();++i)
|
||||||
{
|
{
|
||||||
;
|
nasal_gc.get_scalar(*addr).get_number().set_number((double)i);
|
||||||
int state=block_proc(local_scope,*iter);
|
int state=block_proc(local_scope,*iter);
|
||||||
if(state==__state_break)
|
if(state==__state_break)
|
||||||
break;
|
break;
|
||||||
|
@ -1738,24 +2324,21 @@ int nasal_runtime::loop_expr(std::list<std::map<std::string,int> >& local_scope,
|
||||||
else if(state==__state_no_operation)
|
else if(state==__state_no_operation)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
// run block
|
|
||||||
}
|
}
|
||||||
else if(loop_type==__for)
|
else if(loop_type==__for)
|
||||||
{
|
{
|
||||||
std::list<abstract_syntax_tree>::iterator iter=node.get_children().begin();
|
std::list<abstract_syntax_tree>::iterator iter=node.get_children().begin();
|
||||||
|
if(iter->get_node_type()!=__null_type)
|
||||||
|
definition(local_scope,local_scope.back(),*iter);
|
||||||
// definition before loop
|
// definition before loop
|
||||||
++iter;
|
++iter; std::list<abstract_syntax_tree>::iterator condition_iterator=iter;
|
||||||
std::list<abstract_syntax_tree>::iterator condition_iterator=iter;
|
|
||||||
// conditional
|
// conditional
|
||||||
++iter;
|
++iter; std::list<abstract_syntax_tree>::iterator step_iterator=iter;
|
||||||
std::list<abstract_syntax_tree>::iterator step_iterator=iter;
|
|
||||||
// step length
|
// step length
|
||||||
++iter;
|
++iter; std::list<abstract_syntax_tree>::iterator block_proc_iterator=iter;
|
||||||
std::list<abstract_syntax_tree>::iterator block_proc_iterator=iter;
|
|
||||||
// run block
|
// run block
|
||||||
while(check_condition(local_scope,*condition_iterator))
|
while(check_condition(local_scope,*condition_iterator))
|
||||||
{
|
{
|
||||||
;
|
|
||||||
int state=block_proc(local_scope,*block_proc_iterator);
|
int state=block_proc(local_scope,*block_proc_iterator);
|
||||||
if(state==__state_break)
|
if(state==__state_break)
|
||||||
break;
|
break;
|
||||||
|
@ -1768,6 +2351,13 @@ int nasal_runtime::loop_expr(std::list<std::map<std::string,int> >& local_scope,
|
||||||
else if(state==__state_no_operation)
|
else if(state==__state_no_operation)
|
||||||
;
|
;
|
||||||
// step update here
|
// step update here
|
||||||
|
if(step_iterator->get_node_type()!=__null_type)
|
||||||
|
{
|
||||||
|
int assign_addr=calculation(local_scope,*step_iterator);
|
||||||
|
if(assign_addr<0)
|
||||||
|
return __state_error;
|
||||||
|
nasal_gc.reference_delete(assign_addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(std::map<std::string,int>::iterator i=local_scope.back().begin();i!=local_scope.back().end();++i)
|
for(std::map<std::string,int>::iterator i=local_scope.back().begin();i!=local_scope.back().end();++i)
|
||||||
|
@ -1875,21 +2465,111 @@ int nasal_runtime::block_proc(std::list<std::map<std::string,int> >& local_scope
|
||||||
state=__state_error;
|
state=__state_error;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(state==__state_break || state==__state_continue || state==__state_return || state==__state_error)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
int nasal_runtime::func_proc(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& parameter_list,abstract_syntax_tree& func_root,int called_hash_addr)
|
int nasal_runtime::func_proc(
|
||||||
|
std::list<std::map<std::string,int> >& local_scope,// running scope,often gets the scope that has been recorded in nasal function
|
||||||
|
abstract_syntax_tree& parameter_list, // parameter list format of nasal function
|
||||||
|
abstract_syntax_tree& func_root, // main runnning block of nasal function
|
||||||
|
abstract_syntax_tree& input_parameters, // input parameters when calling this nasal function
|
||||||
|
int called_hash_addr // if called a hash before calling this nasal function,this address will be given to 'me'
|
||||||
|
)
|
||||||
{
|
{
|
||||||
std::map<std::string,int> new_scope;
|
std::map<std::string,int> new_scope;
|
||||||
local_scope.push_back(new_scope);
|
local_scope.push_back(new_scope);
|
||||||
if(called_hash_addr>=0)
|
if(called_hash_addr>=0)
|
||||||
local_scope.back()["me"]=called_hash_addr;
|
local_scope.back()["me"]=called_hash_addr;
|
||||||
// loading parameters
|
// loading parameters
|
||||||
|
std::vector<std::string> para_name_list;
|
||||||
|
bool has_dynamic_id=false;
|
||||||
|
int dynamic_args=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(dynamic_args).set_type(scalar_vector);
|
||||||
for(std::list<abstract_syntax_tree>::iterator iter=parameter_list.get_children().begin();iter!=parameter_list.get_children().end();++iter)
|
for(std::list<abstract_syntax_tree>::iterator iter=parameter_list.get_children().begin();iter!=parameter_list.get_children().end();++iter)
|
||||||
{
|
{
|
||||||
|
if(iter->get_node_type()==__id)
|
||||||
|
{
|
||||||
|
para_name_list.push_back(iter->get_var_name());
|
||||||
|
local_scope.back()[para_name_list.back()]=-1;
|
||||||
|
}
|
||||||
|
else if(iter->get_node_type()==__default_parameter)
|
||||||
|
{
|
||||||
|
para_name_list.push_back(iter->get_children().front().get_var_name());
|
||||||
|
int default_val_addr=calculation(local_scope,iter->get_children().back());
|
||||||
|
if(default_val_addr<0)
|
||||||
|
return -1;
|
||||||
|
local_scope.back()[para_name_list.back()]=default_val_addr;
|
||||||
|
}
|
||||||
|
else if(iter->get_node_type()==__dynamic_id)
|
||||||
|
{
|
||||||
|
has_dynamic_id=true;
|
||||||
|
local_scope.back()[iter->get_var_name()]=dynamic_args;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if(input_parameters.get_children().front().get_node_type()!=__special_parameter)
|
||||||
|
{
|
||||||
|
int tmp_ptr=0;
|
||||||
|
for(std::list<abstract_syntax_tree>::iterator iter=input_parameters.get_children().begin();iter!=input_parameters.get_children().end();++iter)
|
||||||
|
{
|
||||||
|
if(tmp_ptr>=para_name_list.size())
|
||||||
|
{
|
||||||
|
if(has_dynamic_id)
|
||||||
|
{
|
||||||
|
int val_addr=calculation(local_scope,*iter);
|
||||||
|
if(val_addr<0)
|
||||||
|
return -1;
|
||||||
|
nasal_gc.get_scalar(dynamic_args).get_vector().vec_push(val_addr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int val_addr=calculation(local_scope,*iter);
|
||||||
|
if(val_addr<0)
|
||||||
|
return -1;
|
||||||
|
if(local_scope.back()[para_name_list[tmp_ptr]]<0)
|
||||||
|
local_scope.back()[para_name_list[tmp_ptr]]=val_addr;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nasal_gc.reference_delete(local_scope.back()[para_name_list[tmp_ptr]]);
|
||||||
|
local_scope.back()[para_name_list[tmp_ptr]]=val_addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++tmp_ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else// special parameter f(a:1,b:2)
|
||||||
|
{
|
||||||
|
for(std::list<abstract_syntax_tree>::iterator iter=input_parameters.get_children().begin();iter!=input_parameters.get_children().end();++iter)
|
||||||
|
{
|
||||||
|
std::string tmp_para_name=iter->get_children().front().get_var_name();
|
||||||
|
if(local_scope.back().find(tmp_para_name)!=local_scope.back().end())
|
||||||
|
{
|
||||||
|
int val_addr=calculation(local_scope,iter->get_children().back());
|
||||||
|
if(val_addr<0)
|
||||||
|
return -1;
|
||||||
|
if(local_scope.back()[tmp_para_name]<0)
|
||||||
|
local_scope.back()[tmp_para_name]=val_addr;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nasal_gc.reference_delete(local_scope.back()[tmp_para_name]);
|
||||||
|
local_scope.back()[tmp_para_name]=val_addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int i=0;i<para_name_list.size();++i)
|
||||||
|
if(local_scope.back()[para_name_list[i]]<0)
|
||||||
|
{
|
||||||
|
error_interrupt(__call_function_lack_para,input_parameters.get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
// process
|
// process
|
||||||
|
int ret_addr=-1;
|
||||||
int state=__state_no_operation;
|
int state=__state_no_operation;
|
||||||
for(std::list<abstract_syntax_tree>::iterator iter=func_root.get_children().begin();iter!=func_root.get_children().end();++iter)
|
for(std::list<abstract_syntax_tree>::iterator iter=func_root.get_children().begin();iter!=func_root.get_children().end();++iter)
|
||||||
{
|
{
|
||||||
|
@ -1936,6 +2616,17 @@ int nasal_runtime::func_proc(std::list<std::map<std::string,int> >& local_scope,
|
||||||
state=this->conditional(local_scope,*iter);
|
state=this->conditional(local_scope,*iter);
|
||||||
else if((node_type==__while) || (node_type==__for) || (node_type==__foreach) || (node_type==__forindex))
|
else if((node_type==__while) || (node_type==__for) || (node_type==__foreach) || (node_type==__forindex))
|
||||||
state=this->loop_expr(local_scope,*iter);
|
state=this->loop_expr(local_scope,*iter);
|
||||||
|
else if(node_type==__return)
|
||||||
|
{
|
||||||
|
if(!iter->get_children().size())
|
||||||
|
{
|
||||||
|
ret_addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(ret_addr).set_type(scalar_nil);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret_addr=calculation(local_scope,iter->get_children().front());
|
||||||
|
break;
|
||||||
|
}
|
||||||
if(runtime_error_exit_mark>=0)
|
if(runtime_error_exit_mark>=0)
|
||||||
break;
|
break;
|
||||||
if(state==__state_return)
|
if(state==__state_return)
|
||||||
|
@ -1955,7 +2646,7 @@ int nasal_runtime::func_proc(std::list<std::map<std::string,int> >& local_scope,
|
||||||
else if(state==__state_no_operation)
|
else if(state==__state_no_operation)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
return -1;
|
return ret_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nasal_runtime::main_proc(abstract_syntax_tree& root)
|
void nasal_runtime::main_proc(abstract_syntax_tree& root)
|
||||||
|
|
Loading…
Reference in New Issue