1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
11import Prelude hiding (maybe, null)
12import Control.Monad (foldM, zipWithM)
13import qualified Data.Text as Text
14import Data.Text (Text)
16import qualified AST.Expression.Optimized as Opt
17import qualified AST.Helpers as Help
18import qualified AST.Literal as Literal
19import qualified AST.Module.Name as ModuleName
20import qualified AST.Type as T
21import qualified AST.Variable as Var
22import qualified Optimize.DecisionTree as DT
23import qualified Optimize.Environment as Env
30toEncoder :: T.Canonical -> Env.Optimizer Opt.Expr
34 toEncoder (T.dealias args t)
37 error "toEncoder: function"
40 error "toEncoder: type variable"
43 | Var.isPrim "Float" name -> encode "float"
44 | Var.isPrim "Int" name -> encode "int"
45 | Var.isPrim "Bool" name -> encode "bool"
46 | Var.isPrim "String" name -> encode "string"
47 | Var.isJson name -> encode "value"
48 | Var.isTuple name -> encode "null"
49 | otherwise -> error "toEncoder: bad type"
52 | Var.isMaybe name -> encodeMaybe arg
53 | Var.isList name -> encodeList arg
54 | Var.isArray name -> encodeArray arg
55 | otherwise -> error "toEncoder: bad union type"
58 | Var.isTuple name -> encodeTuple args
61 error "toEncoder: bad union type"
63 T.Record _ (Just _) ->
64 error "toEncoder: bad record"
66 T.Record fields Nothing ->
68 convert (field, typ) =
69 do encoder <- toEncoder typ
72 , Opt.Call encoder [ Opt.Access (Opt.VarLocal "r") field ]
75 do record <- traverse convert fields
76 return $ Opt.Function ["r"] (Opt.Record record)
83encodeMaybe :: T.Canonical -> Env.Optimizer Opt.Expr
85 do null <- encode "null"
86 encoder <- toEncoder tipe
88 let nothing = Var.inCore "Maybe" "Nothing"
89 let test = (DT.Empty, DT.Constructor nothing)
90 let just = Opt.Call encoder [ Opt.CtorAccess (Opt.VarLocal "m") 0 ]
91 let leaf expr = Opt.Leaf (Opt.Inline expr)
93 return $ Opt.Function ["m"] $
94 Opt.Case "m" (Opt.Chain [test] (leaf null) (leaf just)) []
97encodeList :: T.Canonical -> Env.Optimizer Opt.Expr
99 do list <- encode "list"
100 map_ <- core "List" "map"
101 encoder <- toEncoder tipe
103 Opt.Function ["xs"] $
104 Opt.Call list [ Opt.Call map_ [ encoder, Opt.VarLocal "xs" ] ]
107encodeArray :: T.Canonical -> Env.Optimizer Opt.Expr
109 do array <- encode "array"
110 map_ <- core "Array" "map"
111 encoder <- toEncoder tipe
113 Opt.Function ["xs"] $
114 Opt.Call array [ Opt.Call map_ [ encoder, Opt.VarLocal "xs" ] ]
117encodeTuple :: [T.Canonical] -> Env.Optimizer Opt.Expr
121 do encoder <- toEncoder tipe
123 Opt.Call encoder [ Opt.CtorAccess (Opt.VarLocal "t") index ]
125 do list <- encode "list"
126 entries <- zipWithM convert tipes [ 0 .. length tipes ]
127 return $ Opt.Function ["t"] $ Opt.Call list entries
134toFlagsDecoder :: T.Canonical -> Env.Optimizer Opt.Expr
137 T.Type name [] | Var.isTuple name ->
138 do succeed <- decode "succeed"
139 return $ Opt.Call succeed [ Opt.Ctor Help.zeroTuple [] ]
149toDecoder :: T.Canonical -> Env.Optimizer Opt.Expr
153 error "functions should not be allowed through input ports"
156 error "type variables should not be allowed through input ports"
158 T.Aliased _ args t ->
159 toDecoder (T.dealias args t)
162 | Var.isPrim "Float" name -> decode "float"
163 | Var.isPrim "Int" name -> decode "int"
164 | Var.isPrim "Bool" name -> decode "bool"
165 | Var.isPrim "String" name -> decode "string"
166 | Var.isJson name -> decode "value"
167 | Var.isTuple name -> decodeTuple0
168 | otherwise -> error "toDecoder: bad type"
171 | Var.isMaybe name -> decodeMaybe arg
172 | Var.isList name -> decodeList arg
173 | Var.isArray name -> decodeArray arg
174 | otherwise -> error "toDecoder: bad union type"
177 | Var.isTuple name -> decodeTuple args
180 error "toDecoder: bad union type"
182 T.Record _ (Just _) ->
183 error "toDecoder: bad record"
185 T.Record fields Nothing ->
193decodeMaybe :: T.Canonical -> Env.Optimizer Opt.Expr
195 do let nothing = Var.Global (ModuleName.inCore "Maybe") "Nothing"
196 let just = Var.Global (ModuleName.inCore "Maybe") "Just"
201 oneOf <- decode "oneOf"
202 null <- decode "null"
205 subDecoder <- toDecoder tipe
210 [ Opt.Call null [ Opt.VarGlobal nothing ]
211 , Opt.Call map_ [ Opt.VarGlobal just, subDecoder ]
219decodeList :: T.Canonical -> Env.Optimizer Opt.Expr
221 do list <- decode "list"
222 decoder <- toDecoder tipe
223 return $ Opt.Call list [ decoder ]
230decodeArray :: T.Canonical -> Env.Optimizer Opt.Expr
232 do array <- decode "array"
233 decoder <- toDecoder tipe
234 return $ Opt.Call array [ decoder ]
241decodeTuple0 :: Env.Optimizer Opt.Expr
243 do null <- decode "null"
244 return (Opt.Call null [ Opt.Ctor Help.zeroTuple [] ])
247decodeTuple :: [T.Canonical] -> Env.Optimizer Opt.Expr
254 zip [ 0 .. size - 1] types
258 (Help.makeTuple size)
259 (map (Opt.VarLocal . indexToName . fst) entries)
261 do succeed <- decode "succeed"
262 foldM indexAndThen (Opt.Call succeed [tuple]) entries
265indexToName :: Int -> Text
267 Text.pack ('x' : show index)
270indexAndThen :: Opt.Expr -> (Int, T.Canonical) -> Env.Optimizer Opt.Expr
271indexAndThen decoder (i, tipe) =
272 do andThen <- decode "andThen"
273 index <- decode "index"
274 typeDecoder <- toDecoder tipe
277 [ Opt.Function [indexToName i] decoder
278 , Opt.Call index [ Opt.Literal (Literal.IntNum i), typeDecoder ]
286decodeRecord :: [(Text, T.Canonical)] -> Env.Optimizer Opt.Expr
289 toFieldExpr (key, _) =
290 (key, Opt.VarLocal key)
293 Opt.Record (map toFieldExpr fields)
295 do succeed <- decode "succeed"
296 foldM fieldAndThen (Opt.Call succeed [record]) fields
299fieldAndThen :: Opt.Expr -> (Text, T.Canonical) -> Env.Optimizer Opt.Expr
300fieldAndThen decoder (key, tipe) =
301 do andThen <- decode "andThen"
302 field <- decode "field"
303 typeDecoder <- toDecoder tipe
306 [ Opt.Function [key] decoder
307 , Opt.Call field [ Opt.Literal (Literal.Str key), typeDecoder ]
315core :: Text -> Text -> Env.Optimizer Opt.Expr
317 do let var = Var.Global (ModuleName.inCore home) name
319 return (Opt.VarGlobal var)
322encode :: Text -> Env.Optimizer Opt.Expr
324 core "Json.Encode" name
327decode :: Text -> Env.Optimizer Opt.Expr
329 core "Json.Decode" 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