update
This commit is contained in:
parent
1625f241fa
commit
4a5083f5cf
|
@ -48,6 +48,8 @@ private:
|
|||
int error;
|
||||
nasal_ast root;
|
||||
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 die(int,std::string);
|
||||
bool check_multi_definition();
|
||||
|
@ -114,6 +116,8 @@ void nasal_parse::clear()
|
|||
this->tok_list_size=0;
|
||||
this->ptr=0;
|
||||
this->error=0;
|
||||
this->in_function=0;
|
||||
this->in_loop=0;
|
||||
this->tok_list.clear();
|
||||
this->root.clear();
|
||||
return;
|
||||
|
@ -166,6 +170,8 @@ nasal_ast& nasal_parse::get_root()
|
|||
void nasal_parse::reset()
|
||||
{
|
||||
this->ptr=0;
|
||||
this->in_function=0;
|
||||
this->in_loop=0;
|
||||
this->error=0;
|
||||
this->root.clear();
|
||||
return;
|
||||
|
@ -521,7 +527,18 @@ nasal_ast nasal_parse::expr()
|
|||
{
|
||||
nasal_ast node;
|
||||
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_number:
|
||||
|
@ -916,7 +933,11 @@ nasal_ast nasal_parse::scalar()
|
|||
node=id_gen();
|
||||
}
|
||||
else
|
||||
{
|
||||
++in_function;
|
||||
node=func_gen();
|
||||
--in_function;
|
||||
}
|
||||
}
|
||||
else if(tok_list[ptr].type==tok_left_bracket)
|
||||
node=vector_gen();
|
||||
|
@ -1204,6 +1225,7 @@ nasal_ast nasal_parse::multi_assgin()
|
|||
}
|
||||
nasal_ast nasal_parse::loop()
|
||||
{
|
||||
++in_loop;
|
||||
nasal_ast node;
|
||||
switch(tok_list[ptr].type)
|
||||
{
|
||||
|
@ -1212,6 +1234,7 @@ nasal_ast nasal_parse::loop()
|
|||
case tok_forindex:
|
||||
case tok_foreach: node=forei_loop(); break;
|
||||
}
|
||||
--in_loop;
|
||||
return node;
|
||||
}
|
||||
nasal_ast nasal_parse::while_loop()
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
enum runtime_returned_state
|
||||
{
|
||||
rt_return=1,
|
||||
rt_error,
|
||||
rt_break,
|
||||
rt_continue,
|
||||
rt_error,
|
||||
rt_exit_without_error
|
||||
};
|
||||
|
||||
|
@ -38,16 +38,16 @@ private:
|
|||
*/
|
||||
|
||||
// main expression block running process
|
||||
int main_progress();
|
||||
void main_progress();
|
||||
// function/loop/conditional expression block running process
|
||||
int block_progress(nasal_ast&,int,bool);
|
||||
int block_progress(nasal_ast&,int);
|
||||
// run loop
|
||||
int before_for_loop(nasal_ast&,int);
|
||||
int after_each_for_loop(nasal_ast&,int);
|
||||
int loop_progress(nasal_ast&,int,bool);
|
||||
void before_for_loop(nasal_ast&,int);
|
||||
void after_each_for_loop(nasal_ast&,int);
|
||||
int loop_progress(nasal_ast&,int);
|
||||
// run conditional
|
||||
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)
|
||||
int call_scalar(nasal_ast&,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();
|
||||
|
||||
time_t begin_time=std::time(NULL);
|
||||
int returned_statement=main_progress();
|
||||
main_progress();
|
||||
time_t end_time=std::time(NULL);
|
||||
|
||||
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;
|
||||
}
|
||||
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 process_returned_value_addr=-1;
|
||||
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_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:
|
||||
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_identifier:
|
||||
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;
|
||||
}
|
||||
if(error)
|
||||
{
|
||||
ret_state=rt_error;
|
||||
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;
|
||||
// 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_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:
|
||||
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_identifier:
|
||||
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_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);
|
||||
else
|
||||
function_returned_address=nasal_vm.gc_alloc(vm_nil);
|
||||
}
|
||||
if(tmp_node.get_children().size())
|
||||
function_returned_address=calculation(tmp_node.get_children()[0],local_scope_addr);
|
||||
else
|
||||
die(tmp_node.get_line(),"cannot use return here");
|
||||
function_returned_address=nasal_vm.gc_alloc(vm_nil);
|
||||
break;
|
||||
}
|
||||
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);
|
||||
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();
|
||||
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;
|
||||
default:die(node.get_line(),"cannot use this expression before for-loop");break;
|
||||
}
|
||||
if(error)
|
||||
return rt_error;
|
||||
return rt_exit_without_error;
|
||||
return;
|
||||
}
|
||||
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();
|
||||
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;
|
||||
default:die(node.get_line(),"cannot use this expression after each for-loop");break;
|
||||
}
|
||||
if(error)
|
||||
return rt_error;
|
||||
return rt_exit_without_error;
|
||||
return;
|
||||
}
|
||||
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 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)
|
||||
{
|
||||
// return expression will be checked in block_progress
|
||||
ret_state=block_progress(run_block_node,local_scope_addr,allow_return);
|
||||
if(ret_state==rt_break || ret_state==rt_error || ret_state==rt_return || error)
|
||||
ret_state=block_progress(run_block_node,local_scope_addr);
|
||||
if(ret_state==rt_break || ret_state==rt_return || error)
|
||||
break;
|
||||
condition_value_addr=calculation(condition_node,while_local_scope_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.mem_change(mem_addr,value_addr);
|
||||
}
|
||||
ret_state=block_progress(run_block_node,forei_local_scope_addr,allow_return);
|
||||
if(ret_state==rt_break || ret_state==rt_return || ret_state==rt_error || error)
|
||||
ret_state=block_progress(run_block_node,forei_local_scope_addr);
|
||||
if(ret_state==rt_break || ret_state==rt_return || error)
|
||||
break;
|
||||
}
|
||||
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();
|
||||
}
|
||||
// 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);
|
||||
bool result=check_condition(condition_value_addr);
|
||||
nasal_vm.del_reference(condition_value_addr);
|
||||
while(result)
|
||||
{
|
||||
if(ret_state==rt_error)
|
||||
if(error)
|
||||
break;
|
||||
ret_state=block_progress(run_block_node,for_local_scope_addr,allow_return);
|
||||
if(ret_state==rt_error || ret_state==rt_return || ret_state==rt_break || error)
|
||||
ret_state=block_progress(run_block_node,for_local_scope_addr);
|
||||
if(ret_state==rt_return || ret_state==rt_break || error)
|
||||
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);
|
||||
result=check_condition(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 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 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);
|
||||
if(condition_value_addr<0)
|
||||
{
|
||||
die(tmp_node.get_children()[0].get_line(),"cannot check condition of this value");
|
||||
return rt_error;
|
||||
}
|
||||
bool result=check_condition(condition_value_addr);
|
||||
nasal_vm.del_reference(condition_value_addr);
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
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();
|
||||
|
||||
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)
|
||||
{
|
||||
ret_value_addr=function_returned_address;
|
||||
|
|
|
@ -59,10 +59,7 @@ var generate_str=func()
|
|||
ptr+=1;
|
||||
}
|
||||
if(ptr>=len)
|
||||
{
|
||||
print("read eof when generating string.");
|
||||
break;
|
||||
}
|
||||
ptr+=1;
|
||||
return tok_str;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue