Skip to content

Commit a6c113d

Browse files
committed
Merge remote-tracking branch 'origin/main' into compiler/arbitrary-instances
2 parents a38170a + b369820 commit a6c113d

File tree

13 files changed

+497
-336
lines changed

13 files changed

+497
-336
lines changed

lambda-buffers-compiler/app/LambdaBuffers/Compiler/Cli/Compile.hs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,12 @@ import Data.ProtoLens.TextFormat qualified as PbText
88
import Data.Text.Lazy qualified as Text
99
import Data.Text.Lazy.IO qualified as Text
1010
import LambdaBuffers.Compiler.KindCheck (check)
11-
import LambdaBuffers.Compiler.KindCheck.Context (getAllContext)
1211
import LambdaBuffers.Compiler.ProtoCompat (
13-
CompilerFailure (KCErr),
14-
CompilerOutput (CompilerOutput),
15-
CompilerResult (RCompilerFailure, RCompilerOutput),
1612
FromProtoErr (NamingError, ProtoError),
1713
IsMessage (fromProto, toProto),
18-
kindConvert,
1914
)
2015
import LambdaBuffers.Compiler.ProtoCompat.Types qualified as ProtoCompat
21-
import Proto.Compiler as ProtoLib (CompilerInput, CompilerResult)
16+
import Proto.Compiler as ProtoLib (CompilerInput, CompilerOutput)
2217
import System.FilePath.Lens (extension)
2318

2419
data CompileOpts = CompileOpts
@@ -41,7 +36,7 @@ compile opts = do
4136
ProtoError pe -> print $ "Encountered a proto error " <> show pe
4237
Right compIn' -> do
4338
print @String "Successfully processed the CompilerInput"
44-
let result = either (RCompilerFailure . KCErr) (RCompilerOutput . CompilerOutput . fmap kindConvert . getAllContext) $ check compIn'
39+
let result = check compIn'
4540
writeCompilerOutput (opts ^. output) (toProto result)
4641
return ()
4742

@@ -57,7 +52,7 @@ readCompilerInput fp = do
5752
return $ PbText.readMessageOrDie content
5853
_ -> error $ "Unknown CompilerInput format " <> ext
5954

60-
writeCompilerOutput :: FilePath -> ProtoLib.CompilerResult -> IO ()
55+
writeCompilerOutput :: FilePath -> ProtoLib.CompilerOutput -> IO ()
6156
writeCompilerOutput fp cr = do
6257
let ext = fp ^. extension
6358
case ext of

lambda-buffers-compiler/lambda-buffers-compiler.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ test-suite tests
158158
Test.KindCheck
159159
Test.Samples
160160
Test.Samples.Proto.CompilerInput
161+
Test.Samples.Proto.Helpers
161162
Test.Samples.Proto.Module
162163
Test.Samples.Proto.SourceInfo
163164
Test.Samples.Proto.TyDef

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

Lines changed: 154 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
1-
{-# LANGUAGE DuplicateRecordFields #-}
2-
{-# LANGUAGE OverloadedLabels #-}
3-
{-# LANGUAGE RecordWildCards #-}
4-
{-# LANGUAGE TemplateHaskell #-}
5-
61
module LambdaBuffers.Compiler.KindCheck (
2+
-- * Kindchecking functions.
73
check,
84
check_,
9-
foldWithSum,
10-
11-
-- * Testing Utils
125

13-
-- * Utilities -- exported for testing
6+
-- * Testing Utils.
7+
foldWithSum,
148
foldWithArrow,
159
foldWithProduct,
1610
) where
@@ -21,21 +15,65 @@ import Control.Monad.Freer (Eff, Members, reinterpret, run)
2115
import Control.Monad.Freer.Error (Error, runError, throwError)
2216
import Control.Monad.Freer.Reader (Reader, ask, runReader)
2317
import Control.Monad.Freer.TH (makeEffect)
18+
import Data.Foldable (traverse_)
19+
import Data.List.NonEmpty (NonEmpty ((:|)), uncons, (<|))
20+
import Data.Map qualified as M
2421
import Data.Text (Text, intercalate)
25-
import LambdaBuffers.Compiler.KindCheck.Context (Context, getAllContext)
22+
import LambdaBuffers.Compiler.KindCheck.Context (Context)
2623
import LambdaBuffers.Compiler.KindCheck.Inference (
24+
InferErr (
25+
InferImpossibleErr,
26+
InferRecursiveSubstitutionErr,
27+
InferUnboundTermErr,
28+
InferUnifyTermErr
29+
),
2730
Kind (Type, (:->:)),
2831
Type (Abs, Var),
2932
context,
3033
infer,
3134
)
35+
import LambdaBuffers.Compiler.KindCheck.Inference qualified as I
3236
import LambdaBuffers.Compiler.KindCheck.Type (Type (App))
33-
import LambdaBuffers.Compiler.KindCheck.Variable (Var)
34-
import LambdaBuffers.Compiler.ProtoCompat qualified as P
35-
36-
import Data.Foldable (traverse_)
37-
import Data.List.NonEmpty (NonEmpty ((:|)), uncons, (<|))
38-
import Data.Map qualified as M
37+
import LambdaBuffers.Compiler.KindCheck.Variable (Variable (ForeignRef, LocalRef))
38+
import LambdaBuffers.Compiler.ProtoCompat (kind2ProtoKind)
39+
import LambdaBuffers.Compiler.ProtoCompat.Types qualified as P (
40+
ClassDef,
41+
CompilerError (..),
42+
CompilerInput,
43+
Constructor,
44+
Field,
45+
ForeignRef,
46+
InstanceClause,
47+
Kind,
48+
KindCheckError (
49+
InconsistentTypeError,
50+
IncorrectApplicationError,
51+
RecursiveKindError,
52+
UnboundTermError
53+
),
54+
KindRefType (KType),
55+
KindType (KindArrow, KindRef),
56+
LocalRef,
57+
Module,
58+
ModuleName,
59+
Product (..),
60+
Record,
61+
SourceInfo (SourceInfo),
62+
SourcePosition (SourcePosition),
63+
Sum,
64+
Tuple,
65+
Ty (..),
66+
TyAbs,
67+
TyApp,
68+
TyArg,
69+
TyBody (..),
70+
TyDef (TyDef),
71+
TyName,
72+
TyRef (..),
73+
TyVar,
74+
VarName (VarName),
75+
)
76+
import LambdaBuffers.Compiler.ProtoCompat.Types qualified as PT
3977

4078
--------------------------------------------------------------------------------
4179
-- Types
@@ -44,11 +82,11 @@ import Data.Map qualified as M
4482
-- - double declaration of a type
4583

4684
-- | Kind Check failure types.
47-
type KindCheckFailure = P.KindCheckErr
85+
type CompilerErr = P.CompilerError
4886

49-
type Err = Error KindCheckFailure
87+
type Err = Error CompilerErr
5088

51-
type ModName = Text
89+
type ModName = [Text]
5290

5391
-- | Main interface to the Kind Checker.
5492
data Check a where
@@ -75,20 +113,24 @@ data KindCheck a where
75113
KindFromTyDef :: ModName -> P.TyDef -> KindCheck Type
76114
InferTypeKind :: ModName -> P.TyDef -> Context -> Type -> KindCheck Kind
77115
CheckKindConsistency :: ModName -> P.TyDef -> Context -> Kind -> KindCheck Kind
116+
117+
-- FIXME(cstml) add check for Context Consistency
118+
-- FIXME(cstml) add check for Double Declaration
119+
-- TyDefToTypes :: ModName -> P.TyDef -> KindCheck [Type]
78120
makeEffect ''KindCheck
79121

80122
--------------------------------------------------------------------------------
81123

82-
runCheck :: Eff (Check ': '[]) a -> Either KindCheckFailure a
124+
runCheck :: Eff (Check ': '[]) a -> Either CompilerErr a
83125
runCheck = run . runError . runKindCheck . localStrategy . moduleStrategy . globalStrategy
84126

85127
-- | Run the check - return the validated context or the failure.
86-
check :: P.CompilerInput -> Either KindCheckFailure Context
87-
check = runCheck . kCheck
128+
check :: P.CompilerInput -> PT.CompilerOutput
129+
check = fmap (const PT.CompilerResult) . runCheck . kCheck
88130

89131
-- | Run the check - drop the result if it succeeds.
90-
check_ :: P.CompilerInput -> Either KindCheckFailure ()
91-
check_ = void . check
132+
check_ :: P.CompilerInput -> Either CompilerErr ()
133+
check_ = void . runCheck . kCheck
92134

93135
--------------------------------------------------------------------------------
94136

@@ -120,8 +162,28 @@ localStrategy = reinterpret $ \case
120162
runKindCheck :: Eff '[KindCheck] a -> Eff '[Err] a
121163
runKindCheck = reinterpret $ \case
122164
KindFromTyDef moduleName tydef -> runReader moduleName (tyDef2Type tydef)
123-
InferTypeKind _modName tyDef ctx ty -> either (throwError . P.InferenceFailure tyDef) pure $ infer ctx ty
165+
-- TyDefToTypes moduleName tydef -> runReader moduleName (tyDef2Types tydef)
166+
InferTypeKind _modName tyDef ctx ty -> either (handleErr tyDef) pure $ infer ctx ty
124167
CheckKindConsistency mname def ctx k -> runReader mname $ resolveKindConsistency def ctx k
168+
where
169+
handleErr :: forall a. P.TyDef -> InferErr -> Eff '[Err] a
170+
handleErr td = \case
171+
InferUnboundTermErr uA ->
172+
throwError . P.CompKindCheckError $ P.UnboundTermError (tyDef2TyName td) (var2VarName uA)
173+
InferUnifyTermErr (I.Constraint (k1, k2)) ->
174+
throwError . P.CompKindCheckError $ P.IncorrectApplicationError (tyDef2TyName td) (kind2ProtoKind k1) (kind2ProtoKind k2)
175+
InferRecursiveSubstitutionErr _ ->
176+
throwError . P.CompKindCheckError $ P.RecursiveKindError $ tyDef2TyName td
177+
InferImpossibleErr t ->
178+
throwError . P.InternalError $ t
179+
180+
var2VarName = \case
181+
LocalRef n -> P.VarName n emptySourceInfo
182+
ForeignRef m s -> P.VarName (intercalate "." m <> s) emptySourceInfo
183+
184+
emptySourceInfo = P.SourceInfo mempty emptySourcePosition emptySourcePosition
185+
186+
emptySourcePosition = P.SourcePosition 0 0
125187

126188
-- Resolvers
127189

@@ -132,27 +194,36 @@ resolveKindConsistency ::
132194
Context ->
133195
Kind ->
134196
Eff effs Kind
135-
resolveKindConsistency tydef ctx inferredKind = do
197+
resolveKindConsistency tydef _ctx inferredKind = do
136198
mName <- ask @ModName
137-
(n, k) <- tyDef2NameAndKind mName tydef
138-
guard $ k == inferredKind
139-
guard $ getAllContext ctx M.!? n == Just inferredKind
199+
let tyName = tyDef2TyName tydef
200+
(_, k) <- tyDef2NameAndKind mName tydef
201+
guard tyName k inferredKind
140202
pure inferredKind
141203
where
142-
guard b = if b then pure () else throwError $ P.InconsistentTypeErr tydef
204+
guard :: P.TyName -> Kind -> Kind -> Eff effs ()
205+
guard n i d
206+
| i == d = pure ()
207+
| otherwise =
208+
throwError . P.CompKindCheckError $
209+
P.InconsistentTypeError n (kind2ProtoKind i) (kind2ProtoKind d)
143210

144211
resolveCreateContext :: forall effs. P.CompilerInput -> Eff effs Context
145212
resolveCreateContext ci = mconcat <$> traverse module2Context (ci ^. #modules)
146213

214+
tyDef2TyName :: P.TyDef -> P.TyName
215+
tyDef2TyName (P.TyDef n _ _) = n
216+
147217
module2Context :: forall effs. P.Module -> Eff effs Context
148-
module2Context m = mconcat <$> traverse (tyDef2Context (flattenModuleName (m ^. #moduleName))) (m ^. #typeDefs)
218+
module2Context m = mconcat <$> traverse (tyDef2Context (moduleName2ModName (m ^. #moduleName))) (m ^. #typeDefs)
149219

150-
flattenModuleName :: P.ModuleName -> Text
151-
flattenModuleName mName = intercalate "." $ (\p -> p ^. #name) <$> mName ^. #parts
220+
moduleName2ModName :: P.ModuleName -> ModName
221+
moduleName2ModName mName = (\p -> p ^. #name) <$> mName ^. #parts
152222

153-
tyDef2NameAndKind :: forall effs. ModName -> P.TyDef -> Eff effs (ModName, Kind)
223+
tyDef2NameAndKind :: forall effs. ModName -> P.TyDef -> Eff effs (Variable, Kind)
154224
tyDef2NameAndKind curModName tyDef = do
155-
let name = curModName <> "." <> (tyDef ^. #tyName . #name) -- name is qualified
225+
-- all names are qualified
226+
let name = ForeignRef curModName (tyDef ^. #tyName . #name)
156227
let k = tyAbsLHS2Kind (tyDef ^. #tyAbs)
157228
pure (name, k)
158229

@@ -205,8 +276,8 @@ tyArgs2Type = \case
205276
f <- tyArgs2Type xs
206277
pure $ \c -> Abs (tyArg2Var x) (f c)
207278

208-
tyArg2Var :: P.TyArg -> Var
209-
tyArg2Var = view (#argName . #name)
279+
tyArg2Var :: P.TyArg -> Variable
280+
tyArg2Var = LocalRef . view (#argName . #name)
210281

211282
tyAbsRHS2Type ::
212283
forall eff.
@@ -221,7 +292,7 @@ tyBody2Type ::
221292
P.TyBody ->
222293
Eff eff Type
223294
tyBody2Type = \case
224-
P.OpaqueI _ -> pure $ Var "Opaque"
295+
P.OpaqueI _ -> pure $ Var $ LocalRef "Opaque"
225296
P.SumI s -> sum2Type s
226297

227298
sum2Type ::
@@ -262,7 +333,7 @@ tuple2Type ::
262333
tuple2Type tu = do
263334
tup <- traverse ty2Type $ tu ^. #fields
264335
case tup of
265-
[] -> pure $ Var "𝟙"
336+
[] -> pure $ Var $ LocalRef "𝟙"
266337
x : xs -> pure . foldWithProduct $ x :| xs
267338

268339
field2Type ::
@@ -286,7 +357,7 @@ tyVar2Type ::
286357
forall eff.
287358
P.TyVar ->
288359
Eff eff Type
289-
tyVar2Type tv = pure . Var $ (tv ^. #varName . #name)
360+
tyVar2Type tv = pure . Var . LocalRef $ (tv ^. #varName . #name)
290361

291362
tyApp2Type ::
292363
forall eff.
@@ -314,27 +385,64 @@ localTyRef2Type ::
314385
Eff eff Type
315386
localTyRef2Type ltr = do
316387
moduleName <- ask
317-
pure $ Var $ moduleName <> "." <> (ltr ^. #tyName . #name)
388+
pure . Var $ ForeignRef moduleName (ltr ^. #tyName . #name)
318389

319390
foreignTyRef2Type ::
320391
forall eff.
321392
P.ForeignRef ->
322393
Eff eff Type
323394
foreignTyRef2Type ftr = do
324-
let moduleName = flattenModuleName (ftr ^. #moduleName)
325-
pure $ Var $ moduleName <> "." <> (ftr ^. #tyName . #name)
395+
let moduleName = moduleName2ModName (ftr ^. #moduleName)
396+
pure $ Var $ ForeignRef moduleName (ftr ^. #tyName . #name)
326397

398+
-- =============================================================================
399+
-- X To Canonical type conversion functions.
400+
{-
401+
-- | TyDef to Kind Canonical representation - sums not folded - therefore we get constructor granularity. Might use in a different implementation for more granular errors.
402+
tyDef2Types ::
403+
forall eff.
404+
Members '[Reader ModName, Err] eff =>
405+
P.TyDef ->
406+
Eff eff [Type]
407+
tyDef2Types tyde = do
408+
f <- tyAbsLHS2Type (tyde ^. #tyAbs) -- abstraction
409+
cs <- tyAbsRHS2Types (tyde ^. #tyAbs) --
410+
pure $ f <$> cs
411+
412+
tyAbsRHS2Types ::
413+
forall eff.
414+
Members '[Reader ModName, Err] eff =>
415+
P.TyAbs ->
416+
Eff eff [Type]
417+
tyAbsRHS2Types tyab = tyBody2Types (tyab ^. #tyBody)
418+
419+
tyBody2Types ::
420+
forall eff.
421+
Members '[Reader ModName, Err] eff =>
422+
P.TyBody ->
423+
Eff eff [Type]
424+
tyBody2Types = \case
425+
P.OpaqueI _ -> pure [Var $ LocalRef "Opaque"]
426+
P.SumI s -> sum2Types s
427+
428+
sum2Types ::
429+
forall eff.
430+
Members '[Reader ModName, Err] eff =>
431+
P.Sum ->
432+
Eff eff [Type]
433+
sum2Types su = NonEmpty.toList <$> traverse constructor2Type (su ^. #constructors)
434+
-}
327435
--------------------------------------------------------------------------------
328436
-- Utilities
329437

330438
foldWithApp :: NonEmpty Type -> Type
331439
foldWithApp = foldWithBinaryOp App
332440

333441
foldWithProduct :: NonEmpty Type -> Type
334-
foldWithProduct = foldWithBinaryOp $ App . App (Var "Π")
442+
foldWithProduct = foldWithBinaryOp $ App . App (Var $ LocalRef "Π")
335443

336444
foldWithSum :: NonEmpty Type -> Type
337-
foldWithSum = foldWithBinaryOp $ App . App (Var "Σ")
445+
foldWithSum = foldWithBinaryOp $ App . App (Var $ LocalRef "Σ")
338446

339447
-- | Generic way of folding.
340448
foldWithBinaryOp :: (Type -> Type -> Type) -> NonEmpty Type -> Type
@@ -343,4 +451,4 @@ foldWithBinaryOp op ne = case uncons ne of
343451
(x, Just xs) -> op x $ foldWithBinaryOp op xs
344452

345453
module2ModuleName :: P.Module -> ModName
346-
module2ModuleName = flattenModuleName . (^. #moduleName)
454+
module2ModuleName = moduleName2ModName . (^. #moduleName)

0 commit comments

Comments
 (0)