Skip to content

Commit 778ab6a

Browse files
authored
Merge pull request #47 from mlabs-haskell/compiler/constructor-based-check
compiler: Constructor based KC
2 parents cc8f0d8 + d131862 commit 778ab6a

File tree

2 files changed

+59
-27
lines changed

2 files changed

+59
-27
lines changed

lambda-buffers-compiler/src/LambdaBuffers/Compiler/KindCheck.hs

Lines changed: 58 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import LambdaBuffers.Compiler.KindCheck.Inference (
3636
)
3737
import LambdaBuffers.Compiler.KindCheck.Inference qualified as I
3838
import LambdaBuffers.Compiler.KindCheck.Kind (kind2ProtoKind)
39-
import LambdaBuffers.Compiler.KindCheck.Type (Type (App), tyEither, tyOpaque, tyProd, tyUnit, tyVoid)
39+
import LambdaBuffers.Compiler.KindCheck.Type (Type (App), tyEither, tyProd, tyUnit, tyVoid)
4040
import LambdaBuffers.Compiler.KindCheck.Variable (Variable (ForeignRef, LocalRef))
4141
import LambdaBuffers.Compiler.ProtoCompat ()
4242
import LambdaBuffers.Compiler.ProtoCompat.Types qualified as PC
@@ -67,18 +67,20 @@ makeEffect ''GlobalCheck
6767
-- | Interactions that happen at the level of the
6868
data ModuleCheck a where -- Module
6969
KCTypeDefinition :: ModName -> Context -> PC.TyDef -> ModuleCheck Kind
70-
KCClassInstance :: Context -> PC.InstanceClause -> ModuleCheck ()
71-
KCClass :: Context -> PC.ClassDef -> ModuleCheck ()
70+
71+
-- fixme(cstml & gnumonik): lets reach consensus on these - Note(1).
72+
-- KCClassInstance :: Context -> P.InstanceClause -> ModuleCheck ()
73+
-- KCClass :: Context -> P.ClassDef -> ModuleCheck ()
7274

7375
makeEffect ''ModuleCheck
7476

7577
data KindCheck a where
76-
KindFromTyDef :: ModName -> PC.TyDef -> KindCheck Type
78+
TypesFromTyDef :: ModName -> PC.TyDef -> KindCheck [Type]
7779
InferTypeKind :: ModName -> PC.TyDef -> Context -> Type -> KindCheck Kind
7880
CheckKindConsistency :: ModName -> PC.TyDef -> Context -> Kind -> KindCheck Kind
7981

80-
-- FIXME(cstml): Add check for Context Consistency
81-
-- TyDefToTypes :: ModName -> PC.TyDef -> KindCheck [Type]
82+
-- TypeFromTyDef :: ModName -> P.TyDef -> KindCheck Type -- replaced with constructor by constructor check
83+
8284
makeEffect ''KindCheck
8385

