|
| 1 | +--- |
| 2 | +layout: doc-page |
| 3 | +title: "Pattern Matching on Quoted Code" |
| 4 | +--- |
| 5 | + |
| 6 | + |
| 7 | + |
| 8 | +## Overview |
| 9 | + |
| 10 | +```scala |
| 11 | +def foo(x: Expr[Int]) given tasty.Reflect: Expr[Int] = x match { |
| 12 | + case '{ val $a = $x; (${Bind(`a`)}: Int) + ($y: Int) } => '{ $x + $y } // TODO needs fix for #6328, `a` is currently not in scope while typing |
| 13 | +} |
| 14 | +``` |
| 15 | + |
| 16 | +```scala |
| 17 | +def foo(x: Expr[Int]) given tasty.Reflect: Expr[Int] = x match { |
| 18 | + case scala.internal.quoted.Matcher.unapply[Tuple3[Bind[Int], Expr[Int], Expr[Int]]](Tuple3(a, x, Bind(`a`), y))('{ @patternBindHole val a: Int = patternHole[Int]; patternHole[Int] + patternHole[Int] }) => |
| 19 | +} |
| 20 | +``` |
| 21 | + |
| 22 | + |
| 23 | +## Matcher |
| 24 | + |
| 25 | +At runtime to a `quoted.Expr` can be matched to another using `scala.internal.quoted.Matcher.unapply`. |
| 26 | + |
| 27 | +```scala |
| 28 | +def unapply[Tup <: Tuple](scrutineeExpr: Expr[_])(implicit patternExpr: Expr[_], reflection: Reflection): Option[Tup] |
| 29 | +``` |
| 30 | + |
| 31 | +The `scrutineeExpr` is a normal quoted expression while `patternExpr` may contain holes representing splices. |
| 32 | +The result of pattern matching is `None` if the expressions are not equivalent, otherwise it returns `Some` (some tuple) containing the contents of the matched holes. |
| 33 | + |
| 34 | + |
| 35 | +| Expression | Pattern | | |
| 36 | +| :-----------------------: |:-----------------------: | -------------------------------------------------------------------------: | |
| 37 | +| Literal `a` | Literal `x` | matches if `a == x` | |
| 38 | +| `a` | `x` | matches if `a` and `x` refer to the same symbol | |
| 39 | +| `a.b` | `x.y` | matches if `b` and `y` refer to the same symbol and `a` matches `x` | |
| 40 | +| `a: A` | `x: X` | matches if `a` matches `x` and `A` matches `X` | |
| 41 | +| `fa(.. bi ..)` | `fx(.. xi ..)` | matches if `fa` matches `fx` and for all `i` `ai` matches `xi` | |
| 42 | +| `fa[.. Ai ..]` | `fx[.. Xi ..]` | matches if `fa` matches `fx` and for all `i` `Ai` matches `Xi` | |
| 43 | +| `{.. ai ..}` | `{.. xi ..}` | matches if all `i` `ai` matches `xi` | |
| 44 | +| `if (a) b else c` | `if (x) y else z` | matches if `a` matches `x`, `b` matches `y` and `c` matches `z` | |
| 45 | +| `while (a) b` | `while (x) y` | matches if `a` matches `x` and `b` matches `y` | |
| 46 | +| Assignment `a = b` | Assignment `x = y` | matches if `a` matches `x`, `b` matches `y` | |
| 47 | +| Named argument `n = a` | Named argument `m = x | matches if `c1` matches `c2`, `t1` matches `t2` and `e1` matches `e2` | |
| 48 | +| `new A` | `new X` | matches if `A` matches `B` | |
| 49 | +| `this` | `this` | matches if both refer to the same symbol | |
| 50 | +| `a.super[B]` | `x.super[Y]` | matches if `a` matches `x` and `A` equals `Y` | |
| 51 | +| Repeated `ai` | Repeated `xi` | matches if for all `i` `ai` matches `xi` | |
| 52 | +> ValDef |
| 53 | +> DefDef |
| 54 | +> Lambda |
| 55 | +> Match |
| 56 | +> Try |
| 57 | +
|
| 58 | +| Type | Pattern | | |
| 59 | +| :-----------------------: |:-----------------------: | -------------------------------------------------------------------------: | |
| 60 | +| Inferred `A` | Inferred `X` | matches if `A <:< B` | |
| 61 | +> Applied Type |
| 62 | +> Annotated |
| 63 | +
|
| 64 | + |
| 65 | +| Pattern inside the quote | Pattern | | |
| 66 | +| :-------------------------: |:--------------------------: | ---------------------------------------------------------------------------------: | |
| 67 | +| Value `a` | Value `x` | matches if `a` matches `x` | |
| 68 | +| `a: A` | `x: X` | matches if `A` matches `X` | |
| 69 | +| `a @ b` | `x @ y` | makes symbols of `a` and `x` equivalent and matches if `b` matches `y` | |
| 70 | +| Unapply `a(..bi..)(..ci..)` | Unapply `x(..yi..)(..zi..)` | matches if `a` matches `x` and for all `i` `bi` matches `yi` and `ci` matches `zi` | |
| 71 | +| `.. | ai | ..` | `.. | xi | ..` | matches if for all `i` `ai` matches `xi` | |
| 72 | +| `_` | `_` | always matches | |
| 73 | + |
| 74 | + |
| 75 | +## Quoted Patterns |
| 76 | + |
| 77 | + |
0 commit comments