Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GDScript: Implement pattern guards for match statement #80085

Merged
merged 1 commit into from
Sep 28, 2023

Conversation

vnen
Copy link
Member

@vnen vnen commented Jul 31, 2023

Within a match statement, it is now possible to add guards in each branch:

var a = 0
match a:
	0 when false: print("does not run")
	0 when true: print("but this does")

This allows more complex logic for deciding which branch to take.

Closes godotengine/godot-proposals#4775

EDIT: Changed the -> if separator to the new keyword when, as discussed.

@vnen vnen added this to the 4.2 milestone Jul 31, 2023
@vnen vnen requested a review from a team as a code owner July 31, 2023 12:11
Copy link
Member

@dalexeev dalexeev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks good to me! 👍 There is a little hack with the pattern guard is SuiteNode, not ExpressionNode. In theory, we can get unrelated warnings or something like that, but I did not find any related bugs when I tested it.

The tests are good, but maybe we should add some more? For example a test that an assignment is not allowed inside a pattern guard.

I'm still not sure about the syntax, so I suggest discussing this at the next GDScript team meeting.

modules/gdscript/gdscript_parser.cpp Outdated Show resolved Hide resolved
@dalexeev
Copy link
Member

dalexeev commented Aug 1, 2023

I noticed that the pattern guard is executed even if none of the patterns matched.

func f() -> bool:
    print("f")
    return true

func _ready() -> void:
    var x := 1
    match x:
        2 -> if f():
            print("A")
        _:
            print("B")

Prints:

f
B

@vnen
Copy link
Member Author

vnen commented Aug 3, 2023

I noticed that the pattern guard is executed even if none of the patterns matched.

func f() -> bool:
    print("f")
    return true

func _ready() -> void:
    var x := 1
    match x:
        2 -> if f():
            print("A")
        _:
            print("B")

Prints:

f
B

Fixed now. Added a test for this case as well as the one for assignment.

@adamscott
Copy link
Member

Discussed during a GDScript Team Meeting: this PR will be modified my @vnen to use the when keyword to introduce the if statement. This PR would be ready for 4.2 afterwards.

Within a match statement, it is now possible to add guards in each
branch:

	var a = 0
	match a:
		0 when false: print("does not run")
		0 when true: print("but this does")

This allows more complex logic for deciding which branch to take.
@vnen
Copy link
Member Author

vnen commented Sep 27, 2023

I updated the PR to use then new when keyword.

Copy link
Member

@dalexeev dalexeev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me and works great, it won't even break compatibility if someone uses when as an identifier. Thank you George!

var when = 1
match when:
    when when when: # I like it.
        when

@YuriSizov YuriSizov merged commit 813cd1d into godotengine:master Sep 28, 2023
15 checks passed
@YuriSizov
Copy link
Contributor

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add guards to match patterns in GDScript
4 participants