feat: update match parser

Support for
```
def fib (x : Nat) : Nat :=
  match x with
  | 0 | 1 => 1
  | x+2   => fib (x+1) + fib x
```

TODO: expand `matchAlts`
This commit is contained in:
Leonardo de Moura 2022-03-20 13:22:39 -07:00
parent 87bb299f08
commit 8f4d58893f
5 changed files with 7 additions and 5 deletions

View file

@ -388,7 +388,7 @@ def elabFunBinders {α} (binders : Array Syntax) (expectedType? : Option Expr) (
/- Helper function for `expandEqnsIntoMatch` -/
private def getMatchAltsNumPatterns (matchAlts : Syntax) : Nat :=
let alt0 := matchAlts[0][0]
let pats := alt0[1].getSepArgs
let pats := alt0[1][0].getSepArgs
pats.size
def expandWhereDecls (whereDecls : Syntax) (body : Syntax) : MacroM Syntax :=

View file

@ -1040,7 +1040,7 @@ partial def toTerm : Code → M Syntax
let mut termAlts := #[]
for alt in alts do
let rhs ← toTerm alt.rhs
let termAlt := mkNode `Lean.Parser.Term.matchAlt #[mkAtomFrom alt.ref "|", alt.patterns, mkAtomFrom alt.ref "=>", rhs]
let termAlt := mkNode `Lean.Parser.Term.matchAlt #[mkAtomFrom alt.ref "|", mkNullNode #[alt.patterns], mkAtomFrom alt.ref "=>", rhs]
termAlts := termAlts.push termAlt
let termMatchAlts := mkNode `Lean.Parser.Term.matchAlts #[mkNullNode termAlts]
return mkNode `Lean.Parser.Term.«match» #[mkAtomFrom ref "match", genParam, optMotive, discrs, mkAtomFrom ref "with", termMatchAlts]
@ -1459,8 +1459,9 @@ mutual
let optMotive := doMatch[2]
let discrs := doMatch[3]
let matchAlts := doMatch[5][0].getArgs -- Array of `doMatchAlt`
-- TODO: expand `matchAlt`
let alts ← matchAlts.mapM fun matchAlt => do
let patterns := matchAlt[1]
let patterns := matchAlt[1][0]
let vars ← getPatternsVarsEx patterns.getSepArgs
withRef patterns <| checkNotShadowingMutable vars
let rhs := matchAlt[3]

View file

@ -1087,6 +1087,7 @@ enforce this. -/
| _ => elabMatchDefault stx expectedType?
where
elabMatchDefault (stx : Syntax) (expectedType? : Option Expr) : TermElabM Expr := do
-- TODO: expand matchAlts
match (← expandNonAtomicDiscrs? stx) with
| some stxNew => withMacroExpansion stx stxNew <| elabTerm stxNew expectedType?
| none =>

View file

@ -135,7 +135,7 @@ def «forall» := leading_parser:leadPrec unicodeSymbol "∀" "forall" >> many1
def matchAlt (rhsParser : Parser := termParser) : Parser :=
nodeWithAntiquot "matchAlt" `Lean.Parser.Term.matchAlt $
"| " >> ppIndent (sepBy1 termParser ", " >> darrow >> checkColGe "alternative right-hand-side to start in a column greater than or equal to the corresponding '|'" >> rhsParser)
"| " >> ppIndent (sepBy1 (sepBy1 termParser ", ") "|" >> darrow >> checkColGe "alternative right-hand-side to start in a column greater than or equal to the corresponding '|'" >> rhsParser)
/--
Useful for syntax quotations. Note that generic patterns such as `` `(matchAltExpr| | ... => $rhs) `` should also
work with other `rhsParser`s (of arity 1). -/

View file

@ -8,7 +8,7 @@ options get_default_options() {
// switch to `true` for ABI-breaking changes affecting meta code
opts = opts.update({"interpreter", "prefer_native"}, false);
// switch to `true` for changing built-in parsers used in quotations
opts = opts.update({"internal", "parseQuotWithCurrentStage"}, false);
opts = opts.update({"internal", "parseQuotWithCurrentStage"}, true);
#endif
return opts;
}