diff --git a/src/Lean/Elab/Tactic/Basic.lean b/src/Lean/Elab/Tactic/Basic.lean index dfec5c8ff2..22d30107a1 100644 --- a/src/Lean/Elab/Tactic/Basic.lean +++ b/src/Lean/Elab/Tactic/Basic.lean @@ -379,8 +379,8 @@ fun stx => match_syntax stx with @[builtinTactic paren] def evalParen : Tactic := fun stx => evalTactic (stx.getArg 1) -@[builtinTactic nestedTacticBlockCurly] def evalNestedTacticBlock : Tactic := -fun stx => focus (evalTactic (stx.getArg 1)) +@[builtinTactic tacticSeq1Bracketed] def evalTacticSeq1Bracketed : Tactic := +fun stx => focus $ (stx.getArg 1).forSepArgsM evalTactic /-- First method searches for a metavariable `g` s.t. `tag` is a suffix of its name. diff --git a/src/Lean/Parser/Tactic.lean b/src/Lean/Parser/Tactic.lean index a2f8f41338..59e813d3b3 100644 --- a/src/Lean/Parser/Tactic.lean +++ b/src/Lean/Parser/Tactic.lean @@ -35,13 +35,13 @@ def ident' : Parser := ident <|> underscore @[builtinTacticParser] def «exact» := parser! nonReservedSymbol "exact " >> termParser @[builtinTacticParser] def «refine» := parser! nonReservedSymbol "refine " >> termParser @[builtinTacticParser] def «refine!» := parser! nonReservedSymbol "refine! " >> termParser -@[builtinTacticParser] def «case» := parser! nonReservedSymbol "case " >> ident >> darrow >> tacticSeq1 -@[builtinTacticParser] def «allGoals» := parser! nonReservedSymbol "allGoals " >> tacticSeq1 +@[builtinTacticParser] def «case» := parser! nonReservedSymbol "case " >> ident >> darrow >> tacticSeq +@[builtinTacticParser] def «allGoals» := parser! nonReservedSymbol "allGoals " >> tacticSeq @[builtinTacticParser] def «skip» := parser! nonReservedSymbol "skip" @[builtinTacticParser] def «done» := parser! nonReservedSymbol "done" @[builtinTacticParser] def «admit» := parser! nonReservedSymbol "admit" @[builtinTacticParser] def «traceState» := parser! nonReservedSymbol "traceState" -@[builtinTacticParser] def «failIfSuccess» := parser! nonReservedSymbol "failIfSuccess " >> tacticSeq1 +@[builtinTacticParser] def «failIfSuccess» := parser! nonReservedSymbol "failIfSuccess " >> tacticSeq @[builtinTacticParser] def «generalize» := parser! nonReservedSymbol "generalize " >> optional (try (ident >> " : ")) >> termParser 51 >> " = " >> ident def locationWildcard := parser! "*" @@ -58,7 +58,7 @@ def rwRuleSeq := parser! "[" >> sepBy1 rwRule ", " true >> "]" @[builtinTacticParser] def «rewriteSeq» := parser! (nonReservedSymbol "rewrite" <|> nonReservedSymbol "rw") >> rwRuleSeq >> optional location def majorPremise := parser! optional (try (ident >> " : ")) >> termParser -def altRHS := Term.hole <|> Term.syntheticHole <|> tacticSeq1 +def altRHS := Term.hole <|> Term.syntheticHole <|> tacticSeq def inductionAlt : Parser := nodeWithAntiquot "inductionAlt" `Lean.Parser.Tactic.inductionAlt $ ident' >> many ident' >> darrow >> altRHS def inductionAlts : Parser := withPosition $ "|" >> sepBy1 inductionAlt (checkColGe "alternatives must be indented" >> "|") def withAlts : Parser := optional (" with " >> inductionAlts) @@ -74,10 +74,9 @@ def matchAlts : Parser := group $ withPosition $ (optional "| ") >> sepBy1 match def withIds : Parser := optional (" with " >> many1 ident') @[builtinTacticParser] def «injection» := parser! nonReservedSymbol "injection " >> termParser >> withIds -def seq := node `Lean.Parser.Tactic.seq $ sepBy tacticParser "; " true def seq1 := node `Lean.Parser.Tactic.seq $ sepBy1 tacticParser "; " true @[builtinTacticParser] def paren := parser! "(" >> seq1 >> ")" -@[builtinTacticParser] def nestedTactic := parser! "{" >> seq >> "}" +@[builtinTacticParser] def nestedTactic := tacticSeqBracketed @[builtinTacticParser] def orelse := tparser!:2 " <|> " >> tacticParser 1 /- Term binders as tactics. They are all implemented as macros using the triad: named holes, hygiene, and `refine` tactic. -/ diff --git a/src/Lean/Parser/Term.lean b/src/Lean/Parser/Term.lean index 6a897af147..6c7a246dcd 100644 --- a/src/Lean/Parser/Term.lean +++ b/src/Lean/Parser/Term.lean @@ -24,12 +24,9 @@ namespace Tactic def tacticSeq1Indented : Parser := nodeWithAntiquot "tacticSeq" `Lean.Parser.Tactic.seq $ withPosition $ sepBy1 tacticParser (try ("; " >> checkColGe "tatic must be indented")) -def tacticSeq1Bracketed : Parser := - parser! "{" >> sepBy1 tacticParser "; " true >> "}" -def tacticSeq1 := tacticSeq1Bracketed <|> tacticSeq1Indented - def tacticSeqBracketed : Parser := parser! "{" >> sepBy tacticParser "; " true >> "}" +def tacticSeq := tacticSeqBracketed <|> tacticSeq1Indented end Tactic @@ -53,7 +50,7 @@ checkPrec prec >> symbol sym >> termParser (prec+1) /- Built-in parsers -/ -@[builtinTermParser] def byTactic := parser!:leadPrec "by " >> Tactic.tacticSeq1 +@[builtinTermParser] def byTactic := parser!:leadPrec "by " >> Tactic.tacticSeq -- `checkPrec` necessary for the pretty printer @[builtinTermParser] def ident := checkPrec maxPrec >> Parser.ident @@ -95,7 +92,7 @@ def optType : Parser := optional typeSpec @[builtinTermParser] def inaccessible := parser! ".(" >> termParser >> ")" def binderIdent : Parser := ident <|> hole def binderType (requireType := false) : Parser := if requireType then group (" : " >> termParser) else optional (" : " >> termParser) -def binderTactic := parser! try (" := " >> " by ") >> Tactic.tacticSeq1 +def binderTactic := parser! try (" := " >> " by ") >> Tactic.tacticSeq def binderDefault := parser! " := " >> termParser def explicitBinder (requireType := false) := ppGroup $ parser! "(" >> many1 binderIdent >> binderType requireType >> optional (binderTactic <|> binderDefault) >> ")" def implicitBinder (requireType := false) := ppGroup $ parser! "{" >> many1 binderIdent >> binderType requireType >> "}"