feat: make structure constructor

This commit is contained in:
Leonardo de Moura 2020-07-23 12:57:06 -07:00
parent 4950c199c2
commit ca096305b2
2 changed files with 33 additions and 1 deletions

View file

@ -59,6 +59,9 @@ structure StructFieldInfo :=
(kind : StructFieldKind)
(value? : Option Expr := none)
instance StructFieldInfo.inhabited : Inhabited StructFieldInfo :=
⟨{ name := arbitrary _, fvar := arbitrary _, kind := StructFieldKind.newField }⟩
structure ElabStructResult :=
(decl : Declaration)
@ -342,6 +345,27 @@ s ← collectLevelParamsInFVars ref params s;
s ← fieldInfos.foldlM (fun (s : CollectLevelParams.State) info => collectLevelParamsInFVar ref s info.fvar) s;
pure s.params
private def addCtorFields (ref : Syntax) (fieldInfos : Array StructFieldInfo) : Nat → Expr → TermElabM Expr
| 0, type => pure type
| i+1, type => do
let info := fieldInfos.get! i;
match info.kind with
| StructFieldKind.fromParent => do
decl ← Term.getFVarLocalDecl! info.fvar;
let val := decl.value;
let type := type.abstract #[info.fvar];
addCtorFields i (type.instantiate1 val)
| _ => do
type ← Term.mkForall ref #[info.fvar] type;
addCtorFields i type
private def mkCtor (view : StructView) (levelParams : List Name) (params : Array Expr) (fieldInfos : Array StructFieldInfo) : TermElabM Constructor := do
let type := mkAppN (mkConst view.declName (levelParams.map mkLevelParam)) params;
type ← addCtorFields view.ref fieldInfos fieldInfos.size type;
type ← Term.mkForall view.ref params type;
let type := type.inferImplicit params.size !view.ctor.inferMod;
pure { name := view.ctor.declName, type := type }
private def elabStructureView (view : StructView) : TermElabM ElabStructResult := do
let numExplicitParams := view.params.size;
type ← Term.elabType view.type;
@ -360,10 +384,12 @@ withFields view.fields 0 fieldInfos fun fieldInfos => do
match sortDeclLevelParams view.scopeLevelNames view.allUserLevelNames usedLevelNames with
| Except.error msg => Term.throwError ref msg
| Except.ok levelParams => do
let params := scopeVars ++ view.params;
structType ← Term.mkForall ref view.params type;
structType ← Term.mkForall ref scopeVars structType;
ctor ← mkCtor view levelParams params fieldInfos;
-- TODO
Term.throwError view.ref ("WIP " ++ toString levelParams ++ " " ++ structType)
Term.throwError view.ref ("WIP " ++ toString levelParams ++ " " ++ ctor.type)
/-
parser! (structureTk <|> classTk) >> declId >> many Term.bracketedBinder >> optional «extends» >> Term.optType >> " := " >> optional structCtor >> structFields

View file

@ -124,6 +124,12 @@ def getLCtx : TermElabM LocalContext := do ctx ← read; pure ctx.lctx
def getLocalInsts : TermElabM LocalInstances := do ctx ← read; pure ctx.localInstances
def getOptions : TermElabM Options := do ctx ← read; pure ctx.config.opts
def getLevelNames : TermElabM (List Name) := do ctx ← read; pure ctx.levelNames
def getFVarLocalDecl! (fvar : Expr) : TermElabM LocalDecl := do
lctx ← getLCtx;
match lctx.find? fvar.fvarId! with
| some d => pure d
| none => unreachable!
def setEnv (env : Environment) : TermElabM Unit := modify $ fun s => { s with env := env }
def setMCtx (mctx : MetavarContext) : TermElabM Unit := modify $ fun s => { s with mctx := mctx }