update
This commit is contained in:
parent
1625f241fa
commit
4a5083f5cf
|
@ -48,6 +48,8 @@ private:
|
||||||
int error;
|
int error;
|
||||||
nasal_ast root;
|
nasal_ast root;
|
||||||
std::vector<token> tok_list;
|
std::vector<token> tok_list;
|
||||||
|
int in_function; // count when generating function block,used to check return-expression
|
||||||
|
int in_loop; // count when generating loop block,used to check break/continue-expression
|
||||||
void reset();
|
void reset();
|
||||||
void die(int,std::string);
|
void die(int,std::string);
|
||||||
bool check_multi_definition();
|
bool check_multi_definition();
|
||||||
|
@ -114,6 +116,8 @@ void nasal_parse::clear()
|
||||||
this->tok_list_size=0;
|
this->tok_list_size=0;
|
||||||
this->ptr=0;
|
this->ptr=0;
|
||||||
this->error=0;
|
this->error=0;
|
||||||
|
this->in_function=0;
|
||||||
|
this->in_loop=0;
|
||||||
this->tok_list.clear();
|
this->tok_list.clear();
|
||||||
this->root.clear();
|
this->root.clear();
|
||||||
return;
|
return;
|
||||||
|
@ -166,6 +170,8 @@ nasal_ast& nasal_parse::get_root()
|
||||||
void nasal_parse::reset()
|
void nasal_parse::reset()
|
||||||
{
|
{
|
||||||
this->ptr=0;
|
this->ptr=0;
|
||||||
|
this->in_function=0;
|
||||||
|
this->in_loop=0;
|
||||||
this->error=0;
|
this->error=0;
|
||||||
this->root.clear();
|
this->root.clear();
|
||||||
return;
|
return;
|
||||||
|
@ -521,7 +527,18 @@ nasal_ast nasal_parse::expr()
|
||||||
{
|
{
|
||||||
nasal_ast node;
|
nasal_ast node;
|
||||||
node.set_line(tok_list[ptr].line);
|
node.set_line(tok_list[ptr].line);
|
||||||
switch(tok_list[ptr].type)
|
int tok_type=tok_list[ptr].type;
|
||||||
|
if((tok_type==tok_break || tok_type==tok_continue) && !in_loop)
|
||||||
|
{
|
||||||
|
die(error_line,"cannot use break/continue outside loop");
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
if(tok_type==tok_return && !in_function)
|
||||||
|
{
|
||||||
|
die(error_line,"cannot use return outside function");
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
switch(tok_type)
|
||||||
{
|
{
|
||||||
case tok_nil:
|
case tok_nil:
|
||||||
case tok_number:
|
case tok_number:
|
||||||
|
@ -916,7 +933,11 @@ nasal_ast nasal_parse::scalar()
|
||||||
node=id_gen();
|
node=id_gen();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
++in_function;
|
||||||
node=func_gen();
|
node=func_gen();
|
||||||
|
--in_function;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(tok_list[ptr].type==tok_left_bracket)
|
else if(tok_list[ptr].type==tok_left_bracket)
|
||||||
node=vector_gen();
|
node=vector_gen();
|
||||||
|
@ -1204,6 +1225,7 @@ nasal_ast nasal_parse::multi_assgin()
|
||||||
}
|
}
|
||||||
nasal_ast nasal_parse::loop()
|
nasal_ast nasal_parse::loop()
|
||||||
{
|
{
|
||||||
|
++in_loop;
|
||||||
nasal_ast node;
|
nasal_ast node;
|
||||||
switch(tok_list[ptr].type)
|
switch(tok_list[ptr].type)
|
||||||
{
|
{
|
||||||
|
@ -1212,6 +1234,7 @@ nasal_ast nasal_parse::loop()
|
||||||
case tok_forindex:
|
case tok_forindex:
|
||||||
case tok_foreach: node=forei_loop(); break;
|
case tok_foreach: node=forei_loop(); break;
|
||||||
}
|
}
|
||||||
|
--in_loop;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
nasal_ast nasal_parse::while_loop()
|
nasal_ast nasal_parse::while_loop()
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
enum runtime_returned_state
|
enum runtime_returned_state
|
||||||
{
|
{
|
||||||
rt_return=1,
|
rt_return=1,
|
||||||
|
rt_error,
|
||||||
rt_break,
|
rt_break,
|
||||||
rt_continue,
|
rt_continue,
|
||||||
rt_error,
|
|
||||||
rt_exit_without_error
|
rt_exit_without_error
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -38,16 +38,16 @@ private:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// main expression block running process
|
// main expression block running process
|
||||||
int main_progress();
|
void main_progress();
|
||||||
// function/loop/conditional expression block running process
|
// function/loop/conditional expression block running process
|
||||||
int block_progress(nasal_ast&,int,bool);
|
int block_progress(nasal_ast&,int);
|
||||||
// run loop
|
// run loop
|
||||||
int before_for_loop(nasal_ast&,int);
|
void before_for_loop(nasal_ast&,int);
|
||||||
int after_each_for_loop(nasal_ast&,int);
|
void after_each_for_loop(nasal_ast&,int);
|
||||||
int loop_progress(nasal_ast&,int,bool);
|
int loop_progress(nasal_ast&,int);
|
||||||
// run conditional
|
// run conditional
|
||||||
bool check_condition(int);
|
bool check_condition(int);
|
||||||
int conditional_progress(nasal_ast&,int,bool);
|
int conditional_progress(nasal_ast&,int);
|
||||||
// get scalars in complex data structure like vector/hash/function/closure(scope)
|
// get scalars in complex data structure like vector/hash/function/closure(scope)
|
||||||
int call_scalar(nasal_ast&,int);
|
int call_scalar(nasal_ast&,int);
|
||||||
int call_vector(nasal_ast&,int,int);
|
int call_vector(nasal_ast&,int,int);
|
||||||
|
@ -194,7 +194,7 @@ void nasal_runtime::run()
|
||||||
nasal_vm.gc_get(global_scope_address).get_closure().add_scope();
|
nasal_vm.gc_get(global_scope_address).get_closure().add_scope();
|
||||||
|
|
||||||
time_t begin_time=std::time(NULL);
|
time_t begin_time=std::time(NULL);
|
||||||
int returned_statement=main_progress();
|
main_progress();
|
||||||
time_t end_time=std::time(NULL);
|
time_t end_time=std::time(NULL);
|
||||||
|
|
||||||
nasal_vm.gc_get(global_scope_address).get_closure().del_scope();
|
nasal_vm.gc_get(global_scope_address).get_closure().del_scope();
|
||||||
|
@ -249,9 +249,8 @@ int nasal_runtime::function_generation(nasal_ast& node,int local_scope_addr)
|
||||||
}
|
}
|
||||||
return new_addr;
|
return new_addr;
|
||||||
}
|
}
|
||||||
int nasal_runtime::main_progress()
|
void nasal_runtime::main_progress()
|
||||||
{
|
{
|
||||||
int ret_state=rt_exit_without_error;
|
|
||||||
int expr_number=root.get_children().size();
|
int expr_number=root.get_children().size();
|
||||||
int process_returned_value_addr=-1;
|
int process_returned_value_addr=-1;
|
||||||
for(int i=0;i<expr_number;++i)
|
for(int i=0;i<expr_number;++i)
|
||||||
|
@ -262,9 +261,9 @@ int nasal_runtime::main_progress()
|
||||||
{
|
{
|
||||||
case ast_definition:definition(node,-1);break;
|
case ast_definition:definition(node,-1);break;
|
||||||
case ast_multi_assign:multi_assignment(node,-1);break;
|
case ast_multi_assign:multi_assignment(node,-1);break;
|
||||||
case ast_conditional:ret_state=conditional_progress(node,-1,false);break;
|
case ast_conditional:conditional_progress(node,-1);break;
|
||||||
case ast_while:case ast_for:case ast_forindex:case ast_foreach:
|
case ast_while:case ast_for:case ast_forindex:case ast_foreach:
|
||||||
ret_state=loop_progress(node,-1,false);break;
|
loop_progress(node,-1);break;
|
||||||
case ast_nil:case ast_number:case ast_string:case ast_function:break;
|
case ast_nil:case ast_number:case ast_string:case ast_function:break;
|
||||||
case ast_identifier:
|
case ast_identifier:
|
||||||
case ast_vector:case ast_hash:
|
case ast_vector:case ast_hash:
|
||||||
|
@ -275,14 +274,11 @@ int nasal_runtime::main_progress()
|
||||||
case ast_trinocular:nasal_vm.del_reference(calculation(node,-1));break;
|
case ast_trinocular:nasal_vm.del_reference(calculation(node,-1));break;
|
||||||
}
|
}
|
||||||
if(error)
|
if(error)
|
||||||
{
|
|
||||||
ret_state=rt_error;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ret_state;
|
return;
|
||||||
}
|
}
|
||||||
int nasal_runtime::block_progress(nasal_ast& node,int local_scope_addr,bool allow_return)
|
int nasal_runtime::block_progress(nasal_ast& node,int local_scope_addr)
|
||||||
{
|
{
|
||||||
int ret_state=rt_exit_without_error;
|
int ret_state=rt_exit_without_error;
|
||||||
// if local_scope does not exist,create a new one.
|
// if local_scope does not exist,create a new one.
|
||||||
|
@ -306,9 +302,9 @@ int nasal_runtime::block_progress(nasal_ast& node,int local_scope_addr,bool allo
|
||||||
{
|
{
|
||||||
case ast_definition:definition(tmp_node,local_scope_addr);break;
|
case ast_definition:definition(tmp_node,local_scope_addr);break;
|
||||||
case ast_multi_assign:multi_assignment(tmp_node,local_scope_addr);break;
|
case ast_multi_assign:multi_assignment(tmp_node,local_scope_addr);break;
|
||||||
case ast_conditional:ret_state=conditional_progress(tmp_node,local_scope_addr,allow_return);break;
|
case ast_conditional:ret_state=conditional_progress(tmp_node,local_scope_addr);break;
|
||||||
case ast_while:case ast_for:case ast_forindex:case ast_foreach:
|
case ast_while:case ast_for:case ast_forindex:case ast_foreach:
|
||||||
ret_state=loop_progress(tmp_node,local_scope_addr,allow_return);break;
|
ret_state=loop_progress(tmp_node,local_scope_addr);break;
|
||||||
case ast_nil:case ast_number:case ast_string:case ast_function:break;
|
case ast_nil:case ast_number:case ast_string:case ast_function:break;
|
||||||
case ast_identifier:
|
case ast_identifier:
|
||||||
case ast_vector:case ast_hash:
|
case ast_vector:case ast_hash:
|
||||||
|
@ -321,15 +317,10 @@ int nasal_runtime::block_progress(nasal_ast& node,int local_scope_addr,bool allo
|
||||||
case ast_continue:ret_state=rt_continue;break;
|
case ast_continue:ret_state=rt_continue;break;
|
||||||
case ast_return:
|
case ast_return:
|
||||||
ret_state=rt_return;
|
ret_state=rt_return;
|
||||||
if(allow_return)
|
if(tmp_node.get_children().size())
|
||||||
{
|
function_returned_address=calculation(tmp_node.get_children()[0],local_scope_addr);
|
||||||
if(tmp_node.get_children().size())
|
|
||||||
function_returned_address=calculation(tmp_node.get_children()[0],local_scope_addr);
|
|
||||||
else
|
|
||||||
function_returned_address=nasal_vm.gc_alloc(vm_nil);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
die(tmp_node.get_line(),"cannot use return here");
|
function_returned_address=nasal_vm.gc_alloc(vm_nil);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(error || ret_state==rt_break || ret_state==rt_continue || ret_state==rt_return)
|
if(error || ret_state==rt_break || ret_state==rt_continue || ret_state==rt_return)
|
||||||
|
@ -339,7 +330,7 @@ int nasal_runtime::block_progress(nasal_ast& node,int local_scope_addr,bool allo
|
||||||
nasal_vm.del_reference(local_scope_addr);
|
nasal_vm.del_reference(local_scope_addr);
|
||||||
return ret_state;
|
return ret_state;
|
||||||
}
|
}
|
||||||
int nasal_runtime::before_for_loop(nasal_ast& node,int local_scope_addr)
|
void nasal_runtime::before_for_loop(nasal_ast& node,int local_scope_addr)
|
||||||
{
|
{
|
||||||
int before_loop_node_type=node.get_type();
|
int before_loop_node_type=node.get_type();
|
||||||
switch(before_loop_node_type)
|
switch(before_loop_node_type)
|
||||||
|
@ -356,11 +347,9 @@ int nasal_runtime::before_for_loop(nasal_ast& node,int local_scope_addr)
|
||||||
case ast_trinocular:nasal_vm.del_reference(calculation(node,local_scope_addr));break;
|
case ast_trinocular:nasal_vm.del_reference(calculation(node,local_scope_addr));break;
|
||||||
default:die(node.get_line(),"cannot use this expression before for-loop");break;
|
default:die(node.get_line(),"cannot use this expression before for-loop");break;
|
||||||
}
|
}
|
||||||
if(error)
|
return;
|
||||||
return rt_error;
|
|
||||||
return rt_exit_without_error;
|
|
||||||
}
|
}
|
||||||
int nasal_runtime::after_each_for_loop(nasal_ast& node,int local_scope_addr)
|
void nasal_runtime::after_each_for_loop(nasal_ast& node,int local_scope_addr)
|
||||||
{
|
{
|
||||||
int node_type=node.get_type();
|
int node_type=node.get_type();
|
||||||
switch(node_type)
|
switch(node_type)
|
||||||
|
@ -377,11 +366,9 @@ int nasal_runtime::after_each_for_loop(nasal_ast& node,int local_scope_addr)
|
||||||
case ast_trinocular:nasal_vm.del_reference(calculation(node,local_scope_addr));break;
|
case ast_trinocular:nasal_vm.del_reference(calculation(node,local_scope_addr));break;
|
||||||
default:die(node.get_line(),"cannot use this expression after each for-loop");break;
|
default:die(node.get_line(),"cannot use this expression after each for-loop");break;
|
||||||
}
|
}
|
||||||
if(error)
|
return;
|
||||||
return rt_error;
|
|
||||||
return rt_exit_without_error;
|
|
||||||
}
|
}
|
||||||
int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr,bool allow_return)
|
int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr)
|
||||||
{
|
{
|
||||||
int ret_state=rt_exit_without_error;
|
int ret_state=rt_exit_without_error;
|
||||||
int loop_type=node.get_type();
|
int loop_type=node.get_type();
|
||||||
|
@ -408,8 +395,8 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr,bool allow
|
||||||
while(result)
|
while(result)
|
||||||
{
|
{
|
||||||
// return expression will be checked in block_progress
|
// return expression will be checked in block_progress
|
||||||
ret_state=block_progress(run_block_node,local_scope_addr,allow_return);
|
ret_state=block_progress(run_block_node,local_scope_addr);
|
||||||
if(ret_state==rt_break || ret_state==rt_error || ret_state==rt_return || error)
|
if(ret_state==rt_break || ret_state==rt_return || error)
|
||||||
break;
|
break;
|
||||||
condition_value_addr=calculation(condition_node,while_local_scope_addr);
|
condition_value_addr=calculation(condition_node,while_local_scope_addr);
|
||||||
result=check_condition(condition_value_addr);
|
result=check_condition(condition_value_addr);
|
||||||
|
@ -475,8 +462,8 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr,bool allow
|
||||||
nasal_vm.add_reference(value_addr);
|
nasal_vm.add_reference(value_addr);
|
||||||
nasal_vm.mem_change(mem_addr,value_addr);
|
nasal_vm.mem_change(mem_addr,value_addr);
|
||||||
}
|
}
|
||||||
ret_state=block_progress(run_block_node,forei_local_scope_addr,allow_return);
|
ret_state=block_progress(run_block_node,forei_local_scope_addr);
|
||||||
if(ret_state==rt_break || ret_state==rt_return || ret_state==rt_error || error)
|
if(ret_state==rt_break || ret_state==rt_return || error)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
nasal_vm.del_reference(vector_value_addr);
|
nasal_vm.del_reference(vector_value_addr);
|
||||||
|
@ -503,18 +490,18 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr,bool allow
|
||||||
nasal_vm.gc_get(for_local_scope_addr).get_closure().add_scope();
|
nasal_vm.gc_get(for_local_scope_addr).get_closure().add_scope();
|
||||||
}
|
}
|
||||||
// for progress
|
// for progress
|
||||||
ret_state=before_for_loop(before_loop_node,for_local_scope_addr);
|
before_for_loop(before_loop_node,for_local_scope_addr);
|
||||||
int condition_value_addr=calculation(condition_node,for_local_scope_addr);
|
int condition_value_addr=calculation(condition_node,for_local_scope_addr);
|
||||||
bool result=check_condition(condition_value_addr);
|
bool result=check_condition(condition_value_addr);
|
||||||
nasal_vm.del_reference(condition_value_addr);
|
nasal_vm.del_reference(condition_value_addr);
|
||||||
while(result)
|
while(result)
|
||||||
{
|
{
|
||||||
if(ret_state==rt_error)
|
if(error)
|
||||||
break;
|
break;
|
||||||
ret_state=block_progress(run_block_node,for_local_scope_addr,allow_return);
|
ret_state=block_progress(run_block_node,for_local_scope_addr);
|
||||||
if(ret_state==rt_error || ret_state==rt_return || ret_state==rt_break || error)
|
if(ret_state==rt_return || ret_state==rt_break || error)
|
||||||
break;
|
break;
|
||||||
ret_state=after_each_for_loop(each_loop_do_node,for_local_scope_addr);
|
after_each_for_loop(each_loop_do_node,for_local_scope_addr);
|
||||||
condition_value_addr=calculation(condition_node,for_local_scope_addr);
|
condition_value_addr=calculation(condition_node,for_local_scope_addr);
|
||||||
result=check_condition(condition_value_addr);
|
result=check_condition(condition_value_addr);
|
||||||
nasal_vm.del_reference(condition_value_addr);
|
nasal_vm.del_reference(condition_value_addr);
|
||||||
|
@ -545,7 +532,7 @@ bool nasal_runtime::check_condition(int value_addr)
|
||||||
return (nasal_vm.gc_get(value_addr).get_number()!=0);
|
return (nasal_vm.gc_get(value_addr).get_number()!=0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int nasal_runtime::conditional_progress(nasal_ast& node,int local_scope_addr,bool allow_return)
|
int nasal_runtime::conditional_progress(nasal_ast& node,int local_scope_addr)
|
||||||
{
|
{
|
||||||
int ret_state=rt_exit_without_error;
|
int ret_state=rt_exit_without_error;
|
||||||
int size=node.get_children().size();
|
int size=node.get_children().size();
|
||||||
|
@ -557,18 +544,21 @@ int nasal_runtime::conditional_progress(nasal_ast& node,int local_scope_addr,boo
|
||||||
{
|
{
|
||||||
int condition_value_addr=calculation(tmp_node.get_children()[0],local_scope_addr);
|
int condition_value_addr=calculation(tmp_node.get_children()[0],local_scope_addr);
|
||||||
if(condition_value_addr<0)
|
if(condition_value_addr<0)
|
||||||
|
{
|
||||||
|
die(tmp_node.get_children()[0].get_line(),"cannot check condition of this value");
|
||||||
return rt_error;
|
return rt_error;
|
||||||
|
}
|
||||||
bool result=check_condition(condition_value_addr);
|
bool result=check_condition(condition_value_addr);
|
||||||
nasal_vm.del_reference(condition_value_addr);
|
nasal_vm.del_reference(condition_value_addr);
|
||||||
if(result)
|
if(result)
|
||||||
{
|
{
|
||||||
ret_state=block_progress(tmp_node.get_children()[1],local_scope_addr,allow_return);
|
ret_state=block_progress(tmp_node.get_children()[1],local_scope_addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret_state=block_progress(tmp_node.get_children()[0],local_scope_addr,allow_return);
|
ret_state=block_progress(tmp_node.get_children()[0],local_scope_addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(error)
|
if(error)
|
||||||
|
@ -1035,17 +1025,9 @@ int nasal_runtime::call_function(nasal_ast& node,std::string func_name,int base_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int ret_state=block_progress(reference_of_func.get_run_block(),run_closure_addr,true);
|
block_progress(reference_of_func.get_run_block(),run_closure_addr);
|
||||||
run_closure.del_scope();
|
run_closure.del_scope();
|
||||||
|
|
||||||
if(ret_state==rt_break || ret_state==rt_continue)
|
|
||||||
{
|
|
||||||
die(node.get_line(),"cannot use break/continue in function main block");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else if(ret_state==rt_error)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if(function_returned_address>=0)
|
if(function_returned_address>=0)
|
||||||
{
|
{
|
||||||
ret_value_addr=function_returned_address;
|
ret_value_addr=function_returned_address;
|
||||||
|
|
|
@ -59,10 +59,7 @@ var generate_str=func()
|
||||||
ptr+=1;
|
ptr+=1;
|
||||||
}
|
}
|
||||||
if(ptr>=len)
|
if(ptr>=len)
|
||||||
{
|
|
||||||
print("read eof when generating string.");
|
print("read eof when generating string.");
|
||||||
break;
|
|
||||||
}
|
|
||||||
ptr+=1;
|
ptr+=1;
|
||||||
return tok_str;
|
return tok_str;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue