see #371 This commit does not implement all features discussed in this issue. It has implemented it as a macro expansion. Thus, the following is accepted ```lean inductive StrOrNum where | S (s : String) | I (i : Int) def StrOrNum.asString (x : StrOrNum) := match x with | I a | S a => toString a ``` It may confuse the Lean LSP server. The `a` on `toString` shows the information for the first alternative after expansion (i.e., `a` is an `Int`). After expansion, we have ``` def StrOrNum.asString (x : StrOrNum) := match x with | I a => toString a | S a => toString a ```
57 lines
1.6 KiB
Text
57 lines
1.6 KiB
Text
/-
|
|
Copyright (c) 2021 Microsoft Corporation. All rights reserved.
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
Authors: Leonardo de Moura
|
|
-/
|
|
import Lean.Parser.Term
|
|
|
|
namespace Lean.Elab.Term
|
|
/-
|
|
Recall that
|
|
```
|
|
def typeSpec := leading_parser " : " >> termParser
|
|
def optType : Parser := optional typeSpec
|
|
```
|
|
-/
|
|
def expandOptType (ref : Syntax) (optType : Syntax) : Syntax :=
|
|
if optType.isNone then
|
|
mkHole ref
|
|
else
|
|
optType[0][1]
|
|
|
|
open Lean.Parser.Term
|
|
|
|
/- Helper function for `expandEqnsIntoMatch` -/
|
|
def getMatchAltsNumPatterns (matchAlts : Syntax) : Nat :=
|
|
let alt0 := matchAlts[0][0]
|
|
let pats := alt0[1][0].getSepArgs
|
|
pats.size
|
|
|
|
/--
|
|
Expand a match alternative such as `| 0 | 1 => rhs` to an array containing `| 0 => rhs` and `| 1 => rhs`.
|
|
-/
|
|
def expandMatchAlt (stx : Syntax) : MacroM (Array Syntax) :=
|
|
match stx with
|
|
| `(matchAltExpr| | $[$patss]|* => $rhs) =>
|
|
if patss.size ≤ 1 then
|
|
return #[stx]
|
|
else
|
|
patss.mapM fun pats => let pats := #[pats]; `(matchAltExpr| | $[$pats]|* => $rhs)
|
|
| _ => return #[stx]
|
|
|
|
def shouldExpandMatchAlt (matchAlt : Syntax) : Bool :=
|
|
match matchAlt with
|
|
| `(matchAltExpr| | $[$patss]|* => $rhs) => patss.size > 1
|
|
| _ => false
|
|
|
|
def expandMatchAlts? (stx : Syntax) : MacroM (Option Syntax) := do
|
|
match stx with
|
|
| `(match $[$gen]? $[$motive]? $discrs,* with $alts:matchAlt*) =>
|
|
if alts.any shouldExpandMatchAlt then
|
|
let alts ← alts.foldlM (init := #[]) fun alts alt => return alts ++ (← expandMatchAlt alt)
|
|
`(match $[$gen]? $[$motive]? $discrs,* with $alts:matchAlt*)
|
|
else
|
|
return none
|
|
| _ => return none
|
|
|
|
end Lean.Elab.Term
|