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

Adds pattern matching to GDScript #6845

Merged
merged 3 commits into from
Jan 14, 2017
Merged

Adds pattern matching to GDScript #6845

merged 3 commits into from
Jan 14, 2017

Conversation

karroffel
Copy link
Contributor

@karroffel karroffel commented Oct 16, 2016

As I proposed in #6593 here is the implementation of pattern matching in GDScript.

Right now the highlighting for the match keywords doesn't work but I think this isn't too important for code reviewing.

@karroffel
Copy link
Contributor Author

karroffel commented Oct 17, 2016

Here the final "specification" of the pattern matching features.


The match statement can be used inside blocks (so where all the other statements can be used too).

Abstract syntax of a match statement:

match expression:
    pattern: block
    pattern: block
    ...

A pattern can be of 6 types:

  • constant pattern
    • number|string|null .. any constant value.
      • Some expressions are foldable during parse time (like 21 * 2 or even abs(3)).
      • Note: function calls are not allowed if they cannot be reduced at parse time!
  • variable pattern
    • identifier
      • matches against a variable/constant
  • array pattern
    • [pattern, pattern, pattern, ... ]
      • trailing commas are allowed.
      • The last entry may be .. , which means "ignore the rest of the array".
      • All the element patterns are nestable (recursive)
  • dictionary pattern
    • {constant: pattern, constant, ... }
      • trailing commas are allowed.
      • If no : is present, only the existence of the key is checked.
      • The last entry may be .. , which means "ignore the rest of the dictionary".
      • The sub-patterns are recursive as well.
  • bind pattern
    • var identifier
      • binds the value that's being matched to the identifier.
  • wildcard pattern
    • _
      • Ignores the value - always matches.

Edit: I forgot one, it isn't really a pattern type but anyway...

  • multipattern
    • pattern, pattern, ... pattern
      • Checks for multiple patterns at once
      • comma separated patterns. Trailing comma is not allowed.
      • Bindings are not allowed in multipatterns
      • Matching is left-to-right

Since it's not really a pattern type it can't be used in array and dictionary patterns, only as a "toplevel" pattern.

The body can contain match statements as well.


Pattern are checked from top to bottom, left to right.

A break is not necessary, it's not even working (break is currently only allowed in loops). So it works when the match statement is inside of a loop, if it isn't a parse error will be thrown.
(It wouldn't be a big change to make it work like expected outside of loops, but I don't think that's a good idea)

A continue stops execution in the current block and checks the next pattern instead.




Error err = _parse_block(codegen, branch.body, p_stack_level, p_break_addr, continue_addr);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If p_break_addr is changed to break_addr then break will work inside of a pattern branch. So no big changes needed to support that. However I think it would be a bad idea to do that since it will cause a lot of confusion amongst newbies and may lead people the wrong way.

break isn't match-idiomatic, so I think it would be a mistake to implement it that way.

@bojidar-bg
Copy link
Contributor

Assigning to @reduz to review, since it is a new gdscript feature.

@pkowal1982
Copy link
Contributor

I think GDScript syntax is complete, maybe missing ternary operator and while, so I'm against merging.

@karroffel
Copy link
Contributor Author

@pkowal1982 ternary operators are implemented on master and while exists for a long time now. switch was a fairly often requested feature, this is just a one-up of a switch. See the issue #6593 for the discussion

@reduz reduz merged commit 4261880 into godotengine:master Jan 14, 2017
@vnen
Copy link
Member

vnen commented Jan 15, 2017

🎉

@bojidar-bg
Copy link
Contributor

@karroffel Now you have to write docs 😛

@karroffel
Copy link
Contributor Author

oh snap. I actually thought about that in bed, will do after Akiens huge formatting code review

@bojidar-bg
Copy link
Contributor

@karroffel I'm speaking of godotengine/godot-docs, heh

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.

6 participants