From 9ee77179b563ea924f85f372c59c48484cd39cd8 Mon Sep 17 00:00:00 2001 From: Thakee Nathees Date: Mon, 2 Mar 2020 17:02:23 +0530 Subject: [PATCH] break, continue outside of a loop, match statement handled (cherry picked from commit c076a2b7e93b67d99a4b76462e4c4e1d92c738c5) --- modules/gdscript/gdscript_parser.cpp | 33 ++++++++++++++++++++++++++++ modules/gdscript/gdscript_parser.h | 5 +++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 1b9d57f6970..7f5e739b6af 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -3092,6 +3092,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)) { @@ -3211,6 +3213,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)) { @@ -3240,6 +3244,20 @@ 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(); @@ -3252,6 +3270,20 @@ 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(); @@ -3320,6 +3352,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 343a237545e..b785c9b5576 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -240,7 +240,9 @@ public: BlockNode *parent_block; List statements; Map variables; - bool has_return; + bool has_return = false; + bool can_break = false; + bool can_continue = false; Node *if_condition; //tiny hack to improve code completion on if () blocks @@ -253,7 +255,6 @@ public: end_line = -1; parent_block = NULL; parent_class = NULL; - has_return = false; } };