1module Generate.JavaScript.Foreign (encode, decode) where
3import qualified Data.List as List
4import Language.ECMAScript3.Syntax
6import qualified AST.Expression.Optimized as Opt
7import qualified AST.Literal as Literal
8import qualified AST.Type as T
9import qualified AST.Variable as Var
10import Generate.JavaScript.Helpers ((<|), (==>), function, ref, var)
11import qualified Generate.JavaScript.Variable as Var
18encode :: T.Canonical -> Expression ()
20 function ["v"] [ ReturnStmt () (Just (encodeHelp tipe (ref "v"))) ]
23encodeHelp :: T.Canonical -> Expression () -> Expression ()
27 encodeHelp (T.dealias args t) expr
30 error "encodeHelp: function"
33 error "encodeHelp: type variable"
36 | Var.isPrim "Float" name -> expr
37 | Var.isPrim "Int" name -> expr
38 | Var.isPrim "Bool" name -> expr
39 | Var.isPrim "String" name -> expr
40 | Var.isJson name -> expr
41 | Var.isTuple name -> NullLit ()
42 | otherwise -> error "encodeHelp: bad type"
44 T.App (T.Type name) [arg]
45 | Var.isMaybe name -> fromMaybe arg expr
46 | Var.isList name -> fromList arg expr
47 | Var.isArray name -> fromArray arg expr
48 | otherwise -> error "encodeHelp: bad union type"
50 T.App (T.Type name) args
51 | Var.isTuple name -> fromTuple args expr
54 error "encodeHelp: bad union type"
56 T.Record _ (Just _) ->
57 error "encodeHelp: bad record"
59 T.Record fields Nothing ->
61 convert (name, tipe) =
62 name ==> encodeHelp tipe (DotRef () expr (var name))
64 ObjectLit () (map convert fields)
67fromMaybe :: T.Canonical -> Expression () -> Expression ()
70 (InfixExpr () OpStrictEq (DotRef () expr (var "ctor")) (StringLit () "Nothing"))
72 (encodeHelp tipe (DotRef () expr (var "_0")))
75fromList :: T.Canonical -> Expression () -> Expression ()
79 Var.coreNative "List" "toArray" <| expr
81 DotRef () array (var "map") <| encode tipe
84fromArray :: T.Canonical -> Expression () -> Expression ()
88 Var.coreNative "Array" "toJSArray" <| expr
90 DotRef () array (var "map") <| encode tipe
93fromTuple :: [T.Canonical] -> Expression () -> Expression ()
97 encodeHelp subType $ DotRef () expr (var ('_':show n))
99 ArrayLit () (zipWith convert types [0..])
106decode :: T.Canonical -> Opt.Expr
110 error "functions should not be allowed through input ports"
113 error "type variables should not be allowed through input ports"
115 T.Aliased _ args t ->
116 decode (T.dealias args t)
119 | Var.isPrim "Float" name -> to "float"
120 | Var.isPrim "Int" name -> to "int"
121 | Var.isPrim "Bool" name -> to "bool"
122 | Var.isPrim "String" name -> to "string"
123 | Var.isJson name -> to "value"
124 | Var.isTuple name -> toTuple0
125 | otherwise -> error "decode: bad type"
127 T.App (T.Type name) [arg]
128 | Var.isMaybe name -> toMaybe arg
129 | Var.isList name -> to "list" <== [decode arg]
130 | Var.isArray name -> to "array" <== [decode arg]
131 | otherwise -> error "decode: bad union type"
133 T.App (T.Type name) args
134 | Var.isTuple name -> toTuple args
137 error "decode: bad union type"
139 T.Record _ (Just _) ->
140 error "decode: bad record"
142 T.Record fields Nothing ->
149inJsonDecode :: String -> Var.Canonical
151 Var.inCore ["Json","Decode"] name
154to :: String -> Opt.Expr
156 Opt.Var (inJsonDecode name)
159field :: String -> Opt.Expr -> Opt.Expr
161 to "field" <== [ Opt.Literal (Literal.Str name), decoder ]
164index :: Int -> Opt.Expr -> Opt.Expr
166 to "index" <== [ Opt.Literal (Literal.IntNum index), decoder ]
169(<==) :: Opt.Expr -> [Opt.Expr] -> Opt.Expr
175-- COMPLEX DECODE HELPERS
178toMaybe :: T.Canonical -> Opt.Expr
182 Opt.Var (Var.inCore ["Maybe"] tag)
186 [ to "null" <== [ maybe "Nothing" ]
187 , to "map" <== [ maybe "Just", decode tipe ]
194 to "null" <== [ Opt.Ctor "_Tuple0" [] ]
197toTuple :: [T.Canonical] -> Opt.Expr
204 zipWith (,) [ 0 .. size - 1] types
212 ("_Tuple" ++ show size)
213 (map (Opt.Var . Var.local . toVar . fst) pairs)
216 andThen (i, tipe) decoder =
217 to "andThen" <== [ Opt.Function [toVar i] decoder, index i (decode tipe) ]
219 List.foldr andThen makeTuple pairs
222toRecord :: [(String, T.Canonical)] -> Opt.Expr
225 toFieldExpr (key, _) =
226 (key, Opt.Var (Var.local key))
229 to "succeed" <== [ Opt.Record (map toFieldExpr fields) ]
231 andThen (key, tipe) decoder =
232 to "andThen" <== [ Opt.Function [key] decoder, field key (decode tipe) ]
234 List.foldr andThen finalDecoder fields
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