2023-05-09 16:39:24 -07:00
|
|
|
import Lean.Data.Json
|
2023-05-09 22:51:19 -07:00
|
|
|
import Lean.Environment
|
2023-05-07 15:19:45 -07:00
|
|
|
|
2023-08-13 21:19:06 -07:00
|
|
|
import Pantograph.Version
|
2024-03-09 16:50:36 -08:00
|
|
|
import Pantograph.Library
|
2023-08-13 21:19:06 -07:00
|
|
|
import Pantograph
|
2024-09-06 22:01:36 -07:00
|
|
|
import Repl
|
2023-05-09 22:51:19 -07:00
|
|
|
|
2023-05-09 16:39:24 -07:00
|
|
|
-- Main IO functions
|
2024-09-08 15:02:43 -07:00
|
|
|
open Pantograph.Repl
|
2023-05-09 16:39:24 -07:00
|
|
|
|
2023-08-22 09:54:37 -07:00
|
|
|
/-- Parse a command either in `{ "cmd": ..., "payload": ... }` form or `cmd { ... }` form. -/
|
2023-10-15 17:15:23 -07:00
|
|
|
def parseCommand (s: String): Except String Protocol.Command := do
|
2023-08-22 09:54:37 -07:00
|
|
|
let s := s.trim
|
|
|
|
match s.get? 0 with
|
|
|
|
| .some '{' => -- Parse in Json mode
|
|
|
|
Lean.fromJson? (← Lean.Json.parse s)
|
|
|
|
| .some _ => -- Parse in line mode
|
|
|
|
let offset := s.posOf ' ' |> s.offsetOfPos
|
|
|
|
if offset = s.length then
|
|
|
|
return { cmd := s.take offset, payload := Lean.Json.null }
|
|
|
|
else
|
|
|
|
let payload ← s.drop offset |> Lean.Json.parse
|
|
|
|
return { cmd := s.take offset, payload := payload }
|
|
|
|
| .none => throw "Command is empty"
|
|
|
|
|
2023-11-06 11:43:57 -08:00
|
|
|
partial def loop : MainM Unit := do
|
2023-08-16 19:25:32 -07:00
|
|
|
let state ← get
|
2023-05-20 15:58:38 -07:00
|
|
|
let command ← (← IO.getStdin).getLine
|
2023-05-22 14:49:56 -07:00
|
|
|
if command.trim.length = 0 then return ()
|
2023-10-15 17:15:23 -07:00
|
|
|
match parseCommand command with
|
2023-05-22 14:49:56 -07:00
|
|
|
| .error error =>
|
2023-10-15 17:15:23 -07:00
|
|
|
let error := Lean.toJson ({ error := "command", desc := error }: Protocol.InteractionError)
|
2023-08-16 19:25:32 -07:00
|
|
|
-- Using `Lean.Json.compress` here to prevent newline
|
|
|
|
IO.println error.compress
|
2023-05-20 15:58:38 -07:00
|
|
|
| .ok command =>
|
|
|
|
let ret ← execute command
|
2023-08-16 19:25:32 -07:00
|
|
|
let str := match state.options.printJsonPretty with
|
|
|
|
| true => ret.pretty
|
|
|
|
| false => ret.compress
|
|
|
|
IO.println str
|
2023-05-09 22:51:19 -07:00
|
|
|
loop
|
2023-05-09 16:39:24 -07:00
|
|
|
|
2023-08-14 17:07:53 -07:00
|
|
|
|
2023-05-23 05:12:46 -07:00
|
|
|
unsafe def main (args: List String): IO Unit := do
|
2023-08-13 21:19:06 -07:00
|
|
|
-- NOTE: A more sophisticated scheme of command line argument handling is needed.
|
|
|
|
-- Separate imports and options
|
|
|
|
if args == ["--version"] then do
|
|
|
|
println! s!"{version}"
|
|
|
|
return
|
|
|
|
|
2024-03-09 19:36:25 -08:00
|
|
|
initSearch ""
|
2023-05-23 05:12:46 -07:00
|
|
|
|
2024-03-09 16:50:36 -08:00
|
|
|
let coreContext ← args.filterMap (λ s => if s.startsWith "--" then .some <| s.drop 2 else .none)
|
|
|
|
|>.toArray |> createCoreContext
|
2023-05-24 00:54:48 -07:00
|
|
|
let imports:= args.filter (λ s => ¬ (s.startsWith "--"))
|
2024-03-09 16:50:36 -08:00
|
|
|
let coreState ← createCoreState imports.toArray
|
2023-05-20 15:58:38 -07:00
|
|
|
let context: Context := {
|
2023-08-14 17:07:53 -07:00
|
|
|
imports
|
2023-05-23 05:12:46 -07:00
|
|
|
}
|
2023-05-21 17:41:39 -07:00
|
|
|
try
|
2023-12-12 18:39:02 -08:00
|
|
|
let coreM := loop.run context |>.run' {}
|
2023-10-01 21:58:58 -07:00
|
|
|
IO.println "ready."
|
2024-03-09 16:50:36 -08:00
|
|
|
discard <| coreM.toIO coreContext coreState
|
2023-05-21 17:41:39 -07:00
|
|
|
catch ex =>
|
|
|
|
IO.println "Uncaught IO exception"
|
|
|
|
IO.println ex.toString
|