Repository: effekt-lang/effekt (scala)

Issue:
Allow braces in a pattern match
When an arm of an pattern match gets too long, I'd like to wrap it in _braces_:
```scala
def main(opt: Option[Int]) = {
  opt match {
    case None() => println("Nothing")
    case Some(x) => {
      println("We have a number: ${x.show}")
    }
  }
}
```

Unfortunately, the parser doesn't like that very much:
<img width="418" alt="Screenshot 2024-03-22 at 11 26 18" src="https://github.com/effekt-lang/effekt/assets/11269173/1b9c7ef3-0e4f-4ca5-b4c1-bac4e4df94eb">

(As far as I know, this is one of the few places where we only allow delimiting by `case`)

Pull request description:
Resolves #422

Patch:
diff --git a/effekt/shared/src/main/scala/effekt/RecursiveDescent.scala b/effekt/shared/src/main/scala/effekt/RecursiveDescent.scala
index 702a3c031..60c959695 100644
--- a/effekt/shared/src/main/scala/effekt/RecursiveDescent.scala
+++ b/effekt/shared/src/main/scala/effekt/RecursiveDescent.scala
@@ -721,7 +721,13 @@ class RecursiveDescent(positions: Positions, tokens: Seq[Token], source: Source)
 
   def matchClause(): MatchClause =
     nonterminal:
-      MatchClause(`case` ~> matchPattern(), manyWhile(`and` ~> matchGuard(), `and`), `=>` ~> stmts())
+      MatchClause(
+        `case` ~> matchPattern(),
+        manyWhile(`and` ~> matchGuard(), `and`),
+        // allow a statement enclosed in braces or without braces
+        // both is allowed since match clauses are already delimited by `case`
+        `=>` ~> (if (peek(`{`)) { stmt() } else { stmts() })
+      )
 
   def matchGuards() =
     nonterminal:


Test patch:
diff --git a/effekt/jvm/src/test/scala/effekt/RecursiveDescentTests.scala b/effekt/jvm/src/test/scala/effekt/RecursiveDescentTests.scala
index 6436fe6d4..7f426ffa8 100644
--- a/effekt/jvm/src/test/scala/effekt/RecursiveDescentTests.scala
+++ b/effekt/jvm/src/test/scala/effekt/RecursiveDescentTests.scala
@@ -157,6 +157,14 @@ class RecursiveDescentTests extends munit.FunSuite {
         |}
         |""".stripMargin)
 
+    parseExpr(
+          """x match {
+            |  case 0 => { 42 }
+            |  case 1 => { 1; 2 }
+            |  case _ => 42
+            |}
+            |""".stripMargin)
+
     parseExpr(
       """x match {
         |  case Some(b) => acc = Cons(b, acc)