|
1 | 1 | /-
|
2 |
| -Copyright (c) 2021 Microsoft Corporation. All rights reserved. |
| 2 | +Copyright (c) 2018 Sebastian Ullrich. All rights reserved. |
3 | 3 | Released under Apache 2.0 license as described in the file LICENSE.
|
4 |
| -Authors: Mario Carneiro |
| 4 | +Authors: Sebastian Ullrich, Mario Carneiro |
5 | 5 | -/
|
6 |
| -import Lean |
| 6 | +import Lean.Elab.SyntheticMVars |
7 | 7 | import Mathlib.Util.TermUnsafe
|
8 | 8 |
|
9 | 9 | /-!
|
10 |
| -Define a `run_cmd a; b` command which executes code in `CommandElabM Unit`. |
11 |
| -This is almost the same as `#eval show CommandElabM Unit from do a; b`, |
12 |
| -except that it doesn't print an empty diagnostic. |
| 10 | +Defines commands to compile and execute a command / term / tactic on the spot: |
| 11 | +
|
| 12 | +* `run_cmd doSeq` command which executes code in `CommandElabM Unit`. |
| 13 | + This is almost the same as `#eval show CommandElabM Unit from do doSeq`, |
| 14 | + except that it doesn't print an empty diagnostic. |
| 15 | +
|
| 16 | +* `run_tac doSeq` tactic which executes code in `TacticM Unit`. |
| 17 | +
|
| 18 | +* `by_elab doSeq` term which executes code in `TermElabM Expr` to produce an expression. |
13 | 19 | -/
|
14 | 20 |
|
15 |
| -namespace Lean.Parser.Command |
16 |
| -open Meta Elab Command Term |
| 21 | +namespace Mathlib.RunCmd |
| 22 | +open Lean Meta Elab Command Term Tactic |
17 | 23 |
|
| 24 | +/-- |
| 25 | +The `run_cmd doSeq` command executes code in `CommandElabM Unit`. |
| 26 | +This is almost the same as `#eval show CommandElabM Unit from do doSeq`, |
| 27 | +except that it doesn't print an empty diagnostic. |
| 28 | +-/ |
18 | 29 | elab (name := runCmd) "run_cmd " elems:doSeq : command => do
|
19 | 30 | ← liftTermElabM <|
|
20 | 31 | unsafe evalTerm (CommandElabM Unit)
|
21 | 32 | (mkApp (mkConst ``CommandElabM) (mkConst ``Unit))
|
22 | 33 | (← `(discard do $elems))
|
| 34 | + |
| 35 | +/-- The `run_tac doSeq` tactic executes code in `TacticM Unit`. -/ |
| 36 | +elab (name := runTac) "run_tac" e:doSeq : tactic => do |
| 37 | + ← unsafe evalTerm (TacticM Unit) (mkApp (mkConst ``TacticM) (mkConst ``Unit)) |
| 38 | + (← `(discard do $e)) |
| 39 | + |
| 40 | +/-- |
| 41 | +* The `by_elab doSeq` expression runs the `doSeq` as a `TermElabM Expr` to |
| 42 | + synthesize the expression. |
| 43 | +* `by_elab fun expectedType? => do doSeq` receives the expected type (an `Option Expr`) |
| 44 | + as well. |
| 45 | +-/ |
| 46 | +syntax (name := byElab) "by_elab" doSeq : term |
| 47 | + |
| 48 | +/-- Elaborator for `by_elab`. -/ |
| 49 | +@[termElab byElab] def elabRunElab : TermElab := fun |
| 50 | +| `(by_elab $cmds:doSeq), expectedType? => do |
| 51 | + if let `(Lean.Parser.Term.doSeq| $e:term) := cmds then |
| 52 | + if e matches `(Lean.Parser.Term.doSeq| fun $_* => $_) then |
| 53 | + let tac ← unsafe evalTerm |
| 54 | + (Option Expr → TermElabM Expr) |
| 55 | + (Lean.mkForall `x .default |
| 56 | + (mkApp (mkConst ``Option) (mkConst ``Expr)) |
| 57 | + (mkApp (mkConst ``TermElabM) (mkConst ``Expr))) e |
| 58 | + return ← tac expectedType? |
| 59 | + (← unsafe evalTerm (TermElabM Expr) (mkApp (mkConst ``TermElabM) (mkConst ``Expr)) |
| 60 | + (← `(do $cmds))) |
| 61 | +| _, _ => throwUnsupportedSyntax |
0 commit comments