8486
--------------------------------------------------------------------------------
@@ -118,20 +120,27 @@ moduleStrategy = reinterpret $ \case
118120
CreateContext ci -> evalState (mempty @(M.Map Variable PC.TyDef)) . resolveCreateContext $ ci
119121
ValidateModule cx md -> do
120122
traverse_ (kCTypeDefinition (module2ModuleName md) cx) (md ^. #typeDefs)
121-
traverse_ (kCClassInstance cx) (md ^. #instances)
122-
traverse_ (kCClass cx) (md ^. #classDefs)
123123

124124
localStrategy :: Transform ModuleCheck KindCheck
125125
localStrategy = reinterpret $ \case
126126
KCTypeDefinition mname ctx tydef -> do
127-
kindFromTyDef mname tydef >>= inferTypeKind mname tydef ctx >>= checkKindConsistency mname tydef ctx
128-
KCClassInstance _ctx _instClause -> pure () -- FIXME(cstml)
129-
KCClass _ctx _classDef -> pure () -- FIXME(cstml)
127+
typesFromTyDef mname tydef
128+
>>= traverse (inferTypeKind mname tydef ctx)
129+
>>= traverse (checkKindConsistency mname tydef ctx)
130+
>>= traverse (checkKindConsistency mname tydef ctx)
131+
>>= \case
132+
[] -> pure Type -- Void
133+
x : _ -> pure x -- The Kind of the first constructor ~ already checked
134+
-- and consistent.
135+
{- See note (1).
136+
-- KCClassInstance _ctx _instClause -> pure ()
137+
-- KCClass _ctx _classDef -> pure ()
138+
-}
130139

131140
runKindCheck :: forall effs {a}. Member Err effs => Eff (KindCheck ': effs) a -> Eff effs a
132141
runKindCheck = interpret $ \case
133-
KindFromTyDef moduleName tydef -> runReader moduleName (tyDef2Type tydef)
134-
-- TyDefToTypes moduleName tydef -> runReader moduleName (tyDef2Types tydef)
142+
-- TypeFromTyDef moduleName tydef -> runReader moduleName (tyDef2Type tydef)
143+
TypesFromTyDef moduleName tydef -> runReader moduleName (tyDef2Types tydef)
135144
InferTypeKind _modName tyDef ctx ty -> either (handleErr tyDef) pure $ infer ctx ty
136145
CheckKindConsistency mname def ctx k -> runReader mname $ resolveKindConsistency def ctx k
137146
where
@@ -219,14 +228,29 @@ tyDef2Context ::
219228
Eff effs Context
220229
tyDef2Context curModName tyDef = do
221230
r@(v, _) <- tyDef2NameAndKind curModName tyDef
231+
ctx2 <- tyDefArgs2Context tyDef
222232
associateName v tyDef
223-
pure $ mempty & context .~ uncurry M.singleton r
233+
pure $ mempty & context .~ uncurry M.singleton r <> ctx2
224234
where
225235
-- Ads the name to our map - we can use its SourceLocation in the case of a
226236
-- double use. If it's already in our map - that means we've double declared it.
227237
associateName :: Variable -> PC.TyDef -> Eff effs ()
228238
associateName v curTyDef = modify (M.insert v curTyDef)
229239

240+
{- | Gets the kind of the variables from the definition and adds them to the
241+
context.
242+
-}
243+
tyDefArgs2Context :: PC.TyDef -> Eff effs (M.Map Variable Kind)
244+
tyDefArgs2Context tydef = do
245+
let ds = g <$> M.elems (tydef ^. #tyAbs . #tyArgs)
246+
pure $ M.fromList ds
247+
where
248+
g :: PC.TyArg -> (Variable, Kind)
249+
g tyarg = (v, k)
250+
where
251+
v = LocalRef (tyarg ^. #argName . #name)
252+
k = pKind2Kind (tyarg ^. #argKind)
253+
230254
{- | Converts the Proto Module name to a local modname - dropping the
231255
information.
232256
-}
@@ -241,31 +265,34 @@ tyDef2NameAndKind curModName tyDef = do
241265
pure (name, k)
242266

243267
tyAbsLHS2Kind :: PC.TyAbs -> Kind
244-
tyAbsLHS2Kind tyAbs = foldWithArrow $ pKind2Type . (\x -> x ^. #argKind) <$> toList (tyAbs ^. #tyArgs)
268+
tyAbsLHS2Kind tyAbs = foldWithArrow $ pKind2Kind . (\x -> x ^. #argKind) <$> toList (tyAbs ^. #tyArgs)
245269

246270
foldWithArrow :: [Kind] -> Kind
247-
foldWithArrow = foldl (:->:) Type
271+
foldWithArrow = foldr (:->:) Type
248272

249273
-- ================================================================================
250274
-- To Kind Conversion functions
251275

252-
pKind2Type :: PC.Kind -> Kind
253-
pKind2Type k =
276+
pKind2Kind :: PC.Kind -> Kind
277+
pKind2Kind k =
254278
case k ^. #kind of
255279
PC.KindRef PC.KType -> Type
256-
PC.KindArrow l r -> pKind2Type l :->: pKind2Type r
280+
PC.KindArrow l r -> pKind2Kind l :->: pKind2Kind r
257281
-- FIXME(cstml) what is an undefined type meant to mean?
258282
_ -> error "Fixme undefined type"
259283

260-
{- | TyDef to Kind Canonical representation.
261-
TODO(@cstml): Move this close to KindCheck/Type.hs (even just there).
262-
-}
284+
-- =============================================================================
285+
-- X To Canonical type conversion functions.
286+
287+
{- Replaced with Constructor by Constructor check.
288+
-- | TyDef to Kind Canonical representation.
263289
tyDef2Type ::
264290
forall eff.
265291
Members '[Reader ModName, Err] eff =>
266292
PC.TyDef ->
267293
Eff eff Type
268294
tyDef2Type tyde = tyAbsLHS2Type (tyde ^. #tyAbs) <*> tyAbsRHS2Type (tyde ^. #tyAbs)
295+
-}
269296

270297
tyAbsLHS2Type ::
271298
forall eff.
@@ -286,6 +313,7 @@ tyArgs2Type = \case
286313
tyArg2Var :: PC.TyArg -> Variable
287314
tyArg2Var = LocalRef . view (#argName . #name)
288315

316+
{- Replaced with Constructor by Constructor check.
289317
tyAbsRHS2Type ::
290318
forall eff.
291319
Members '[Reader ModName, Err] eff =>
@@ -308,6 +336,7 @@ sum2Type ::
308336
PC.Sum ->
309337
Eff eff Type
310338
sum2Type su = foldWithSum <$> traverse constructor2Type (toList $ su ^. #constructors)
339+
-}
311340

312341
constructor2Type ::
313342
forall eff.
@@ -402,8 +431,11 @@ foreignTyRef2Type ftr = do
402431

403432
-- =============================================================================
404433
-- X To Canonical type conversion functions.
405-
{-
406-
-- | TyDef to Kind Canonical representation - sums not folded - therefore we get constructor granularity. Might use in a different implementation for more granular errors.
434+
435+
{- | TyDef to Kind Canonical representation - sums not folded - therefore we get
436+
constructor granularity. Might use in a different implementation for more
437+
granular errors.
438+
-}
407439
tyDef2Types ::
408440
forall eff.
409441
Members '[Reader ModName, Err] eff =>
@@ -435,8 +467,8 @@ sum2Types ::
435467
Members '[Reader ModName, Err] eff =>
436468
PC.Sum ->
437469
Eff eff [Type]
438-
sum2Types su = NonEmpty.toList <$> traverse constructor2Type (su ^. #constructors)
439-
-}
470+
sum2Types su = traverse constructor2Type $ M.elems (su ^. #constructors)
471+
440472
--------------------------------------------------------------------------------
441473
-- Utilities
442474

lambda-buffers-compiler/src/LambdaBuffers/Compiler/KindCheck/Inference.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ derive x = do
122122
tell [Constraint (ty1, ty2 :->: v)]
123123
pure $ Application (Judgement (c, x, v)) d1 d2
124124
Abs v t -> do
125-
newTy <- KVar <$> fresh
125+
newTy <- getBinding v
126126
d <- local (\(Context ctx addC) -> Context ctx $ M.insert v newTy addC) (derive t)
127127
let ty = d ^. topKind
128128
freshT <- KVar <$> fresh

0 commit comments

Comments
 (0)