feat: generalize helper functions

This commit is contained in:
Leonardo de Moura 2022-08-11 17:37:50 -07:00
parent 4361eef907
commit 6a67c13044
3 changed files with 38 additions and 27 deletions

View file

@ -23,28 +23,9 @@ instance : AddMessageContext CompilerM where
let opts ← getOptions
return MessageData.withContext { env, lctx, opts, mctx := {} } msgData
/--
Infer the type of a LCNF expression.
-/
def inferType (e : Expr) : CompilerM Expr := do
InferType.inferType e { lctx := (← get).lctx }
def getLevel (type : Expr) : CompilerM Level := do
match (← inferType type) with
| .sort u => return u
| e => if e.isAnyType then return levelOne else throwError "type expected{indentExpr type}"
/-- Create `lcUnreachable type` -/
def mkLcUnreachable (type : Expr) : CompilerM Expr := do
let u ← getLevel type
return .app (.const ``lcUnreachable [u]) type
/-- Create `lcCast expectedType e : expectedType` -/
def mkLcCast (e : Expr) (expectedType : Expr) : CompilerM Expr := do
let type ← inferType e
let u ← getLevel type
let v ← getLevel expectedType
return mkApp3 (.const ``lcCast [u, v]) type expectedType e
instance : MonadInferType CompilerM where
inferType e := do
InferType.inferType e { lctx := (← get).lctx }
def mkLocalDecl (binderName : Name) (type : Expr) (bi := BinderInfo.default) : CompilerM Expr := do
let fvarId ← mkFreshFVarId

View file

@ -6,7 +6,12 @@ Authors: Leonardo de Moura
import Lean.Compiler.LCNFTypes
import Lean.Compiler.Util
namespace Lean.Compiler.InferType
namespace Lean.Compiler
class MonadInferType (m : Type → Type) where
inferType : Expr → m Expr
namespace InferType
structure InferTypeM.Context where
lctx : LocalContext
@ -140,4 +145,30 @@ mutual
| .forallE .. => inferForallType e
| .lam .. => inferLambdaType e
| .letE .. => inferLambdaType e
end
end
end InferType
instance : MonadInferType InferType.InferTypeM where
inferType := InferType.inferType
export MonadInferType (inferType)
def getLevel [Monad m] [MonadInferType m] [MonadError m] (type : Expr) : m Level := do
match (← inferType type) with
| .sort u => return u
| e => if e.isAnyType then return levelOne else throwError "type expected{indentExpr type}"
/-- Create `lcUnreachable type` -/
def mkLcUnreachable [Monad m] [MonadInferType m] [MonadError m] (type : Expr) : m Expr := do
let u ← getLevel type
return .app (.const ``lcUnreachable [u]) type
/-- Create `lcCast expectedType e : expectedType` -/
def mkLcCast [Monad m] [MonadInferType m] [MonadError m] (e : Expr) (expectedType : Expr) : m Expr := do
let type ← inferType e
let u ← getLevel type
let v ← getLevel expectedType
return mkApp3 (.const ``lcCast [u, v]) type expectedType e
end Lean.Compiler

View file

@ -41,9 +41,8 @@ structure State where
abbrev M := ReaderT Context $ StateRefT State CoreM
/-- Return the type of the given LCNF expression. -/
def inferType (e : Expr) : M Expr := do
InferType.inferType e { lctx := (← get).lctx' }
instance : MonadInferType M where
inferType e := do InferType.inferType e { lctx := (← get).lctx' }
@[inline] def liftMetaM (x : MetaM α) : M α := do
x.run' { lctx := (← get).lctx }