Skip to content

Commit 521093f

Browse files
authored
Merge pull request #44 from mlabs-haskell/compiler/typeclass-utils
Compiler/typeclass utils
2 parents 074ec6d + 9ac4dd9 commit 521093f

File tree

14 files changed

+1913
-497
lines changed

14 files changed

+1913
-497
lines changed

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,14 @@ library
120120
LambdaBuffers.Compiler.ProtoCompat
121121
LambdaBuffers.Compiler.ProtoCompat.FromProto
122122
LambdaBuffers.Compiler.ProtoCompat.Types
123-
LambdaBuffers.Compiler.TypeClass.Pat
124-
LambdaBuffers.Compiler.TypeClass.Pretty
125-
LambdaBuffers.Compiler.TypeClass.Rules
126-
LambdaBuffers.Compiler.TypeClass.Solve
127123
LambdaBuffers.Compiler.TypeClassCheck
124+
LambdaBuffers.Compiler.TypeClassCheck.Compat
125+
LambdaBuffers.Compiler.TypeClassCheck.Pat
126+
LambdaBuffers.Compiler.TypeClassCheck.Pretty
127+
LambdaBuffers.Compiler.TypeClassCheck.Rules
128+
LambdaBuffers.Compiler.TypeClassCheck.Solve
129+
LambdaBuffers.Compiler.TypeClassCheck.Utils
130+
LambdaBuffers.Compiler.TypeClassCheck.Validate
128131

129132
hs-source-dirs: src
130133

@@ -150,7 +153,8 @@ test-suite tests
150153
hs-source-dirs: test
151154
main-is: Test.hs
152155
build-depends:
153-
, containers >=0.6
156+
, containers
157+
, generic-lens
154158
, lambda-buffers-compiler
155159
, lambda-buffers-compiler-pb >=0.1
156160
, proto-lens >=0.7
@@ -161,6 +165,7 @@ test-suite tests
161165
, text >=1.2
162166

163167
other-modules:
168+
Test.DeriveCheck
164169
Test.KindCheck
165170
Test.KindCheck.Errors
166171
Test.LambdaBuffers.Compiler

lambda-buffers-compiler/src/LambdaBuffers/Compiler/TypeClass/Pretty.hs

Lines changed: 0 additions & 137 deletions
This file was deleted.

lambda-buffers-compiler/src/LambdaBuffers/Compiler/TypeClass/Solve.hs

Lines changed: 0 additions & 131 deletions
This file was deleted.

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

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,33 @@
11
{-# LANGUAGE OverloadedLabels #-}
22
{-# LANGUAGE OverloadedStrings #-}
33

4-
module LambdaBuffers.Compiler.TypeClassCheck (detectSuperclassCycles, detectSuperclassCycles') where
4+
module LambdaBuffers.Compiler.TypeClassCheck (detectSuperclassCycles, detectSuperclassCycles', runDeriveCheck, validateTypeClasses) where
55

66
import Control.Lens.Combinators (view)
77
import Control.Lens.Operators ((^.))
8+
import Control.Monad (void)
89
import Data.Generics.Labels ()
910
import Data.List (foldl')
11+
import Data.Map (traverseWithKey)
1012
import Data.Map qualified as M
13+
import Data.Set qualified as S
1114
import Data.Text (Text)
15+
import LambdaBuffers.Compiler.ProtoCompat qualified as P
1216
import LambdaBuffers.Compiler.ProtoCompat.Types (
1317
ClassDef (),
1418
ForeignClassRef (ForeignClassRef),
1519
LocalClassRef (LocalClassRef),
1620
TyClassRef (ForeignCI, LocalCI),
1721
)
22+
import LambdaBuffers.Compiler.TypeClassCheck.Pretty (spaced, (<//>))
23+
import LambdaBuffers.Compiler.TypeClassCheck.Utils (
24+
Instance,
25+
ModuleBuilder (mbInstances),
26+
TypeClassError (FailedToSolveConstraints),
27+
checkInstance,
28+
mkBuilders,
29+
)
30+
import LambdaBuffers.Compiler.TypeClassCheck.Validate (checkDerive)
1831
import Prettyprinter (
1932
Doc,
2033
Pretty (pretty),
@@ -23,6 +36,7 @@ import Prettyprinter (
2336
line,
2437
punctuate,
2538
vcat,
39+
(<+>),
2640
)
2741

2842
data ClassInfo = ClassInfo {ciName :: Text, ciSupers :: [Text]}
@@ -65,3 +79,39 @@ detectSuperclassCycles cds = case detectSuperclassCycles' cds of
6579
where
6680
format :: [Text] -> Doc a
6781
format = hcat . punctuate " => " . map pretty
82+
83+
runDeriveCheck :: P.ModuleName -> ModuleBuilder -> Either TypeClassError ()
84+
runDeriveCheck mn mb = mconcat <$> traverse go (S.toList $ mbInstances mb)
85+
where
86+
go :: Instance -> Either TypeClassError ()
87+
go i =
88+
checkInstance i
89+
>> checkDerive mn mb i
90+
>>= \case
91+
[] -> pure ()
92+
xs -> Left $ FailedToSolveConstraints mn xs i
93+
94+
-- ModuleBuilder is suitable codegen input,
95+
-- and is (relatively) computationally expensive to
96+
-- construct, so we return it here if successful.
97+
validateTypeClasses' :: P.CompilerInput -> Either TypeClassError (M.Map P.ModuleName ModuleBuilder)
98+
validateTypeClasses' ci = do
99+
-- detectSuperclassCycles ci
100+
moduleBuilders <- mkBuilders ci
101+
void $ traverseWithKey runDeriveCheck moduleBuilders
102+
pure moduleBuilders
103+
104+
-- maybe use Control.Exception? Tho if we're not gonna catch it i guess this is fine
105+
validateTypeClasses :: P.CompilerInput -> IO (M.Map P.ModuleName ModuleBuilder)
106+
validateTypeClasses ci = case validateTypeClasses' ci of
107+
Left err -> print (spaced $ pretty err) >> error "\nCompilation aborted due to TypeClass Error"
108+
Right mbs -> print (prettyBuilders mbs) >> pure mbs
109+
110+
prettyBuilders :: forall a. M.Map P.ModuleName ModuleBuilder -> Doc a
111+
prettyBuilders = spaced . vcat . punctuate line . map (uncurry go) . M.toList
112+
where
113+
go :: P.ModuleName -> ModuleBuilder -> Doc a
114+
go mn mb =
115+
"MODULE"
116+
<+> pretty mn
117+
<//> indent 2 (pretty mb)

0 commit comments

Comments
 (0)