1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
11import Prelude hiding (maybe, null)
12import Control.Monad (foldM)
13import qualified Data.Map as Map
14import qualified Data.Name as Name
16import qualified AST.Canonical as Can
17import qualified AST.Optimized as Opt
18import qualified AST.Utils.Type as Type
19import qualified Data.Index as Index
20import qualified Elm.ModuleName as ModuleName
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"
41 Opt.Function [Name.dollar] <$> encode "null"
46 Can.TType _ name args ->
49 | name == Name.float -> encode "float"
50 | name == Name.int -> encode "int"
51 | name == Name.bool -> encode "bool"
52 | name == Name.string -> encode "string"
53 | name == Name.value -> Names.registerGlobal ModuleName.basics Name.identity
56 | name == Name.maybe -> encodeMaybe arg
57 | name == Name.list -> encodeList arg
58 | name == Name.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, Can.FieldType _ fieldType) =
69 do encoder <- toEncoder fieldType
70 let value = Opt.Call encoder [Opt.Access (Opt.VarLocal Name.dollar) name]
71 return $ Opt.Tuple (Opt.Str (Name.toElmString name)) value Nothing
73 do object <- encode "object"
74 keyValuePairs <- traverse encodeField (Map.toList fields)
75 Names.registerFieldDict fields $
76 Opt.Function [Name.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 [Name.dollar] $
89 Opt.Call destruct [ null, encoder, Opt.VarLocal Name.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 Name.dollar))) body
113 do encoder <- toEncoder tipe
114 return $ Opt.Call encoder [ Opt.VarLocal arg ]
116 do list <- encode "list"
117 identity <- Names.registerGlobal ModuleName.basics Name.identity
118 arg1 <- encodeArg "a" a
119 arg2 <- encodeArg "b" b
123 return $ Opt.Function [Name.dollar] $
124 let_ "a" Index.first $
125 let_ "b" Index.second $
126 Opt.Call list [ identity, Opt.List [ arg1, arg2 ] ]
129 do arg3 <- encodeArg "c" c
130 return $ Opt.Function [Name.dollar] $
131 let_ "a" Index.first $
132 let_ "b" Index.second $
133 let_ "c" Index.third $
134 Opt.Call list [ identity, Opt.List [ arg1, arg2, arg3 ] ]
141toFlagsDecoder :: Can.Type -> Names.Tracker Opt.Expr
145 do succeed <- decode "succeed"
146 return $ Opt.Call succeed [ Opt.Unit ]
156toDecoder :: Can.Type -> Names.Tracker Opt.Expr
160 error "functions should not be allowed through input ports"
163 error "type variables should not be allowed through input ports"
165 Can.TAlias _ _ args alias ->
166 toDecoder (Type.dealias args alias)
174 Can.TType _ name args ->
177 | name == Name.float -> decode "float"
178 | name == Name.int -> decode "int"
179 | name == Name.bool -> decode "bool"
180 | name == Name.string -> decode "string"
181 | name == Name.value -> decode "value"
184 | name == Name.maybe -> decodeMaybe arg
185 | name == Name.list -> decodeList arg
186 | name == Name.array -> decodeArray arg
189 error "toDecoder: bad type"
191 Can.TRecord _ (Just _) ->
192 error "toDecoder: bad record"
194 Can.TRecord fields Nothing ->
202decodeMaybe :: Can.Type -> Names.Tracker Opt.Expr
204 do nothing <- Names.registerGlobal ModuleName.maybe "Nothing"
205 just <- Names.registerGlobal ModuleName.maybe "Just"
207 oneOf <- decode "oneOf"
208 null <- decode "null"
211 subDecoder <- toDecoder tipe
216 [ Opt.Call null [ nothing ]
217 , Opt.Call map_ [ just, subDecoder ]
225decodeList :: Can.Type -> Names.Tracker Opt.Expr
227 do list <- decode "list"
228 decoder <- toDecoder tipe
229 return $ Opt.Call list [ decoder ]
236decodeArray :: Can.Type -> Names.Tracker Opt.Expr
238 do array <- decode "array"
239 decoder <- toDecoder tipe
240 return $ Opt.Call array [ decoder ]
247decodeTuple0 :: Names.Tracker Opt.Expr
249 do null <- decode "null"
250 return (Opt.Call null [ Opt.Unit ])
253decodeTuple :: Can.Type -> Can.Type -> Maybe Can.Type -> Names.Tracker Opt.Expr
254decodeTuple a b maybeC =
255 do succeed <- decode "succeed"
258 let tuple = Opt.Tuple (toLocal 0) (toLocal 1) Nothing in
260 indexAndThen 1 b (Opt.Call succeed [tuple])
263 let tuple = Opt.Tuple (toLocal 0) (toLocal 1) (Just (toLocal 2)) in
266 indexAndThen 2 c (Opt.Call succeed [tuple])
269toLocal :: Int -> Opt.Expr
271 Opt.VarLocal (Name.fromVarIndex index)
274indexAndThen :: Int -> Can.Type -> Opt.Expr -> Names.Tracker Opt.Expr
275indexAndThen i tipe decoder =
276 do andThen <- decode "andThen"
277 index <- decode "index"
278 typeDecoder <- toDecoder tipe
281 [ Opt.Function [Name.fromVarIndex i] decoder
282 , Opt.Call index [ Opt.Int i, typeDecoder ]
290decodeRecord :: Map.Map Name.Name Can.FieldType -> Names.Tracker Opt.Expr
297 Opt.Record (Map.mapWithKey toFieldExpr fields)
299 do succeed <- decode "succeed"
300 foldM fieldAndThen (Opt.Call succeed [record]) =<<
301 Names.registerFieldDict fields (Map.toList fields)
304fieldAndThen :: Opt.Expr -> (Name.Name, Can.FieldType) -> Names.Tracker Opt.Expr
305fieldAndThen decoder (key, Can.FieldType _ tipe) =
306 do andThen <- decode "andThen"
307 field <- decode "field"
308 typeDecoder <- toDecoder tipe
311 [ Opt.Function [key] decoder
312 , Opt.Call field [ Opt.Str (Name.toElmString key), typeDecoder ]
320encode :: Name.Name -> Names.Tracker Opt.Expr
322 Names.registerGlobal ModuleName.jsonEncode name
325decode :: Name.Name -> Names.Tracker Opt.Expr
327 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