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 (N.toText 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 encoder <- toEncoder tipe
96 return $ Opt.Call list [ encoder ]
99encodeArray :: Can.Type -> Names.Tracker Opt.Expr
101 do array <- encode "array"
102 encoder <- toEncoder tipe
103 return $ Opt.Call array [ encoder ]
106encodeTuple :: Can.Type -> Can.Type -> Maybe Can.Type -> Names.Tracker Opt.Expr
107encodeTuple a b maybeC =
109 let_ arg index body =
110 Opt.Destruct (Opt.Destructor arg (Opt.Index index (Opt.Root N.dollar))) body
113 do encoder <- toEncoder tipe
114 return $ Opt.Call encoder [ Opt.VarLocal arg ]
116 do list <- encode "list"
117 arg1 <- encodeArg "a" a
118 arg2 <- encodeArg "b" b
120 Opt.Function [N.dollar] <$>
121 let_ "a" Index.first <$>
122 let_ "b" Index.second <$>
125 return $ Opt.Call list [ arg1, arg2 ]
128 do arg3 <- encodeArg "c" c
129 return $ let_ "c" Index.third $
130 Opt.Call list [ arg1, arg2, arg3 ]
137toFlagsDecoder :: Can.Type -> Names.Tracker Opt.Expr
141 do succeed <- decode "succeed"
142 return $ Opt.Call succeed [ Opt.Unit ]
152toDecoder :: Can.Type -> Names.Tracker Opt.Expr
156 error "functions should not be allowed through input ports"
159 error "type variables should not be allowed through input ports"
161 Can.TAlias _ _ args alias ->
162 toDecoder (Type.dealias args alias)
170 Can.TType _ name args ->
173 | name == N.float -> decode "float"
174 | name == N.int -> decode "int"
175 | name == N.bool -> decode "bool"
176 | name == N.string -> decode "string"
177 | name == N.value -> decode "value"
180 | name == N.maybe -> decodeMaybe arg
181 | name == N.list -> decodeList arg
182 | name == N.array -> decodeArray arg
185 error "toDecoder: bad type"
187 Can.TRecord _ (Just _) ->
188 error "toDecoder: bad record"
190 Can.TRecord fields Nothing ->
198decodeMaybe :: Can.Type -> Names.Tracker Opt.Expr
200 do nothing <- Names.registerGlobal ModuleName.maybe "Nothing"
201 just <- Names.registerGlobal ModuleName.maybe "Just"
203 oneOf <- decode "oneOf"
204 null <- decode "null"
207 subDecoder <- toDecoder tipe
212 [ Opt.Call null [ nothing ]
213 , Opt.Call map_ [ just, subDecoder ]
221decodeList :: Can.Type -> Names.Tracker Opt.Expr
223 do list <- decode "list"
224 decoder <- toDecoder tipe
225 return $ Opt.Call list [ decoder ]
232decodeArray :: Can.Type -> Names.Tracker Opt.Expr
234 do array <- decode "array"
235 decoder <- toDecoder tipe
236 return $ Opt.Call array [ decoder ]
243decodeTuple0 :: Names.Tracker Opt.Expr
245 do null <- decode "null"
246 return (Opt.Call null [ Opt.Unit ])
249decodeTuple :: Can.Type -> Can.Type -> Maybe Can.Type -> Names.Tracker Opt.Expr
250decodeTuple a b maybeC =
251 do succeed <- decode "succeed"
254 let tuple = Opt.Tuple (toLocal 0) (toLocal 1) Nothing in
256 indexAndThen 1 b (Opt.Call succeed [tuple])
259 let tuple = Opt.Tuple (toLocal 0) (toLocal 1) (Just (toLocal 2)) in
262 indexAndThen 2 c (Opt.Call succeed [tuple])
265toLocal :: Int -> Opt.Expr
267 Opt.VarLocal (N.addIndex "x" index)
270indexAndThen :: Int -> Can.Type -> Opt.Expr -> Names.Tracker Opt.Expr
271indexAndThen i tipe decoder =
272 do andThen <- decode "andThen"
273 index <- decode "index"
274 typeDecoder <- toDecoder tipe
277 [ Opt.Function [N.addIndex "x" i] decoder
278 , Opt.Call index [ Opt.Int i, typeDecoder ]
286decodeRecord :: Map.Map N.Name Can.Type -> Names.Tracker Opt.Expr
293 Opt.Record (Map.mapWithKey toFieldExpr fields)
295 do succeed <- decode "succeed"
296 foldM fieldAndThen (Opt.Call succeed [record]) =<<
297 Names.registerFieldDict fields (Map.toList fields)
300fieldAndThen :: Opt.Expr -> (N.Name, Can.Type) -> Names.Tracker Opt.Expr
301fieldAndThen decoder (key, tipe) =
302 do andThen <- decode "andThen"
303 field <- decode "field"
304 typeDecoder <- toDecoder tipe
307 [ Opt.Function [key] decoder
308 , Opt.Call field [ Opt.Str (N.toText key), typeDecoder ]
316encode :: N.Name -> Names.Tracker Opt.Expr
318 Names.registerGlobal ModuleName.jsonEncode name
321decode :: N.Name -> Names.Tracker Opt.Expr
323 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