lean4-htt/src/Lean/CoreM.lean
Leonardo de Moura e000fcaeda chore: cleanup
2020-08-24 12:17:47 -07:00

106 lines
3.8 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2020 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
import Init.System.IO
import Init.Control.StateRef
import Lean.Util.RecDepth
import Lean.Util.Trace
import Lean.Environment
import Lean.Exception
import Lean.InternalExceptionId
import Lean.Eval
import Lean.MonadEnv
namespace Lean
namespace Core
structure State :=
(env : Environment)
(ngen : NameGenerator := {})
(traceState : TraceState := {})
instance State.inhabited : Inhabited State := ⟨{ env := arbitrary _ }⟩
structure Context :=
(options : Options := {})
(currRecDepth : Nat := 0)
(maxRecDepth : Nat := 1000)
(ref : Syntax := Syntax.missing)
abbrev CoreM := ReaderT Context $ StateRefT State $ EIO Exception
instance CoreM.inhabited {α} : Inhabited (CoreM α) :=
⟨fun _ _ => throw $ arbitrary _⟩
instance : MonadError CoreM :=
{ getRef := do ctx ← read; pure ctx.ref,
withRef := fun α ref x => adaptReader (fun (ctx : Context) => { ctx with ref := ref }) x,
addContext := fun ref msg => do
ctx ← read;
s ← get;
pure (ref, MessageData.withContext { env := s.env, mctx := {}, lctx := {}, opts := ctx.options } msg) }
instance : MonadEnv CoreM :=
{ getEnv := do s ← get; pure s.env,
modifyEnv := fun f => modify fun s => { s with env := f s.env } }
instance : MonadOptions CoreM :=
{ getOptions := do ctx ← read; pure ctx.options }
instance : MonadNameGenerator CoreM :=
{ getNGen := do s ← get; pure s.ngen,
setNGen := fun ngen => modify fun s => { s with ngen := ngen } }
instance : MonadRecDepth CoreM :=
{ withRecDepth := fun α d x => adaptReader (fun (ctx : Context) => { ctx with currRecDepth := d }) x,
getRecDepth := do ctx ← read; pure ctx.currRecDepth,
getMaxRecDepth := do ctx ← read; pure ctx.maxRecDepth }
@[inline] def liftIOCore {α} (x : IO α) : CoreM α := do
ref ← getRef;
liftM $ (adaptExcept (fun (err : IO.Error) => Exception.error ref (toString err)) x : EIO Exception α)
instance : MonadIO CoreM :=
{ liftIO := @liftIOCore }
instance : SimpleMonadTracerAdapter CoreM :=
{ getOptions := getOptions,
getTraceState := do s ← get; pure s.traceState,
addTraceContext := fun msg => Prod.snd <$> addContext Syntax.missing msg,
modifyTraceState := fun f => modify $ fun s => { s with traceState := f s.traceState } }
@[inline] def CoreM.run {α} (x : CoreM α) (ctx : Context) (s : State) : EIO Exception (α × State) :=
(x.run ctx).run s
@[inline] def CoreM.run' {α} (x : CoreM α) (ctx : Context) (s : State) : EIO Exception α :=
Prod.fst <$> x.run ctx s
@[inline] def CoreM.toIO {α} (x : CoreM α) (ctx : Context) (s : State) : IO (α × State) :=
adaptExcept
(fun (ex : Exception) => match ex with
| Exception.error _ msg => IO.userError $ toString $ format msg
| Exception.internal id => IO.userError $ toString $ "internal exception #" ++ toString id.idx)
(x.run ctx s)
instance hasEval {α} [MetaHasEval α] : MetaHasEval (CoreM α) :=
⟨fun env opts x _ => do
(a, s) ← (finally x printTraces).toIO { maxRecDepth := getMaxRecDepth opts, options := opts} { env := env};
MetaHasEval.eval s.env opts a⟩
end Core
export Core (CoreM)
@[inline] def catchInternalId {α} {m : Type → Type} [MonadExcept Exception m] (id : InternalExceptionId) (x : m α) (h : Exception → m α) : m α :=
catch x fun ex => match ex with
| Exception.error _ _ => throw ex
| Exception.internal id' => if id == id' then h ex else throw ex
@[inline] def catchInternalIds {α} {m : Type → Type} [MonadExcept Exception m] (ids : List InternalExceptionId) (x : m α) (h : Exception → m α) : m α :=
catch x fun ex => match ex with
| Exception.error _ _ => throw ex
| Exception.internal id => if ids.contains id then h ex else throw ex
end Lean