From c076a2b7e93b67d99a4b76462e4c4e1d92c738c5 Mon Sep 17 00:00:00 2001 From: Thakee Nathees Date: Mon, 2 Mar 2020 17:02:23 +0530 Subject: break, continue outside of a loop, match statement handled --- modules/gdscript/gdscript_parser.cpp | 35 +++++++++++++++++++++++++++++++++++ modules/gdscript/gdscript_parser.h | 2 ++ 2 files changed, 37 insertions(+) (limited to 'modules/gdscript') diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 57531ed13b..fbb5f91139 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -3151,6 +3151,8 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { cf_while->body = alloc_node(); cf_while->body->parent_block = p_block; + cf_while->body->can_break = true; + cf_while->body->can_continue = true; p_block->sub_blocks.push_back(cf_while->body); if (!_enter_indent_block(cf_while->body)) { @@ -3278,6 +3280,8 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { cf_for->body = alloc_node(); cf_for->body->parent_block = p_block; + cf_for->body->can_break = true; + cf_for->body->can_continue = true; p_block->sub_blocks.push_back(cf_for->body); if (!_enter_indent_block(cf_for->body)) { @@ -3308,6 +3312,21 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { p_block->statements.push_back(cf_for); } break; case GDScriptTokenizer::TK_CF_CONTINUE: { + BlockNode *upper_block = p_block; + bool is_continue_valid = false; + while (upper_block) { + if (upper_block->can_continue) { + is_continue_valid = true; + break; + } + upper_block = upper_block->parent_block; + } + + if (!is_continue_valid) { + _set_error("Unexpected keyword \"continue\" outside a loop."); + return; + } + _mark_line_as_safe(tokenizer->get_token_line()); tokenizer->advance(); ControlFlowNode *cf_continue = alloc_node(); @@ -3319,6 +3338,21 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { } } break; case GDScriptTokenizer::TK_CF_BREAK: { + BlockNode *upper_block = p_block; + bool is_break_valid = false; + while (upper_block) { + if (upper_block->can_break) { + is_break_valid = true; + break; + } + upper_block = upper_block->parent_block; + } + + if (!is_break_valid) { + _set_error("Unexpected keyword \"break\" outside a loop."); + return; + } + _mark_line_as_safe(tokenizer->get_token_line()); tokenizer->advance(); ControlFlowNode *cf_break = alloc_node(); @@ -3384,6 +3418,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { BlockNode *compiled_branches = alloc_node(); compiled_branches->parent_block = p_block; compiled_branches->parent_class = p_block->parent_class; + compiled_branches->can_continue = true; p_block->sub_blocks.push_back(compiled_branches); diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index cfcca9584e..7dedb6d6f9 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -231,6 +231,8 @@ public: List statements; Map variables; bool has_return = false; + bool can_break = false; + bool can_continue = false; Node *if_condition = nullptr; //tiny hack to improve code completion on if () blocks -- cgit v1.2.3