1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-13 13:31:48 +00:00

Merge pull request #71914 from vnen/gdscript-no-continue-match

GDScript: Remove function of `continue` for match statement
This commit is contained in:
Rémi Verschelde
2023-01-23 15:35:55 +01:00
10 changed files with 5 additions and 76 deletions

View File

@@ -1543,28 +1543,6 @@ void GDScriptByteCodeGenerator::write_endwhile() {
current_breaks_to_patch.pop_back(); current_breaks_to_patch.pop_back();
} }
void GDScriptByteCodeGenerator::start_match() {
match_continues_to_patch.push_back(List<int>());
}
void GDScriptByteCodeGenerator::start_match_branch() {
// Patch continue statements.
for (const int &E : match_continues_to_patch.back()->get()) {
patch_jump(E);
}
match_continues_to_patch.pop_back();
// Start a new list for next branch.
match_continues_to_patch.push_back(List<int>());
}
void GDScriptByteCodeGenerator::end_match() {
// Patch continue statements.
for (const int &E : match_continues_to_patch.back()->get()) {
patch_jump(E);
}
match_continues_to_patch.pop_back();
}
void GDScriptByteCodeGenerator::write_break() { void GDScriptByteCodeGenerator::write_break() {
append_opcode(GDScriptFunction::OPCODE_JUMP); append_opcode(GDScriptFunction::OPCODE_JUMP);
current_breaks_to_patch.back()->get().push_back(opcodes.size()); current_breaks_to_patch.back()->get().push_back(opcodes.size());
@@ -1576,12 +1554,6 @@ void GDScriptByteCodeGenerator::write_continue() {
append(continue_addrs.back()->get()); append(continue_addrs.back()->get());
} }
void GDScriptByteCodeGenerator::write_continue_match() {
append_opcode(GDScriptFunction::OPCODE_JUMP);
match_continues_to_patch.back()->get().push_back(opcodes.size());
append(0);
}
void GDScriptByteCodeGenerator::write_breakpoint() { void GDScriptByteCodeGenerator::write_breakpoint() {
append_opcode(GDScriptFunction::OPCODE_BREAKPOINT); append_opcode(GDScriptFunction::OPCODE_BREAKPOINT);
} }

View File

@@ -113,7 +113,6 @@ class GDScriptByteCodeGenerator : public GDScriptCodeGenerator {
List<int> ternary_jump_skip_pos; List<int> ternary_jump_skip_pos;
List<List<int>> current_breaks_to_patch; List<List<int>> current_breaks_to_patch;
List<List<int>> match_continues_to_patch;
void add_stack_identifier(const StringName &p_id, int p_stackpos) { void add_stack_identifier(const StringName &p_id, int p_stackpos) {
if (locals.size() > max_locals) { if (locals.size() > max_locals) {
@@ -496,12 +495,8 @@ public:
virtual void start_while_condition() override; virtual void start_while_condition() override;
virtual void write_while(const Address &p_condition) override; virtual void write_while(const Address &p_condition) override;
virtual void write_endwhile() override; virtual void write_endwhile() override;
virtual void start_match() override;
virtual void start_match_branch() override;
virtual void end_match() override;
virtual void write_break() override; virtual void write_break() override;
virtual void write_continue() override; virtual void write_continue() override;
virtual void write_continue_match() override;
virtual void write_breakpoint() override; virtual void write_breakpoint() override;
virtual void write_newline(int p_line) override; virtual void write_newline(int p_line) override;
virtual void write_return(const Address &p_return_value) override; virtual void write_return(const Address &p_return_value) override;

View File

@@ -148,12 +148,8 @@ public:
virtual void start_while_condition() = 0; // Used to allow a jump to the expression evaluation. virtual void start_while_condition() = 0; // Used to allow a jump to the expression evaluation.
virtual void write_while(const Address &p_condition) = 0; virtual void write_while(const Address &p_condition) = 0;
virtual void write_endwhile() = 0; virtual void write_endwhile() = 0;
virtual void start_match() = 0;
virtual void start_match_branch() = 0;
virtual void end_match() = 0;
virtual void write_break() = 0; virtual void write_break() = 0;
virtual void write_continue() = 0; virtual void write_continue() = 0;
virtual void write_continue_match() = 0;
virtual void write_breakpoint() = 0; virtual void write_breakpoint() = 0;
virtual void write_newline(int p_line) = 0; virtual void write_newline(int p_line) = 0;
virtual void write_return(const Address &p_return_value) = 0; virtual void write_return(const Address &p_return_value) = 0;

View File

@@ -1679,7 +1679,6 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui
case GDScriptParser::Node::MATCH: { case GDScriptParser::Node::MATCH: {
const GDScriptParser::MatchNode *match = static_cast<const GDScriptParser::MatchNode *>(s); const GDScriptParser::MatchNode *match = static_cast<const GDScriptParser::MatchNode *>(s);
gen->start_match();
codegen.start_block(); codegen.start_block();
// Evaluate the match expression. // Evaluate the match expression.
@@ -1718,7 +1717,6 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui
const GDScriptParser::MatchBranchNode *branch = match->branches[j]; const GDScriptParser::MatchBranchNode *branch = match->branches[j];
gen->start_match_branch(); // Need so lower level code can patch 'continue' jumps.
codegen.start_block(); // Create an extra block around for binds. codegen.start_block(); // Create an extra block around for binds.
// Add locals in block before patterns, so temporaries don't use the stack address for binds. // Add locals in block before patterns, so temporaries don't use the stack address for binds.
@@ -1756,8 +1754,6 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui
for (int j = 0; j < match->branches.size(); j++) { for (int j = 0; j < match->branches.size(); j++) {
gen->write_endif(); gen->write_endif();
} }
gen->end_match();
} break; } break;
case GDScriptParser::Node::IF: { case GDScriptParser::Node::IF: {
const GDScriptParser::IfNode *if_n = static_cast<const GDScriptParser::IfNode *>(s); const GDScriptParser::IfNode *if_n = static_cast<const GDScriptParser::IfNode *>(s);
@@ -1845,12 +1841,7 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui
gen->write_break(); gen->write_break();
} break; } break;
case GDScriptParser::Node::CONTINUE: { case GDScriptParser::Node::CONTINUE: {
const GDScriptParser::ContinueNode *cont = static_cast<const GDScriptParser::ContinueNode *>(s);
if (cont->is_for_match) {
gen->write_continue_match();
} else {
gen->write_continue(); gen->write_continue();
}
} break; } break;
case GDScriptParser::Node::RETURN: { case GDScriptParser::Node::RETURN: {
const GDScriptParser::ReturnNode *return_n = static_cast<const GDScriptParser::ReturnNode *>(s); const GDScriptParser::ReturnNode *return_n = static_cast<const GDScriptParser::ReturnNode *>(s);

View File

@@ -1789,11 +1789,10 @@ GDScriptParser::BreakNode *GDScriptParser::parse_break() {
GDScriptParser::ContinueNode *GDScriptParser::parse_continue() { GDScriptParser::ContinueNode *GDScriptParser::parse_continue() {
if (!can_continue) { if (!can_continue) {
push_error(R"(Cannot use "continue" outside of a loop or pattern matching block.)"); push_error(R"(Cannot use "continue" outside of a loop.)");
} }
current_suite->has_continue = true; current_suite->has_continue = true;
ContinueNode *cont = alloc_node<ContinueNode>(); ContinueNode *cont = alloc_node<ContinueNode>();
cont->is_for_match = is_continue_match;
complete_extents(cont); complete_extents(cont);
end_statement(R"("continue")"); end_statement(R"("continue")");
return cont; return cont;
@@ -1819,12 +1818,10 @@ GDScriptParser::ForNode *GDScriptParser::parse_for() {
// Save break/continue state. // Save break/continue state.
bool could_break = can_break; bool could_break = can_break;
bool could_continue = can_continue; bool could_continue = can_continue;
bool was_continue_match = is_continue_match;
// Allow break/continue. // Allow break/continue.
can_break = true; can_break = true;
can_continue = true; can_continue = true;
is_continue_match = false;
SuiteNode *suite = alloc_node<SuiteNode>(); SuiteNode *suite = alloc_node<SuiteNode>();
if (n_for->variable) { if (n_for->variable) {
@@ -1842,7 +1839,6 @@ GDScriptParser::ForNode *GDScriptParser::parse_for() {
// Reset break/continue state. // Reset break/continue state.
can_break = could_break; can_break = could_break;
can_continue = could_continue; can_continue = could_continue;
is_continue_match = was_continue_match;
return n_for; return n_for;
} }
@@ -1979,13 +1975,6 @@ GDScriptParser::MatchBranchNode *GDScriptParser::parse_match_branch() {
return nullptr; return nullptr;
} }
// Save continue state.
bool could_continue = can_continue;
bool was_continue_match = is_continue_match;
// Allow continue for match.
can_continue = true;
is_continue_match = true;
SuiteNode *suite = alloc_node<SuiteNode>(); SuiteNode *suite = alloc_node<SuiteNode>();
if (branch->patterns.size() > 0) { if (branch->patterns.size() > 0) {
for (const KeyValue<StringName, IdentifierNode *> &E : branch->patterns[0]->binds) { for (const KeyValue<StringName, IdentifierNode *> &E : branch->patterns[0]->binds) {
@@ -1998,10 +1987,6 @@ GDScriptParser::MatchBranchNode *GDScriptParser::parse_match_branch() {
branch->block = parse_suite("match pattern block", suite); branch->block = parse_suite("match pattern block", suite);
complete_extents(branch); complete_extents(branch);
// Restore continue state.
can_continue = could_continue;
is_continue_match = was_continue_match;
return branch; return branch;
} }
@@ -2160,12 +2145,10 @@ GDScriptParser::WhileNode *GDScriptParser::parse_while() {
// Save break/continue state. // Save break/continue state.
bool could_break = can_break; bool could_break = can_break;
bool could_continue = can_continue; bool could_continue = can_continue;
bool was_continue_match = is_continue_match;
// Allow break/continue. // Allow break/continue.
can_break = true; can_break = true;
can_continue = true; can_continue = true;
is_continue_match = false;
n_while->loop = parse_suite(R"("while" block)"); n_while->loop = parse_suite(R"("while" block)");
n_while->loop->is_loop = true; n_while->loop->is_loop = true;
@@ -2174,7 +2157,6 @@ GDScriptParser::WhileNode *GDScriptParser::parse_while() {
// Reset break/continue state. // Reset break/continue state.
can_break = could_break; can_break = could_break;
can_continue = could_continue; can_continue = could_continue;
is_continue_match = was_continue_match;
return n_while; return n_while;
} }

View File

@@ -758,7 +758,6 @@ public:
}; };
struct ContinueNode : public Node { struct ContinueNode : public Node {
bool is_for_match = false;
ContinueNode() { ContinueNode() {
type = CONTINUE; type = CONTINUE;
} }
@@ -1254,7 +1253,6 @@ private:
bool panic_mode = false; bool panic_mode = false;
bool can_break = false; bool can_break = false;
bool can_continue = false; bool can_continue = false;
bool is_continue_match = false; // Whether a `continue` will act on a `match`.
List<bool> multiline_stack; List<bool> multiline_stack;
ClassNode *head = nullptr; ClassNode *head = nullptr;

View File

@@ -3,8 +3,6 @@ func test():
match i: match i:
"Hello": "Hello":
print("hello") print("hello")
# This will fall through to the default case below.
continue
"Good bye": "Good bye":
print("bye") print("bye")
_: _:

View File

@@ -1,4 +1,3 @@
GDTEST_OK GDTEST_OK
hello hello
default
This will match This will match

View File

@@ -8,11 +8,10 @@ func test():
1234: 1234:
print("2") print("2")
match number: match number:
1234: 4321:
print("3") print("Should not be printed")
continue
_: _:
print("Should also be printed") print("3")
match number: match number:
1234: 1234:
print("4") print("4")

View File

@@ -2,7 +2,6 @@ GDTEST_OK
1 1
2 2
3 3
Should also be printed
4 4
5 5
6 6