From 70d9106644ed4a7df8ca21bb7a47ad442ce946e5 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 1 Mar 2024 19:30:08 -0800 Subject: [PATCH] feat: `match_expr` parsers --- src/Lean/Parser/Do.lean | 6 +++++- src/Lean/Parser/Term.lean | 15 ++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/Lean/Parser/Do.lean b/src/Lean/Parser/Do.lean index 6680273c4c..29fdd2a9f4 100644 --- a/src/Lean/Parser/Do.lean +++ b/src/Lean/Parser/Do.lean @@ -50,7 +50,7 @@ def notFollowedByRedefinedTermToken := -- but we include them in the following list to fix the ambiguity where -- an "open" command follows the `do`-block. -- If we don't add `do`, then users would have to indent `do` blocks or use `{ ... }`. - notFollowedBy ("set_option" <|> "open" <|> "if" <|> "match" <|> "let" <|> "have" <|> + notFollowedBy ("set_option" <|> "open" <|> "if" <|> "match" <|> "match_expr" <|> "let" <|> "let_expr" <|> "have" <|> "do" <|> "dbg_trace" <|> "assert!" <|> "for" <|> "unless" <|> "return" <|> symbol "try") "token at 'do' element" @@ -150,6 +150,10 @@ def doMatchAlts := ppDedent <| matchAlts (rhsParser := doSeq) "match " >> optional Term.generalizingParam >> optional Term.motive >> sepBy1 matchDiscr ", " >> " with" >> doMatchAlts +def doMatchExprAlts := ppDedent <| matchExprAlts (rhsParser := doSeq) +@[builtin_doElem_parser] def doMatchExpr := leading_parser:leadPrec + "match_expr " >> optional ("(" >> nonReservedSymbol "meta" >> " := " >> nonReservedSymbol "false" >> ") ") >> termParser >> " with" >> doMatchExprAlts + def doCatch := leading_parser ppDedent ppLine >> atomic ("catch " >> binderIdent) >> optional (" : " >> termParser) >> darrow >> doSeq def doCatchMatch := leading_parser diff --git a/src/Lean/Parser/Term.lean b/src/Lean/Parser/Term.lean index 535802b09a..7ff30c8717 100644 --- a/src/Lean/Parser/Term.lean +++ b/src/Lean/Parser/Term.lean @@ -802,7 +802,6 @@ interpolated string literal) to stderr. It should only be used for debugging. @[builtin_term_parser] def assert := leading_parser:leadPrec withPosition ("assert! " >> termParser) >> optSemicolon termParser - def macroArg := termParser maxPrec def macroDollarArg := leading_parser "$" >> termParser 10 def macroLastArg := macroDollarArg <|> macroArg @@ -823,6 +822,19 @@ Implementation of the `show_term` term elaborator. @[builtin_term_parser] def showTermElabImpl := leading_parser:leadPrec "show_term_elab " >> termParser +/-! +`match_expr` support. +-/ + +def matchExprAlt (rhsParser : Parser) := leading_parser "| " >> ppIndent (optional (atomic (ident >> "@")) >> ident >> many binderIdent >> " => " >> rhsParser) +def matchExprElseAlt (rhsParser : Parser) := leading_parser "| " >> ppIndent (hole >> " => " >> rhsParser) +def matchExprAlts (rhsParser : Parser) := + leading_parser withPosition $ + many (ppLine >> checkColGe "irrelevant" >> notFollowedBy (symbol "| " >> " _ ") "irrelevant" >> matchExprAlt rhsParser) + >> (ppLine >> checkColGe "irrelevant" >> matchExprElseAlt rhsParser) +@[builtin_term_parser] def matchExpr := leading_parser:leadPrec + "match_expr " >> termParser >> " with" >> ppDedent (matchExprAlts termParser) + end Term @[builtin_term_parser default+1] def Tactic.quot : Parser := leading_parser @@ -841,6 +853,7 @@ builtin_initialize register_parser_alias matchDiscr register_parser_alias bracketedBinder register_parser_alias attrKind + register_parser_alias optSemicolon end Parser end Lean