-
Notifications
You must be signed in to change notification settings - Fork 184
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
Implement partial support for Ruby 2.7 pattern matching #2186
Conversation
104c107
to
bcd1b0b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good so far.
This actually reminded me I implemented pattern matching in Mozart-Graal, maybe there is some similarity: https://github.com/eregon/mozart-graal/blob/ca762ad12d505647a8a872b4993ff76b92ea643a/vm/src/org/mozartoz/truffle/translator/Translator.java#L458
Do you intend the implement the rest of pattern matching in this PR, or would you rather merge this part, and the rest later?
If the latter, I think for users it would be safer to keep raising a SyntaxError (in visitCase3Node()
) until it's complete. We could have a temporary option to enable pattern matching to let specs run and to help working on it (i.e., setting the option to true
would not throw the SyntaxError).
7595b77
to
05d84e6
Compare
How do I get the linting check to pass? I’ve tried several times but can’t get it to stop flip-flopping. |
@tomstuart Are you using |
IMHO the best way to deal with formatting and lint checks is to enable this hook as |
05d84e6
to
27971da
Compare
Thanks, that worked. I was trying to eliminate the diff output by CI but that obviously wasn’t right because it kept changing its mind. |
I think we'd like to merge this. It's the result of a team hack-week. We'll come back and do more pattern matching work later - probably starting with doing the parser properly. |
OK, please add an expert experimental option for pattern matching then, as described in #2186 (review) |
585eb17
to
cf6c011
Compare
Option done |
53d9647
to
6989305
Compare
Rebased to merge parser changes. |
We added
to our test matrix. |
I think we can automatically set the option when running specs, e.g., in jt's Could you remove the last commit, and I'll find a way to run the specs for them automatically? |
6989305
to
c6dc29d
Compare
Done. Thank you — it’s better for us if these specs run in this repo’s CI, cos then they won’t get accidentally broken. |
We don’t intend to implement Ruby 3.0’s `#deconstruct` cache yet, but we’re including the example here for future reference.
This is how MRI behaves as of Ruby 2.7.2 & 3.0.0-preview2, so it’s important that we continue to do the same when implementing the rest of pattern matching.
… they are Co-authored-by: Lillian Zhang <[email protected]> Co-authored-by: Maple Ong <[email protected]>
Co-authored-by: Lillian Zhang <[email protected]> Co-authored-by: Maple Ong <[email protected]>
Co-authored-by: Lillian Zhang <[email protected]> Co-authored-by: Maple Ong <[email protected]>
We can't untag any existing tests because the simplest binding variable spec is in an array, but this now works: ``` >> a = "FIRSTINSTANCE" => "FIRSTINSTANCE" >> case 1 in a p "s" in 1 p "o" end "s" => "s" >> a => 1 ```
This will make it easier to combine the two switch statements.
This isn’t always needed, so we shouldn’t do it unconditionally.
We’re switching twice on the node type, so we should just do it once instead.
We can't untag any existing tests because we currently depend upon the local variable having already been declared, but this now works: ``` >> a = "FIRSTINSTANCE" => "FIRSTINSTANCE" >> case [[1,1,1],[6,6,6]] in [[a,1,1],[Integer,Integer,Integer,]] >> end => nil >> a => 1 ```
This branch didn’t introduce these violations, but they’re preventing its build from going green.
By adding it to `src/options.yml`, then running `ruby tool/generate-options.rb` to regenerate `LanguageOptions.java` and `OptionsCatalog.java`.
The message is “syntax error, unexpected keyword_in” because that’s what TruffleRuby (without pattern matching support) currently raises. # Conflicts: # src/main/java/org/truffleruby/parser/BodyTranslator.java
c6dc29d
to
4ca026c
Compare
* | ||
* @param expression of the case node (e.g. case foo) | ||
* @param firstInNode first in (which could also be the else) | ||
* @return a new case node */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For what it's worth, I don't think this is ugly at all. It keeps the grammar clean and all the logic in a single place.
The alternative would be to use the pattern used with ArrayParser
in the grammar with left-recursion, so something roughly like this:
p_case_body : keyword_in args then compstmt {
$$ = new SomeKindOfCaseBodyThing();
// or $$ = support.storedCaseInNode;
$$.add(support.newInNode($1, $2, $4));
}
| p_case_body keyword_in args then compstmt {
$$ = $1.add(support.newInNode($2, $3, $5));
}
| p_case_body keyword_else compstmt {
$$ = $1.set_else($3);
}
Is this problematic with the grammar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay! Probably worth changing that later if we decide that's not how we feel about it.
…2186) PullRequest: truffleruby/2263
TruffleRuby needs support for
case … in
pattern matching in order to be fully compatible with Ruby 2.7 (#2004). This PR includes an initial implementation of parsing and matching simple patterns. Specifically we now support:case … in
syntaxArray
s,Hash
es andStruct
s against array and hash patterns (#deconstruct
and#deconstruct_keys
)Before these changes, 2% (2/89) of the relevant
ruby/spec
examples (spec/ruby/core/**/deconstruct*
+spec/ruby/language/pattern_matching_spec.rb
) were passing; now, 37% (35/94) are passing. Further parser work is required to pass all of the remaining examples.Shopify#1