Skip to content

Commit f325ac2

Browse files
authored
Merge pull request #11 from mlabs-haskell/bladyjoker/frontend
Frontend
2 parents 03dd0eb + c2145c3 commit f325ac2

File tree

51 files changed

+1400
-73
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1400
-73
lines changed

flake.nix

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,14 @@
7575
inherit (protosBuild) compilerHsPb;
7676
inherit (pre-commit-check) shellHook;
7777
};
78-
compilerFlake = compilerBuild.compilerHsNixProj.flake { };
78+
compilerFlake = compilerBuild.hsNixProj.flake { };
79+
80+
frontendBuild = import ./lambda-buffers-frontend/build.nix {
81+
inherit pkgs compiler-nix-name index-state haskell-nix mlabs-tooling commonTools;
82+
inherit (protosBuild) compilerHsPb;
83+
inherit (pre-commit-check) shellHook;
84+
};
85+
frontendFlake = frontendBuild.hsNixProj.flake { };
7986

8087
# Utilities
8188
# INFO: Will need this; renameAttrs = rnFn: pkgs.lib.attrsets.mapAttrs' (n: value: { name = rnFn n; inherit value; });
@@ -85,14 +92,15 @@
8592
inherit pkgs;
8693

8794
# Standard flake attributes
88-
packages = { inherit (protosBuild) compilerHsPb; } // compilerFlake.packages;
95+
packages = { inherit (protosBuild) compilerHsPb; } // compilerFlake.packages // frontendFlake.packages;
8996

9097
devShells = rec {
9198
dev-pre-commit = preCommitDevShell;
9299
dev-experimental = experimentalDevShell;
93100
dev-docs = docsDevShell;
94101
dev-protos = protosBuild.devShell;
95102
dev-compiler = compilerFlake.devShell;
103+
dev-frontend = frontendFlake.devShell;
96104
default = preCommitDevShell;
97105
};
98106

lambda-buffers-compiler/build.nix

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ let
2727
allComponent.doHaddock = true;
2828

2929
# Enable strict compilation
30-
allComponent.configureFlags = [ "-f-dev" ];
30+
lambda-buffers-compiler.configureFlags = [ "-f-dev" ];
3131
};
3232
})
3333
];
@@ -40,10 +40,6 @@ let
4040

4141
nativeBuildInputs = builtins.attrValues commonTools;
4242

43-
additional = ps: [
44-
ps.lambda-buffers-compiler-pb
45-
];
46-
4743
tools = {
4844
cabal = { };
4945
haskell-language-server = { };
@@ -59,7 +55,7 @@ let
5955
};
6056
in
6157
{
62-
compilerHsNixProj = haskell-nix.cabalProject' [
58+
hsNixProj = haskell-nix.cabalProject' [
6359
mlabs-tooling.lib.mkHackageMod
6460
project
6561
];

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

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -79,34 +79,24 @@ common common-language
7979

8080
default-language: Haskell2010
8181

82-
common common-dependencies
83-
build-depends:
84-
, base >=4.16
85-
, containers >=0.6
86-
, lens >=5.2
87-
, proto-lens >=0.7
88-
, text >=1.2
89-
, transformers >=0.5
90-
9182
library
9283
import: common-language
93-
import: common-dependencies
9484
build-depends:
95-
, containers >=0.6
85+
, base >=4.16
9686
, freer-simple >=1.2
9787
, lambda-buffers-compiler-pb >=0.1.0.0
98-
, mtl >=2.2
88+
, lens >=5.2
9989
, prettyprinter >=1.7
90+
, text >=1.2
10091

10192
exposed-modules:
10293
LambdaBuffers.Compiler.KindCheck
10394
LambdaBuffers.Compiler.KindCheck.Inference
10495

10596
hs-source-dirs: src
10697

107-
executable lambda-buffers-compiler
98+
executable lambda-buffers-compiler-cli
10899
import: common-language
109-
import: common-dependencies
110100
main-is: Main.hs
111101
build-depends:
112102
, base >=4.16
@@ -118,18 +108,13 @@ executable lambda-buffers-compiler
118108

119109
test-suite tests
120110
import: common-language
121-
import: common-dependencies
122111
type: exitcode-stdio-1.0
123112
hs-source-dirs: test
124113
main-is: Test.hs
125114
build-depends:
126-
, hedgehog >=1
115+
, base >=4.16
127116
, lambda-buffers-compiler
128-
, QuickCheck >=2
129117
, tasty >=1.4
130-
, tasty-expected-failure >=0.12
131-
, tasty-hedgehog >=1.4
132118
, tasty-hunit >=0.10
133-
, tasty-quickcheck >=0.10
134119

135120
other-modules: Test.KindCheck

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import Control.Lens (folded, makeLenses, to, (&), (.~), (^.), (^..))
1818
import Control.Monad.Freer (Eff, interpret, run)
1919
import Control.Monad.Freer.Error (Error, runError, throwError)
2020
import Control.Monad.Freer.TH (makeEffect)
21-
import Data.Text (Text, unpack)
21+
import Data.Text (Text, intercalate, unpack)
2222
import LambdaBuffers.Compiler.KindCheck.Inference (
2323
Context,
2424
InferErr,
@@ -32,7 +32,7 @@ import Control.Monad (void)
3232
import Data.Traversable (for)
3333
import Proto.Compiler (
3434
Product'NTuple,
35-
Product'Product (Product'Empty', Product'Ntuple, Product'Record'),
35+
Product'Product (Product'Ntuple, Product'Record'),
3636
Product'Record,
3737
Sum,
3838
Ty,
@@ -54,6 +54,7 @@ import Proto.Compiler_Fields as PF (
5454
maybe'tyRef,
5555
moduleName,
5656
name,
57+
parts,
5758
product,
5859
tyAbs,
5960
tyArgs,
@@ -171,7 +172,6 @@ sumToType sumT = do
171172
for
172173
products
173174
$ \case
174-
Just (Product'Empty' _) -> pure $ Var "()"
175175
Just (Product'Ntuple nt) -> nTupleToType nt
176176
Just (Product'Record' re) -> recordToType re
177177
Nothing -> throwError $ InvalidProto "Every constructor should have a product defining it"
@@ -236,5 +236,5 @@ tyRefToType :: TyRef -> Eff KindCheckFailEff Type
236236
tyRefToType tR = do
237237
case tR ^. maybe'tyRef of
238238
Just (TyRef'LocalTyRef t) -> pure $ Var $ t ^. tyName . name . to unpack
239-
Just (TyRef'ForeignTyRef t) -> pure $ Var $ (t ^. moduleName . name . to unpack) <> "." <> (t ^. tyName . name . to unpack)
239+
Just (TyRef'ForeignTyRef t) -> pure $ Var $ (t ^. moduleName . parts . to (\ps -> unpack $ intercalate "." [p ^. name | p <- ps])) <> "." <> (t ^. tyName . name . to unpack)
240240
Nothing -> throwError $ InvalidProto "TyRef Cannot be empty"
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
{-# LANGUAGE ImportQualifiedPost #-}
2-
31
module Main (main) where
42

53
import Test.KindCheck qualified as KC
6-
import Test.Tasty
4+
import Test.Tasty (defaultMain, testGroup)
75

86
main :: IO ()
9-
main = defaultMain $ testGroup "All Tests" [KC.test]
7+
main = defaultMain $ testGroup "Compiler tests" [KC.test]

lambda-buffers-compiler/test/Test/KindCheck.hs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,48 @@
1-
{-# OPTIONS_GHC -Wno-missing-signatures #-}
2-
31
module Test.KindCheck (test) where
42

5-
import LambdaBuffers.Compiler.KindCheck
6-
import LambdaBuffers.Compiler.KindCheck.Inference
7-
import Test.Tasty
8-
import Test.Tasty.HUnit
3+
import LambdaBuffers.Compiler.KindCheck (
4+
KindCheckFailure (InferenceFailed),
5+
TypeDefinition (TypeDefinition, _td'name, _td'sop, _td'variables),
6+
kindCheckType,
7+
runKindCheckEff,
8+
)
9+
import LambdaBuffers.Compiler.KindCheck.Inference (
10+
InferErr (ImpossibleUnificationErr),
11+
Kind (Type, (:->:)),
12+
Type (Abs, App, Var),
13+
)
14+
import Test.Tasty (TestTree, testGroup)
15+
import Test.Tasty.HUnit (testCase, (@?=))
916

1017
test :: TestTree
11-
test = testGroup "KindChecker Tests" [t1, t2, t3, t4, t5]
18+
test = testGroup "KindChecker tests" [t1, t2, t3, t4, t5]
1219

1320
runKC :: [TypeDefinition] -> Either KindCheckFailure [Kind]
1421
runKC = runKindCheckEff . kindCheckType
1522

23+
t1 :: TestTree
1624
t1 =
17-
testCase "No Definition, No Kinds." $
25+
testCase "No Definition, No Kinds" $
1826
runKC [] @?= Right []
1927

28+
t2 :: TestTree
2029
t2 =
21-
testCase "Maybe has the correct Kind." $
30+
testCase "Maybe has the correct Kind" $
2231
runKC [tdMaybe] @?= Right [Type :->: Type]
2332

33+
t3 :: TestTree
2434
t3 =
25-
testCase "Maybe works correctly when used as a type." $
35+
testCase "Maybe works correctly when used as a type" $
2636
runKC [tdT1, tdMaybe] @?= Right [Type :->: Type, Type :->: Type]
2737

38+
t4 :: TestTree
2839
t4 =
29-
testCase "Maybe and a term containing a maybe work correctly." $
40+
testCase "Maybe and a term containing a maybe work correctly" $
3041
runKC [tdT1, tdMaybe, tdT2] @?= Right [Type :->: Type, Type :->: Type, Type :->: Type]
3142

43+
t5 :: TestTree
3244
t5 =
33-
testCase "Bad Type is caught and reported." $
45+
testCase "Bad Type is caught and reported" $
3446
runKC [tdMaybe, tdBT0]
3547
@?= Left
3648
( InferenceFailed
@@ -46,6 +58,7 @@ t5 =
4658
--------------------------------------------------------------------------------
4759
-- Manual type definitions.
4860

61+
tdMaybe :: TypeDefinition
4962
tdMaybe =
5063
TypeDefinition
5164
{ _td'name = "Maybe"
@@ -58,6 +71,7 @@ tdMaybe =
5871
}
5972

6073
-- T1 ~ T a = T Maybe (Maybe a)
74+
tdT1 :: TypeDefinition
6175
tdT1 =
6276
TypeDefinition
6377
{ _td'name = "T"
@@ -66,6 +80,7 @@ tdT1 =
6680
}
6781

6882
-- T2 ~ T a = T Maybe (Maybe a)
83+
tdT2 :: TypeDefinition
6984
tdT2 =
7085
TypeDefinition
7186
{ _td'name = "T2"
@@ -74,6 +89,7 @@ tdT2 =
7489
}
7590

7691
-- T2 ~ T = T Maybe Maybe
92+
tdBT0 :: TypeDefinition
7793
tdBT0 =
7894
TypeDefinition
7995
{ _td'name = "T"

lambda-buffers-frontend/.envrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
use flake ..#dev-frontend
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module LambdaBuffers.Frontend.Cli.Compile (CompileOpts (..), compile) where
2+
3+
import Control.Lens (makeLenses, (^.))
4+
import Data.Map qualified as Map
5+
import LambdaBuffers.Frontend (runFrontend)
6+
import LambdaBuffers.Frontend.PPrint ()
7+
import Prettyprinter (Pretty (pretty))
8+
import Proto.Compiler ()
9+
10+
data CompileOpts = CompileOpts
11+
{ _importPaths :: [FilePath]
12+
, _moduleFilepath :: FilePath
13+
}
14+
deriving stock (Eq, Show)
15+
16+
makeLenses ''CompileOpts
17+
18+
-- | Compile a filepath containing a LambdaBuffers module
19+
compile :: CompileOpts -> IO ()
20+
compile opts = do
21+
errOrMod <- runFrontend (opts ^. importPaths) (opts ^. moduleFilepath)
22+
case errOrMod of
23+
Left err -> print err
24+
Right mods -> do
25+
putStrLn "OK"
26+
putStrLn $ "Compiler closure contains the following modules: " <> (show . pretty . Map.elems $ mods)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
module LambdaBuffers.Frontend.Cli.Format (FormatOpts (..), format) where
2+
3+
import Control.Lens (makeLenses, (^.))
4+
import Data.Text.IO qualified as Text
5+
import LambdaBuffers.Frontend.PPrint ()
6+
import LambdaBuffers.Frontend.Parsec qualified as Parsec
7+
import Prettyprinter (Pretty (pretty))
8+
import Proto.Compiler ()
9+
10+
data FormatOpts = FormatOpts
11+
{ _moduleFilepath :: FilePath
12+
, _inPlace :: Bool
13+
}
14+
deriving stock (Eq, Show)
15+
16+
makeLenses ''FormatOpts
17+
18+
-- | Format a LambdaBuffers file
19+
format :: FormatOpts -> IO ()
20+
format opts = do
21+
modContent <- Text.readFile (opts ^. moduleFilepath)
22+
modOrErr <- Parsec.runParser Parsec.parseModule (opts ^. moduleFilepath) modContent
23+
case modOrErr of
24+
Left err -> print err
25+
Right m -> do
26+
let formatted = show . pretty $ m
27+
if opts ^. inPlace
28+
then Prelude.writeFile (opts ^. moduleFilepath) formatted
29+
else Prelude.putStrLn formatted

0 commit comments

Comments
 (0)