@@ -9,7 +9,8 @@ module LambdaBuffers.Compiler.KindCheck (
99 foldWithArrowToType ,
1010) where
1111
12- import Control.Lens (Getter , to , view , (&) , (.~) , (^.) )
12+ import Control.Lens (view , (&) , (.~) , (^.) )
13+ import Control.Lens.Iso (withIso )
1314import Control.Monad (void )
1415import Control.Monad.Freer (Eff , Member , Members , interpret , reinterpret , run )
1516import Control.Monad.Freer.Error (Error , runError , throwError )
@@ -18,11 +19,16 @@ import Control.Monad.Freer.TH (makeEffect)
1819import Data.Default (Default (def ))
1920import Data.Foldable (Foldable (toList ), traverse_ )
2021import Data.Map qualified as M
21-
22- import LambdaBuffers.Compiler.KindCheck.Derivation ( Context , context )
22+ import LambdaBuffers.Compiler.KindCheck.Derivation ( Context , constraintContext , context )
23+ import LambdaBuffers.Compiler.KindCheck.Inference ( protoKind2Kind )
2324import LambdaBuffers.Compiler.KindCheck.Inference qualified as I
24- import LambdaBuffers.Compiler.KindCheck.Kind (Kind (KType , (:->:) ), kind2ProtoKind )
25- import LambdaBuffers.Compiler.KindCheck.Type (Variable (QualifiedTyRef , TyVar ))
25+ import LambdaBuffers.Compiler.KindCheck.Kind (Kind (KConstraint , KType , KVar , (:->:) ))
26+ import LambdaBuffers.Compiler.KindCheck.Type (
27+ Variable (QualifiedConstraint , QualifiedTyRef , TyVar ),
28+ ftrISOqtr ,
29+ ltrISOqtr ,
30+ qTyRef'moduleName ,
31+ )
2632import LambdaBuffers.Compiler.ProtoCompat.InfoLess (InfoLess , mkInfoLess )
2733import LambdaBuffers.Compiler.ProtoCompat.Types qualified as PC
2834
@@ -50,18 +56,20 @@ makeEffect ''GlobalCheck
5056-- | Interactions that happen at the level of the
5157data ModuleCheck a where -- Module
5258 KCTypeDefinition :: PC. ModuleName -> Context -> PC. TyDef -> ModuleCheck Kind
59+ KCClassInstance :: PC. ModuleName -> Context -> PC. ClassDef -> ModuleCheck ()
5360
54- -- NOTE(cstml & gnumonik): Lets reach consensus on these - Note(1).
55- -- KCClassInstance :: Context -> P.InstanceClause -> ModuleCheck ()
5661-- KCClass :: Context -> P.ClassDef -> ModuleCheck ()
5762
5863makeEffect ''ModuleCheck
5964
6065data KindCheck a where
6166 GetSpecifiedKind :: PC. ModuleName -> PC. TyDef -> KindCheck Kind
6267 InferTypeKind :: PC. ModuleName -> PC. TyDef -> Context -> Kind -> KindCheck Kind
68+ CheckClassDefinition :: PC. ModuleName -> PC. ClassDef -> Context -> KindCheck ()
6369 CheckKindConsistency :: PC. ModuleName -> PC. TyDef -> Context -> Kind -> KindCheck Kind
6470
71+ -- CheckClassInstance :: PC.ModuleName -> KindCheck Kind
72+
6573makeEffect ''KindCheck
6674
6775--------------------------------------------------------------------------------
@@ -113,57 +121,48 @@ localStrategy = reinterpret $ \case
113121 desiredK <- getSpecifiedKind modName tyDef
114122 k <- inferTypeKind modName tyDef ctx desiredK
115123 checkKindConsistency modName tyDef ctx k
124+ KCClassInstance modName ctx classDef -> do
125+ _ <- checkClassDefinition modName classDef ctx
126+ pure ()
116127
117128runKindCheck :: forall effs {a }. Member Err effs => Eff (KindCheck ': effs ) a -> Eff effs a
118129runKindCheck = interpret $ \ case
119- InferTypeKind modName tyDef ctx k ->
120- either (handleErr modName tyDef) pure $ I. infer ctx tyDef k modName
130+ InferTypeKind modName tyDef ctx _k ->
131+ either (handleErr modName tyDef) pure $ I. infer ctx tyDef modName
121132 CheckKindConsistency modName tyDef ctx k ->
122133 runReader modName $ resolveKindConsistency tyDef ctx k
123134 GetSpecifiedKind modName tyDef ->
124135 fmap snd $ runReader modName $ tyDef2NameAndKind tyDef
136+ CheckClassDefinition modName classDef ctx ->
137+ either (handleErr2 modName classDef) pure $ I. runClassDefCheck ctx modName classDef
125138 where
139+ handleErr2 = undefined
140+
126141 handleErr :: forall {b }. PC. ModuleName -> PC. TyDef -> I. InferErr -> Eff effs b
127142 handleErr modName td = \ case
128- I. InferUnboundTermErr uA -> do
129- case uA of
130- QualifiedTyRef fr ->
131- if (fr ^. # moduleName) == modName
132- then -- We're looking at the local module.
133-
134- throwError
135- . PC. CompKindCheckError
136- $ PC. UnboundTyRefError td (PC. LocalI $ fr ^. foreignRef2LocalRef) modName
137- else -- We're looking at a foreign module.
138-
139- throwError
140- . PC. CompKindCheckError
141- $ PC. UnboundTyRefError td (PC. ForeignI fr) modName
143+ I. InferUnboundTermErr ut ->
144+ case ut of
145+ QualifiedTyRef qtr -> do
146+ if qtr ^. qTyRef'moduleName == modName
147+ then do
148+ -- We're looking at the local module.
149+ let localRef = PC. LocalI . fst . withIso ltrISOqtr (\ _ f -> f) $ qtr
150+ let err = PC. UnboundTyRefError td localRef modName
151+ throwError . PC. CompKindCheckError $ err
152+ else do
153+ -- We're looking at a foreign module.
154+ let foreignRef = PC. ForeignI . withIso ftrISOqtr (\ _ f -> f) $ qtr
155+ throwError . PC. CompKindCheckError $ PC. UnboundTyRefError td foreignRef modName
142156 TyVar tv ->
143- throwError
144- . PC. CompKindCheckError
145- $ PC. UnboundTyVarError td (PC. TyVar tv) modName
146- I. InferUnifyTermErr (I. Constraint (k1, k2)) ->
147- throwError
148- . PC. CompKindCheckError
149- $ PC. IncorrectApplicationError td (kind2ProtoKind k1) (kind2ProtoKind k2) modName
157+ throwError . PC. CompKindCheckError $ PC. UnboundTyVarError td (PC. TyVar tv) modName
158+ QualifiedConstraint _ -> error " NOTE(cstml): FIXME."
159+ I. InferUnifyTermErr (I. Constraint (k1, k2)) -> do
160+ err <- PC. IncorrectApplicationError td <$> kind2ProtoKind k1 <*> kind2ProtoKind k2 <*> pure modName
161+ throwError $ PC. CompKindCheckError err
150162 I. InferRecursiveSubstitutionErr _ ->
151- throwError
152- . PC. CompKindCheckError
153- $ PC. RecursiveKindError td modName
163+ throwError . PC. CompKindCheckError $ PC. RecursiveKindError td modName
154164 I. InferImpossibleErr t ->
155- throwError $
156- PC. InternalError t
157-
158- foreignRef2LocalRef :: Getter PC. ForeignRef PC. LocalRef
159- foreignRef2LocalRef =
160- to
161- ( \ fr ->
162- PC. LocalRef
163- { tyName = fr ^. # tyName
164- , sourceInfo = fr ^. # sourceInfo
165- }
166- )
165+ throwError $ PC. InternalError t
167166
168167--------------------------------------------------------------------------------
169168-- Resolvers
@@ -183,24 +182,28 @@ resolveKindConsistency tyDef _ctx inferredKind = do
183182 guard t i d
184183 | i == d = pure ()
185184 | otherwise = do
186- mn <- ask
187- throwError
188- . PC. CompKindCheckError
189- $ PC. InconsistentTypeError t (kind2ProtoKind i) (kind2ProtoKind d) mn
185+ err <- PC. InconsistentTypeError t <$> kind2ProtoKind i <*> kind2ProtoKind d <*> ask
186+ throwError $ PC. CompKindCheckError err
190187
191188--------------------------------------------------------------------------------
192189-- Context Creation
193190
194191-- | Resolver function for the context creation. There is a guarantee from ProtoCompat that the input is sanitised.
195192resolveCreateContext :: forall effs . PC. CompilerInput -> Eff effs Context
196- resolveCreateContext ci =
197- mconcat <$> traverse module2Context (toList $ ci ^. # modules)
193+ resolveCreateContext = fmap mconcat . traverse module2Context . toList . view # modules
198194
199195module2Context :: forall effs . PC. Module -> Eff effs Context
200196module2Context m = do
201197 let typeDefinitions = toList $ m ^. # typeDefs
202- ctxs <- runReader (m ^. # moduleName) $ traverse tyDef2Context typeDefinitions
203- pure $ mconcat ctxs
198+ let classDefinitions = toList $ m ^. # classDefs
199+ -- Context built from type definitions.
200+ typeDefCtx <- fmap mconcat . runReader (m ^. # moduleName) $ traverse tyDef2Context typeDefinitions
201+ -- Context built from class definitions.
202+ classDefCtx <- fmap mconcat . runReader (m ^. # moduleName) $ traverse classDef2Context classDefinitions
203+ return $ typeDefCtx <> classDefCtx
204+
205+ --------------------------------------------------------------------------------
206+ -- Type Definition Based Context Building.
204207
205208-- | Creates a Context entry from one type definition.
206209tyDef2Context ::
@@ -219,19 +222,45 @@ tyDef2NameAndKind ::
219222 Eff effs (InfoLess Variable , Kind )
220223tyDef2NameAndKind tyDef = do
221224 curModName <- ask
222-
223- -- InfoLess name - the SourceInfo doesn't matter therefore it is defaulted.
225+ -- InfoLess Qualified name - the SourceInfo doesn't matter therefore it is defaulted.
224226 let name =
225227 QualifiedTyRef
226- . view (PC. localRef2ForeignRef curModName)
228+ . withIso ltrISOqtr const
229+ . (,curModName)
227230 $ PC. LocalRef (tyDef ^. # tyName) def
228231
229232 k = tyAbsLHS2Kind (tyDef ^. # tyAbs)
230233
231234 pure (mkInfoLess name, k)
232235
233236tyAbsLHS2Kind :: PC. TyAbs -> Kind
234- tyAbsLHS2Kind tyAbs = foldWithArrowToType $ pKind2Kind . (\ x -> x ^. # argKind) <$> toList (tyAbs ^. # tyArgs)
237+ tyAbsLHS2Kind tyAbs = foldWithArrowToType $ tyArg2Kind <$> toList (tyAbs ^. # tyArgs)
238+
239+ tyArg2Kind :: PC. TyArg -> Kind
240+ tyArg2Kind = protoKind2Kind . view # argKind
241+
242+ --------------------------------------------------------------------------------
243+ -- Class Definition Based Context Building.
244+
245+ --- | Convert from internal Kind to Proto Kind.
246+ kind2ProtoKind :: forall effs . Member Err effs => Kind -> Eff effs PC. Kind
247+ kind2ProtoKind = \ case
248+ k1 :->: k2 -> fmap PC. Kind $ PC. KindArrow <$> kind2ProtoKind k1 <*> kind2ProtoKind k2
249+ KType -> pure . PC. Kind . PC. KindRef $ PC. KType
250+ KVar _ -> pure . PC. Kind . PC. KindRef $ PC. KUnspecified -- this shouldn't happen.
251+ KConstraint -> pure . PC. Kind . PC. KindRef $ PC. KConstraint
252+
253+ --------------------------------------------------------------------------------
254+ -- Class Definition Based Context Building.
255+
256+ classDef2Context :: forall effs . PC. ClassDef -> Eff effs Context
257+ classDef2Context cDef = do
258+ let className = mkInfoLess . view # className $ cDef
259+ let classArg = tyArg2Kind . view # classArgs $ cDef
260+ pure $ mempty & constraintContext .~ M. singleton className classArg
261+
262+ --------------------------------------------------------------------------------
263+ -- utilities
235264
236265{- | Folds kinds and appends them to a Kind result type. In essence creates a
237266 curried function with a Type final kind.
@@ -250,13 +279,3 @@ foldWithArrowToType = foldWithArrowToKind KType
250279
251280foldWithArrowToKind :: Kind -> [Kind ] -> Kind
252281foldWithArrowToKind = foldr (:->:)
253-
254- --------------------------------------------------------------------------------
255- -- To Kind Conversion functions
256-
257- pKind2Kind :: PC. Kind -> Kind
258- pKind2Kind k =
259- case k ^. # kind of
260- PC. KindRef PC. KType -> KType
261- PC. KindArrow l r -> pKind2Kind l :->: pKind2Kind r
262- PC. KindRef PC. KUnspecified -> KType -- (for now) defaulting unspecified kinds to Type
0 commit comments