Merge branch 'main' of github.com:leanprover-community/lean4game

pull/43/head
Jon Eugster 2 years ago
commit 695903f5d8

@ -26,9 +26,6 @@ partial def parseTactic (inputCtx : InputContext) (pmctx : ParserModuleContext)
let mut recovering := mps.recovering let mut recovering := mps.recovering
let mut messages := messages let mut messages := messages
let mut stx := Syntax.missing -- will always be assigned below let mut stx := Syntax.missing -- will always be assigned below
if inputCtx.input.atEnd pos ∧ couldBeEndSnap then
stx := mkEOI pos
return (stx, { pos, recovering }, messages, 0)
let tokens := getTokenTable pmctx.env let tokens := getTokenTable pmctx.env
@ -107,38 +104,55 @@ where addErrorMessage (info : SourceInfo) (s : MessageData) :=
open Elab Meta Expr in open Elab Meta Expr in
def compileProof (inputCtx : Parser.InputContext) (snap : Snapshot) (hasWidgets : Bool) (couldBeEndSnap : Bool) : IO Snapshot := do def compileProof (inputCtx : Parser.InputContext) (snap : Snapshot) (hasWidgets : Bool) (couldBeEndSnap : Bool) : IO Snapshot := do
let cmdState := snap.cmdState -- Recognize end snap
let scope := cmdState.scopes.head! if inputCtx.input.atEnd snap.mpState.pos ∧ couldBeEndSnap then
let pmctx := { env := cmdState.env, options := scope.opts, currNamespace := scope.currNamespace, openDecls := scope.openDecls }
let (tacticStx, cmdParserState, msgLog, endOfWhitespace) :=
MyModule.parseTactic inputCtx pmctx snap.mpState snap.msgLog couldBeEndSnap
let cmdPos := tacticStx.getPos?.getD 0
if Parser.isTerminalCommand tacticStx then
let endSnap : Snapshot := { let endSnap : Snapshot := {
beginPos := cmdPos beginPos := snap.mpState.pos
stx := tacticStx stx := MyModule.mkEOI snap.mpState.pos
mpState := cmdParserState mpState := snap.mpState
cmdState := snap.cmdState cmdState := snap.cmdState
interactiveDiags := ← withNewInteractiveDiags msgLog interactiveDiags := ← withNewInteractiveDiags snap.msgLog
tacticCache := snap.tacticCache tacticCache := snap.tacticCache
} }
return endSnap return endSnap
else
let cmdStateRef ← IO.mkRef { snap.cmdState with messages := msgLog } let parseResultRef ← IO.mkRef (Syntax.missing, snap.mpState)
/- The same snapshot may be executed by different tasks. So, to make sure `elabCommandTopLevel` has exclusive
access to the cache, we create a fresh reference here. Before this change, the let cmdStateRef ← IO.mkRef snap.cmdState
following `snap.tacticCache.modify` would reset the tactic post cache while another snapshot was still using it. -/ /- The same snapshot may be executed by different tasks. So, to make sure `elabCommandTopLevel` has exclusive
let tacticCacheNew ← IO.mkRef (← snap.tacticCache.get) access to the cache, we create a fresh reference here. Before this change, the
let cmdCtx : Elab.Command.Context := { following `snap.tacticCache.modify` would reset the tactic post cache while another snapshot was still using it. -/
cmdPos := snap.endPos let tacticCacheNew ← IO.mkRef (← snap.tacticCache.get)
fileName := inputCtx.fileName let cmdCtx : Elab.Command.Context := {
fileMap := inputCtx.fileMap cmdPos := snap.endPos
tacticCache? := some tacticCacheNew fileName := inputCtx.fileName
} fileMap := inputCtx.fileMap
let (output, _) ← IO.FS.withIsolatedStreams (isolateStderr := server.stderrAsMessages.get scope.opts) <| liftM (m := BaseIO) do tacticCache? := some tacticCacheNew
Elab.Command.catchExceptions }
(getResetInfoTrees *> do let (output, _) ← IO.FS.withIsolatedStreams (isolateStderr := server.stderrAsMessages.get snap.cmdState.scopes.head!.opts) <| liftM (m := BaseIO) do
let level ← GameServer.getLevelByFileName inputCtx.fileName Elab.Command.catchExceptions
(getResetInfoTrees *> do
let level ← GameServer.getLevelByFileName inputCtx.fileName
let scope := level.scope
-- use open namespaces and options as in the level file
Elab.Command.withScope (fun _ => scope) do
for od in scope.openDecls do
let .simple ns _ := od
| pure ()
activateScoped ns
activateScoped scope.currNamespace
-- parse tactics
let pmctx := {
env := ← getEnv,
options := scope.opts,
currNamespace := scope.currNamespace,
openDecls := scope.openDecls }
let (tacticStx, cmdParserState, msgLog, endOfWhitespace) :=
MyModule.parseTactic inputCtx pmctx snap.mpState snap.msgLog couldBeEndSnap
modify (fun s => { s with messages := msgLog })
parseResultRef.set (tacticStx, cmdParserState)
-- Check for forbidden tactics -- Check for forbidden tactics
findForbiddenTactics inputCtx level tacticStx findForbiddenTactics inputCtx level tacticStx
@ -150,34 +164,35 @@ def compileProof (inputCtx : Parser.InputContext) (snap : Snapshot) (hasWidgets
let tacticStx := (#[skip] ++ tacticStx.getArgs ++ #[done]).map (⟨.⟩) let tacticStx := (#[skip] ++ tacticStx.getArgs ++ #[done]).map (⟨.⟩)
let tacticStx := ← `(Lean.Parser.Tactic.tacticSeq| $[$(tacticStx)]*) let tacticStx := ← `(Lean.Parser.Tactic.tacticSeq| $[$(tacticStx)]*)
let cmdStx ← `(command| theorem the_theorem $(level.goal) := by {$(⟨tacticStx⟩)} ) let cmdStx ← `(command|
theorem the_theorem $(level.goal) := by {$(⟨tacticStx⟩)} )
Elab.Command.withScope (fun _ => level.scope) do -- use open namespaces and options as in the file Elab.Command.elabCommandTopLevel cmdStx)
Elab.Command.elabCommandTopLevel cmdStx) cmdCtx cmdStateRef
cmdCtx cmdStateRef let postNew := (← tacticCacheNew.get).post
let postNew := (← tacticCacheNew.get).post snap.tacticCache.modify fun _ => { pre := postNew, post := {} }
snap.tacticCache.modify fun _ => { pre := postNew, post := {} } let mut postCmdState ← cmdStateRef.get
let mut postCmdState ← cmdStateRef.get if !output.isEmpty then
if !output.isEmpty then postCmdState := {
postCmdState := { postCmdState with
postCmdState with messages := postCmdState.messages.add {
messages := postCmdState.messages.add { fileName := inputCtx.fileName
fileName := inputCtx.fileName severity := MessageSeverity.information
severity := MessageSeverity.information pos := inputCtx.fileMap.toPosition snap.endPos
pos := inputCtx.fileMap.toPosition snap.endPos data := output
data := output
}
} }
let postCmdSnap : Snapshot := {
beginPos := cmdPos
stx := tacticStx
mpState := cmdParserState
cmdState := postCmdState
interactiveDiags := ← withNewInteractiveDiags postCmdState.messages
tacticCache := (← IO.mkRef {})
} }
return postCmdSnap
let (tacticStx, cmdParserState) ← parseResultRef.get
let postCmdSnap : Snapshot := {
beginPos := tacticStx.getPos?.getD 0
stx := tacticStx
mpState := cmdParserState
cmdState := postCmdState
interactiveDiags := ← withNewInteractiveDiags postCmdState.messages
tacticCache := (← IO.mkRef {})
}
return postCmdSnap
where where
/-- Compute the current interactive diagnostics log by finding a "diff" relative to the parent /-- Compute the current interactive diagnostics log by finding a "diff" relative to the parent

Loading…
Cancel
Save