1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
11import Prelude hiding (maybe, null)
12import Control.Monad (foldM)
13import qualified Data.Map as Map
15import qualified AST.Canonical as Can
16import qualified AST.Optimized as Opt
17import qualified AST.Module.Name as ModuleName
18import qualified AST.Utils.Type as Type
19import qualified Data.Index as Index
20import qualified Elm.Name as N
21import qualified Optimize.Names as Names
28toEncoder :: Can.Type -> Names.Tracker Opt.Expr
31 Can.TAlias _ _ args alias ->
32 toEncoder (Type.dealias args alias)
35 error "toEncoder: function"
38 error "toEncoder: type variable"
46 Can.TType _ name args ->
49 | name == N.float -> encode "float"
50 | name == N.int -> encode "int"
51 | name == N.bool -> encode "bool"
52 | name == N.string -> encode "string"
53 | name == N.value -> encode "value"
56 | name == N.maybe -> encodeMaybe arg
57 | name == N.list -> encodeList arg
58 | name == N.array -> encodeArray arg
61 error "toEncoder: bad union type"
63 Can.TRecord _ (Just _) ->
64 error "toEncoder: bad record"
66 Can.TRecord fields Nothing ->
68 encodeField (name, fieldType) =
69 do encoder <- toEncoder fieldType
70 let value = Opt.Call encoder [Opt.Access (Opt.VarLocal N.dollar) name]
71 return $ Opt.Tuple (Opt.Str name) value Nothing
73 do object <- encode "object"
74 keyValuePairs <- traverse encodeField (Map.toList fields)
75 Names.registerFieldDict fields $
76 Opt.Function [N.dollar] (Opt.Call object [Opt.List keyValuePairs])
83encodeMaybe :: Can.Type -> Names.Tracker Opt.Expr
85 do null <- encode "null"
86 encoder <- toEncoder tipe
87 destruct <- Names.registerGlobal ModuleName.maybe "destruct"
88 return $ Opt.Function [N.dollar] $
89 Opt.Call destruct [ null, encoder, Opt.VarLocal N.dollar ]
92encodeList :: Can.Type -> Names.Tracker Opt.Expr
94 do list <- encode "list"
95 map_ <- Names.registerGlobal ModuleName.list "map"
96 encoder <- toEncoder tipe
98 Opt.Function [N.dollar] $
99 Opt.Call list [ Opt.Call map_ [ encoder, Opt.VarLocal N.dollar ] ]
102encodeArray :: Can.Type -> Names.Tracker Opt.Expr
104 do array <- encode "array"
105 map_ <- Names.registerGlobal ModuleName.array "map"
106 encoder <- toEncoder tipe
108 Opt.Function [N.dollar] $
109 Opt.Call array [ Opt.Call map_ [ encoder, Opt.VarLocal N.dollar ] ]
112encodeTuple :: Can.Type -> Can.Type -> Maybe Can.Type -> Names.Tracker Opt.Expr
113encodeTuple a b maybeC =
115 let_ arg index body =
116 Opt.Destruct (Opt.Destructor arg (Opt.Index index (Opt.Root N.dollar))) body
119 do encoder <- toEncoder tipe
120 return $ Opt.Call encoder [ Opt.VarLocal arg ]
122 do list <- encode "list"
123 arg1 <- encodeArg "a" a
124 arg2 <- encodeArg "b" b
126 Opt.Function [N.dollar] <$>
127 let_ "a" Index.first <$>
128 let_ "b" Index.second <$>
131 return $ Opt.Call list [ arg1, arg2 ]
134 do arg3 <- encodeArg "c" c
135 return $ let_ "c" Index.third $
136 Opt.Call list [ arg1, arg2, arg3 ]
143toFlagsDecoder :: Can.Type -> Names.Tracker Opt.Expr
147 do succeed <- decode "succeed"
148 return $ Opt.Call succeed [ Opt.Unit ]
158toDecoder :: Can.Type -> Names.Tracker Opt.Expr
162 error "functions should not be allowed through input ports"
165 error "type variables should not be allowed through input ports"
167 Can.TAlias _ _ args alias ->
168 toDecoder (Type.dealias args alias)
176 Can.TType _ name args ->
179 | name == N.float -> decode "float"
180 | name == N.int -> decode "int"
181 | name == N.bool -> decode "bool"
182 | name == N.string -> decode "string"
183 | name == N.value -> decode "value"
186 | name == N.maybe -> decodeMaybe arg
187 | name == N.list -> decodeList arg
188 | name == N.array -> decodeArray arg
191 error "toDecoder: bad type"
193 Can.TRecord _ (Just _) ->
194 error "toDecoder: bad record"
196 Can.TRecord fields Nothing ->
204decodeMaybe :: Can.Type -> Names.Tracker Opt.Expr
206 do nothing <- Names.registerGlobal ModuleName.maybe "Nothing"
207 just <- Names.registerGlobal ModuleName.maybe "Just"
209 oneOf <- decode "oneOf"
210 null <- decode "null"
213 subDecoder <- toDecoder tipe
218 [ Opt.Call null [ nothing ]
219 , Opt.Call map_ [ just, subDecoder ]
227decodeList :: Can.Type -> Names.Tracker Opt.Expr
229 do list <- decode "list"
230 decoder <- toDecoder tipe
231 return $ Opt.Call list [ decoder ]
238decodeArray :: Can.Type -> Names.Tracker Opt.Expr
240 do array <- decode "array"
241 decoder <- toDecoder tipe
242 return $ Opt.Call array [ decoder ]
249decodeTuple0 :: Names.Tracker Opt.Expr
251 do null <- decode "null"
252 return (Opt.Call null [ Opt.Unit ])
255decodeTuple :: Can.Type -> Can.Type -> Maybe Can.Type -> Names.Tracker Opt.Expr
256decodeTuple a b maybeC =
257 do succeed <- decode "succeed"
260 let tuple = Opt.Tuple (toLocal 0) (toLocal 1) Nothing in
262 indexAndThen 1 b (Opt.Call succeed [tuple])
265 let tuple = Opt.Tuple (toLocal 0) (toLocal 1) (Just (toLocal 2)) in
268 indexAndThen 2 c (Opt.Call succeed [tuple])
271toLocal :: Int -> Opt.Expr
273 Opt.VarLocal (N.addIndex "x" index)
276indexAndThen :: Int -> Can.Type -> Opt.Expr -> Names.Tracker Opt.Expr
277indexAndThen i tipe decoder =
278 do andThen <- decode "andThen"
279 index <- decode "index"
280 typeDecoder <- toDecoder tipe
283 [ Opt.Function [N.addIndex "x" i] decoder
284 , Opt.Call index [ Opt.Int i, typeDecoder ]
292decodeRecord :: Map.Map N.Name Can.Type -> Names.Tracker Opt.Expr
299 Opt.Record (Map.mapWithKey toFieldExpr fields)
301 do succeed <- decode "succeed"
302 foldM fieldAndThen (Opt.Call succeed [record]) =<<
303 Names.registerFieldDict fields (Map.toList fields)
306fieldAndThen :: Opt.Expr -> (N.Name, Can.Type) -> Names.Tracker Opt.Expr
307fieldAndThen decoder (key, tipe) =
308 do andThen <- decode "andThen"
309 field <- decode "field"
310 typeDecoder <- toDecoder tipe
313 [ Opt.Function [key] decoder
314 , Opt.Call field [ Opt.Str key, typeDecoder ]
322encode :: N.Name -> Names.Tracker Opt.Expr
324 Names.registerGlobal ModuleName.jsonEncode name
327decode :: N.Name -> Names.Tracker Opt.Expr
329 Names.registerGlobal ModuleName.jsonDecode name
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list