Skip to content

Commit bd36da3

Browse files
committed
merge file_mode
2 parents 0261af9 + 2ab7948 commit bd36da3

File tree

6 files changed

+67
-7
lines changed

6 files changed

+67
-7
lines changed

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,34 @@ However, if the first `def f` command returned `{"env" : 1}`, then we can use
9292
```
9393
and then the second invocation of `expensive_tactic` will be fast again.
9494

95+
## File mode
96+
97+
There is a simple wrapper around command mode that allows reading in an entire file.
98+
99+
If `test/file.lean` contains
100+
```lean
101+
def f : Nat := 37
102+
103+
def g := 2
104+
105+
theorem h : f + g = 39 := by exact rfl
106+
```
107+
108+
then
109+
```
110+
echo '{"path": "test/file.lean", "allTactics": true}' | lake exe repl
111+
```
112+
results in output
113+
```json
114+
{"tactics":
115+
[{"tactic": "exact rfl",
116+
"proofState": 0,
117+
"pos": {"line": 5, "column": 29},
118+
"goals": "⊢ f + g = 39",
119+
"endPos": {"line": 5, "column": 38}}],
120+
"env": 0}
121+
```
122+
95123
## Tactic mode (experimental)
96124

97125
To enter tactic mode issue a command containing a `sorry`,

REPL/JSON.lean

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,29 @@ open Lean Elab InfoTree
1111

1212
namespace REPL
1313

14+
structure CommandOptions where
15+
allTactics : Option Bool := none
16+
/--
17+
Should be "full", "tactics", "original", or "substantive".
18+
Anything else is ignored.
19+
-/
20+
infotree : Option String
21+
1422
/-- Run Lean commands.
1523
If `env = none`, starts a new session (in which you can use `import`).
1624
If `env = some n`, builds on the existing environment `n`.
1725
-/
18-
structure Command where
26+
structure Command extends CommandOptions where
1927
env : Option Nat
2028
incr : Option Nat
2129
cmd : String
22-
allTactics : Option Bool := none
23-
/--
24-
Should be "full", "tactics", "original", or "substantive".
25-
Anything else is ignored.
26-
-/
27-
infotree : Option String
2830
deriving ToJson, FromJson
2931

32+
/-- Process a Lean file in a fresh environment. -/
33+
structure File extends CommandOptions where
34+
path : System.FilePath
35+
deriving FromJson
36+
3037
/--
3138
Run a tactic in a proof state.
3239
-/

REPL/Main.lean

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,13 @@ def runCommand (s : Command) : M IO (CommandResponse ⊕ Error) := do
252252
tactics
253253
infotree }
254254

255+
def processFile (s : File) : M IO (CommandResponse ⊕ Error) := do
256+
try
257+
let cmd ← IO.FS.readFile s.path
258+
runCommand { s with env := none, cmd }
259+
catch e =>
260+
pure <| .inr ⟨e.toString⟩
261+
255262
/--
256263
Run a single tactic, returning the id of the new proof statement, and the new goals.
257264
-/
@@ -286,6 +293,7 @@ instance [ToJson α] [ToJson β] : ToJson (α ⊕ β) where
286293
/-- Commands accepted by the REPL. -/
287294
inductive Input
288295
| command : REPL.Command → Input
296+
| file : REPL.File → Input
289297
| proofStep : REPL.ProofStep → Input
290298
| pickleEnvironment : REPL.PickleEnvironment → Input
291299
| unpickleEnvironment : REPL.UnpickleEnvironment → Input
@@ -310,6 +318,8 @@ def parse (query : String) : IO Input := do
310318
| .ok (r : REPL.UnpickleProofState) => return .unpickleProofSnapshot r
311319
| .error _ => match fromJson? j with
312320
| .ok (r : REPL.Command) => return .command r
321+
| .error _ => match fromJson? j with
322+
| .ok (r : REPL.File) => return .file r
313323
| .error e => throw <| IO.userError <| toString <| toJson <|
314324
(⟨"Could not parse as a valid JSON command:\n" ++ e⟩ : Error)
315325

@@ -323,6 +333,7 @@ where loop : M IO Unit := do
323333
if query.startsWith "#" || query.startsWith "--" then loop else
324334
IO.println <| toString <| ← match ← parse query with
325335
| .command r => return toJson (← runCommand r)
336+
| .file r => return toJson (← processFile r)
326337
| .proofStep r => return toJson (← runProofStep r)
327338
| .pickleEnvironment r => return toJson (← pickleCommandSnapshot r)
328339
| .unpickleEnvironment r => return toJson (← unpickleCommandSnapshot r)

test/file.expected.out

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{"tactics":
2+
[{"tactic": "exact rfl",
3+
"proofState": 0,
4+
"pos": {"line": 5, "column": 29},
5+
"goals": "⊢ f + g = 39",
6+
"endPos": {"line": 5, "column": 38}}],
7+
"env": 0}
8+

test/file.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"path": "test/file.lean", "allTactics": true}

test/file.lean

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
def f : Nat := 37
2+
3+
def g := 2
4+
5+
theorem h : f + g = 39 := by exact rfl

0 commit comments

Comments
 (0)