break, continue outside of a loop, match statement handled
This commit is contained in:
parent
00949f0c5f
commit
c076a2b7e9
|
@ -3151,6 +3151,8 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
|
||||||
|
|
||||||
cf_while->body = alloc_node<BlockNode>();
|
cf_while->body = alloc_node<BlockNode>();
|
||||||
cf_while->body->parent_block = p_block;
|
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);
|
p_block->sub_blocks.push_back(cf_while->body);
|
||||||
|
|
||||||
if (!_enter_indent_block(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<BlockNode>();
|
cf_for->body = alloc_node<BlockNode>();
|
||||||
cf_for->body->parent_block = p_block;
|
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);
|
p_block->sub_blocks.push_back(cf_for->body);
|
||||||
|
|
||||||
if (!_enter_indent_block(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);
|
p_block->statements.push_back(cf_for);
|
||||||
} break;
|
} break;
|
||||||
case GDScriptTokenizer::TK_CF_CONTINUE: {
|
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());
|
_mark_line_as_safe(tokenizer->get_token_line());
|
||||||
tokenizer->advance();
|
tokenizer->advance();
|
||||||
ControlFlowNode *cf_continue = alloc_node<ControlFlowNode>();
|
ControlFlowNode *cf_continue = alloc_node<ControlFlowNode>();
|
||||||
|
@ -3319,6 +3338,21 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case GDScriptTokenizer::TK_CF_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());
|
_mark_line_as_safe(tokenizer->get_token_line());
|
||||||
tokenizer->advance();
|
tokenizer->advance();
|
||||||
ControlFlowNode *cf_break = alloc_node<ControlFlowNode>();
|
ControlFlowNode *cf_break = alloc_node<ControlFlowNode>();
|
||||||
|
@ -3384,6 +3418,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
|
||||||
BlockNode *compiled_branches = alloc_node<BlockNode>();
|
BlockNode *compiled_branches = alloc_node<BlockNode>();
|
||||||
compiled_branches->parent_block = p_block;
|
compiled_branches->parent_block = p_block;
|
||||||
compiled_branches->parent_class = p_block->parent_class;
|
compiled_branches->parent_class = p_block->parent_class;
|
||||||
|
compiled_branches->can_continue = true;
|
||||||
|
|
||||||
p_block->sub_blocks.push_back(compiled_branches);
|
p_block->sub_blocks.push_back(compiled_branches);
|
||||||
|
|
||||||
|
|
|
@ -231,6 +231,8 @@ public:
|
||||||
List<Node *> statements;
|
List<Node *> statements;
|
||||||
Map<StringName, LocalVarNode *> variables;
|
Map<StringName, LocalVarNode *> variables;
|
||||||
bool has_return = false;
|
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
|
Node *if_condition = nullptr; //tiny hack to improve code completion on if () blocks
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue