@@ -2,8 +2,14 @@
2module Elm.Interface
2module Elm.Interface
3 ( Interfaces
3 ( Interfaces
4 , Interface(..)
4 , Interface(..)
5 , Binop(..)
7 , Binop(..)
6 , fromModule
8 , fromModule
@@ -12,6 +18,7 @@ import Control.Monad (liftM4)
12import Data.Binary
18import Data.Binary
13import Data.Map ((!))
19import Data.Map ((!))
14import qualified Data.Map as Map
20import qualified Data.Map as Map
21+import qualified Data.Map.Merge.Strict as Map
16import qualified AST.Canonical as Can
23import qualified AST.Canonical as Can
17import qualified AST.Module.Name as ModuleName
24import qualified AST.Module.Name as ModuleName
@@ -35,12 +42,23 @@ type Interfaces =
35data Interface =
42data Interface =
37 { _types :: Map.Map N.Name Can.Annotation
44 { _types :: Map.Map N.Name Can.Annotation
38− , _unions :: Map.Map N.Name Can.Union
45+ , _unions :: Map.Map N.Name Union
39− , _aliases :: Map.Map N.Name Can.Alias
46+ , _aliases :: Map.Map N.Name Alias
40 , _binops :: Map.Map N.Name Binop
47 , _binops :: Map.Map N.Name Binop
52+ = OpenUnion Can.Union
53+ | ClosedUnion Can.Union
54+ | PrivateUnion Can.Union
58+ = PublicAlias Can.Alias
59+ | PrivateAlias Can.Alias
44data Binop =
62data Binop =
46 { _op_name :: N.Name
64 { _op_name :: N.Name
@@ -57,39 +75,104 @@ data Binop =
57fromModule :: Map.Map N.Name Can.Annotation -> Can.Module -> Interface
75fromModule :: Map.Map N.Name Can.Annotation -> Can.Module -> Interface
58fromModule types (Can.Module _ _ exports _ unions aliases binops _) =
76fromModule types (Can.Module _ _ exports _ unions aliases binops _) =
60− { _types = privatize exports const types
78+ { _types = privatize exports types
61− , _unions = privatize exports toUnion unions
79+ , _unions = privatizeUnions exports unions
62− , _aliases = privatize exports const aliases
80+ , _aliases = privatizeAliases exports aliases
63− , _binops = privatize exports const (Map.map (toOp types) binops)
81+ , _binops = privatize exports (Map.map (toOp types) binops)
67−privatize :: Can.Exports -> (a -> A.Located Can.Export -> a) -> Map.Map N.Name a -> Map.Map N.Name a
85+privatize :: Can.Exports -> Map.Map N.Name a -> Map.Map N.Name a
68−privatize exports func dict =
86+privatize exports dict =
69 case exports of
87 case exports of
70 Can.ExportEverything _ ->
88 Can.ExportEverything _ ->
73 Can.Export explicitExports ->
91 Can.Export explicitExports ->
74− Map.intersectionWith func dict explicitExports
92+ Map.intersection dict explicitExports
77−toUnion :: Can.Union -> A.Located Can.Export -> Can.Union
95+toOp :: Map.Map N.Name Can.Annotation -> Can.Binop -> Binop
78−toUnion union@(Can.Union vars _ _ opts) (A.At _ export) =
96+toOp types (Can.Binop_ associativity precedence name) =
79− case export of
97+ Binop name (types ! name) associativity precedence
80− Can.ExportUnionOpen ->
83− Can.ExportUnionClosed ->
84− Can.Union vars [] 0 opts
86− _ ->
100+privatizeUnions :: Can.Exports -> Map.Map N.Name Can.Union -> Map.Map N.Name Union
87− error "Compiler bug. Should not run into non-union exports here."
101+privatizeUnions exports unions =
103+ Can.ExportEverything _ ->
104+ Map.map OpenUnion unions
106+ Can.Export explicitExports ->
107+ Map.merge onLeft onRight onBoth explicitExports unions
109+ onLeft = Map.dropMissing
110+ onRight = Map.mapMissing (\_ u -> PrivateUnion u)
111+ onBoth = Map.zipWithMatched $ \_ e u ->
113+ Can.ExportUnionOpen -> OpenUnion u
114+ Can.ExportUnionClosed -> ClosedUnion u
115+ _ -> error "impossible exports discovered in privatizeUnions"
118+privatizeAliases :: Can.Exports -> Map.Map N.Name Can.Alias -> Map.Map N.Name Alias
119+privatizeAliases exports aliases =
121+ Can.ExportEverything _ ->
122+ Map.map PublicAlias aliases
90−toOp :: Map.Map N.Name Can.Annotation -> Can.Binop -> Binop
124+ Can.Export explicitExports ->
91−toOp types (Can.Binop_ associativity precedence name) =
125+ Map.merge onLeft onRight onBoth explicitExports aliases
92− Binop name (types ! name) associativity precedence
126+ where
127+ onLeft = Map.dropMissing
128+ onRight = Map.mapMissing (\_ a -> PrivateAlias a)
129+ onBoth = Map.zipWithMatched (\_ _ a -> PublicAlias a)
136+toPublicUnion :: Union -> Maybe Can.Union
137+toPublicUnion iUnion =
142+ ClosedUnion (Can.Union vars _ _ opts) ->
143+ Just (Can.Union vars [] 0 opts)
149+toPublicAlias :: Alias -> Maybe Can.Alias
150+toPublicAlias iAlias =
152+ PublicAlias alias ->
163+toUnionInternals :: Union -> Can.Union
164+toUnionInternals iUnion =
166+ OpenUnion union -> union
167+ ClosedUnion union -> union
168+ PrivateUnion union -> union
171+toAliasInternals :: Alias -> Can.Alias
172+toAliasInternals iAlias =
174+ PublicAlias alias -> alias
175+ PrivateAlias alias -> alias
@@ -104,6 +187,36 @@ instance Binary Interface where
104 put a >> put b >> put c >> put d
187 put a >> put b >> put c >> put d
190+instance Binary Union where
193+ OpenUnion u -> putWord8 0 >> put u
194+ ClosedUnion u -> putWord8 1 >> put u
195+ PrivateUnion u -> putWord8 2 >> put u
200+ 0 -> OpenUnion <$> get
201+ 1 -> ClosedUnion <$> get
202+ 2 -> PrivateUnion <$> get
203+ _ -> error "binary encoding of Union was corrupted"
206+instance Binary Alias where
209+ PublicAlias a -> putWord8 0 >> put a
210+ PrivateAlias a -> putWord8 1 >> put a
215+ 0 -> PublicAlias <$> get
216+ 1 -> PrivateAlias <$> get
217+ _ -> error "binary encoding of Alias was corrupted"
107instance Binary Binop where
220instance Binary Binop where
109 liftM4 Binop get get get get
222 liftM4 Binop get get get get