diff --git a/nasal_parse.h b/nasal_parse.h index 0c50686..746a945 100644 --- a/nasal_parse.h +++ b/nasal_parse.h @@ -48,6 +48,8 @@ private: int error; nasal_ast root; std::vector 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() diff --git a/nasal_runtime.h b/nasal_runtime.h index d22621c..d24e78a 100644 --- a/nasal_runtime.h +++ b/nasal_runtime.h @@ -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=0) { ret_value_addr=function_returned_address; diff --git a/test/lexer.nas b/test/lexer.nas index 126ed18..b63e192 100644 --- a/test/lexer.nas +++ b/test/lexer.nas @@ -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; }