AnyDSL / artic

The AlteRnaTive Impala Compiler
MIT License
25 stars 6 forks source link

Add `if let` and `while let` constructs #4

Closed Hugobros3 closed 3 years ago

Hugobros3 commented 3 years ago

Following https://github.com/AnyDSL/artic/pull/3 and https://github.com/AnyDSL/artic/projects/7, this PR adds the ability to use let in combination with if and while to do pattern-matching in place of a boolean condition. The patterns have to be refutable, meaning you cannot use this syntax to perform simple deconstruction (for that you are invited to use regular let statements, which have the opposite restriction: they must be trivial).

let x: (i32, i32) = ... ;
if let (0, five) = x {
    foo();
} else { bar(); }
while let Some(x) = get_next() {
    process(x);
}

Since this feature relies on the same pattern compiler that match uses, some re-factoring was performed: PtrnCompiler now has a MatchCase helper struct used in place of CaseExpr internally, this was done so that we did not have to generate dummy CaseExprs in the if let/while let cases, and also because CaseExpr owns ptrn and expr, while MatchCase does not, meaning IfLetExpr and WhileLetExpr can retain ownership of those two without any copying or extraneous moving. Additionally PtrnCompiler is now invoked via a static emit method which takes ownership of a vector of PtrnCompiler::MatchCases and perform redundancy checks.

Tests are provided for this functionality, and the coverage metrics are slightly better than on master.

madmann91 commented 3 years ago

Looks good. Please merge master into this branch (just run git merge master when on the branch) to resolve conflicts. Then I'll merge this PR into master.