Make the code style more uniform. We still have a lot of leftovers from the old frontend.
122 lines
4.3 KiB
Text
122 lines
4.3 KiB
Text
/-
|
||
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 Lean.Message
|
||
import Lean.InternalExceptionId
|
||
import Lean.Data.Options
|
||
import Lean.Util.MonadCache
|
||
|
||
namespace Lean
|
||
|
||
/- Exception type used in most Lean monads -/
|
||
inductive Exception where
|
||
| error (ref : Syntax) (msg : MessageData)
|
||
| internal (id : InternalExceptionId) (extra : KVMap := {})
|
||
|
||
def Exception.toMessageData : Exception → MessageData
|
||
| Exception.error _ msg => msg
|
||
| Exception.internal id _ => id.toString
|
||
|
||
def Exception.getRef : Exception → Syntax
|
||
| Exception.error ref _ => ref
|
||
| Exception.internal _ _ => Syntax.missing
|
||
|
||
instance : Inhabited Exception := ⟨Exception.error default default⟩
|
||
|
||
/- Similar to `AddMessageContext`, but for error messages.
|
||
The default instance just uses `AddMessageContext`.
|
||
In error messages, we may want to provide additional information (e.g., macro expansion stack),
|
||
and refine the `(ref : Syntax)`. -/
|
||
class AddErrorMessageContext (m : Type → Type) where
|
||
add : Syntax → MessageData → m (Syntax × MessageData)
|
||
|
||
instance (m : Type → Type) [AddMessageContext m] [Monad m] : AddErrorMessageContext m where
|
||
add ref msg := do
|
||
let msg ← addMessageContext msg
|
||
pure (ref, msg)
|
||
|
||
class abbrev MonadError (m : Type → Type) :=
|
||
MonadExceptOf Exception m
|
||
MonadRef m
|
||
AddErrorMessageContext m
|
||
|
||
section Methods
|
||
|
||
protected def throwError [Monad m] [MonadError m] (msg : MessageData) : m α := do
|
||
let ref ← getRef
|
||
let (ref, msg) ← AddErrorMessageContext.add ref msg
|
||
throw <| Exception.error ref msg
|
||
|
||
def throwUnknownConstant [Monad m] [MonadError m] (constName : Name) : m α :=
|
||
Lean.throwError m!"unknown constant '{mkConst constName}'"
|
||
|
||
protected def throwErrorAt [Monad m] [MonadError m] (ref : Syntax) (msg : MessageData) : m α := do
|
||
withRef ref <| Lean.throwError msg
|
||
|
||
def ofExcept [Monad m] [MonadError m] [ToString ε] (x : Except ε α) : m α :=
|
||
match x with
|
||
| Except.ok a => pure a
|
||
| Except.error e => Lean.throwError <| toString e
|
||
|
||
def throwKernelException [Monad m] [MonadError m] [MonadOptions m] (ex : KernelException) : m α := do
|
||
Lean.throwError <| ex.toMessageData (← getOptions)
|
||
|
||
end Methods
|
||
|
||
class MonadRecDepth (m : Type → Type) where
|
||
withRecDepth {α} : Nat → m α → m α
|
||
getRecDepth : m Nat
|
||
getMaxRecDepth : m Nat
|
||
|
||
instance [Monad m] [MonadRecDepth m] : MonadRecDepth (ReaderT ρ m) where
|
||
withRecDepth d x := fun ctx => MonadRecDepth.withRecDepth d (x ctx)
|
||
getRecDepth := fun _ => MonadRecDepth.getRecDepth
|
||
getMaxRecDepth := fun _ => MonadRecDepth.getMaxRecDepth
|
||
|
||
instance [Monad m] [MonadRecDepth m] : MonadRecDepth (StateRefT' ω σ m) :=
|
||
inferInstanceAs (MonadRecDepth (ReaderT _ _))
|
||
|
||
instance [BEq α] [Hashable α] [Monad m] [STWorld ω m] [MonadRecDepth m] : MonadRecDepth (MonadCacheT α β m) :=
|
||
inferInstanceAs (MonadRecDepth (StateRefT' _ _ _))
|
||
|
||
def throwMaxRecDepthAt [MonadError m] (ref : Syntax) : m α :=
|
||
throw <| Exception.error ref (MessageData.ofFormat (Std.Format.text maxRecDepthErrorMessage))
|
||
|
||
/--
|
||
Return true if `ex` was generated by `throwMaxRecDepthAt`.
|
||
This function is a bit hackish. The max rec depth exception should probably be an internal exception,
|
||
but it is also produced by `MacroM` which implemented in the prelude, and internal exceptions have not
|
||
been defined yet. -/
|
||
def Exception.isMaxRecDepth (ex : Exception) : Bool :=
|
||
match ex with
|
||
| error _ (MessageData.ofFormat (Std.Format.text msg)) => msg == maxRecDepthErrorMessage
|
||
| _ => false
|
||
|
||
@[inline] def withIncRecDepth [Monad m] [MonadError m] [MonadRecDepth m] (x : m α) : m α := do
|
||
let curr ← MonadRecDepth.getRecDepth
|
||
let max ← MonadRecDepth.getMaxRecDepth
|
||
if curr == max then
|
||
throwMaxRecDepthAt (← getRef)
|
||
else
|
||
MonadRecDepth.withRecDepth (curr+1) x
|
||
|
||
syntax "throwError " (interpolatedStr(term) <|> term) : term
|
||
syntax "throwErrorAt " term:max (interpolatedStr(term) <|> term) : term
|
||
|
||
macro_rules
|
||
| `(throwError $msg) =>
|
||
if msg.getKind == interpolatedStrKind then
|
||
`(Lean.throwError (m! $msg))
|
||
else
|
||
`(Lean.throwError $msg)
|
||
|
||
macro_rules
|
||
| `(throwErrorAt $ref $msg) =>
|
||
if msg.getKind == interpolatedStrKind then
|
||
`(Lean.throwErrorAt $ref (m! $msg))
|
||
else
|
||
`(Lean.throwErrorAt $ref $msg)
|
||
|
||
end Lean
|