@@ -3,6 +3,7 @@
33module Generate.JavaScript.Foreign (encode, decode) where
44
55import Prelude hiding (maybe)
6+import Control.Monad (zipWithM)
67import qualified Data.List as List
78import qualified Data.Text as Text
89import Data.Text (Text)
@@ -15,18 +16,20 @@ import qualified AST.Variable as Var
1516import qualified Generate.JavaScript.Builder as JS
1617import qualified Generate.JavaScript.Helpers as JS (function, ref)
1718import Generate.JavaScript.Helpers ((<|), (==>))
19+import qualified Generate.JavaScript.Variable as JS (Generator, global)
1820
1921
2022
2123-- ENCODE
2224
2325
24−encode :: T.Canonical -> JS.Expr
26+encode :: T.Canonical -> JS.Generator JS.Expr
2527encode tipe =
26− JS.function ["v"] [ JS.Return (Just (encodeHelp tipe (JS.ref "v"))) ]
28+ do js <- encodeHelp tipe (JS.ref "v")
29+ return $ JS.function ["v"] [ JS.Return (Just js) ]
2730
2831
29−encodeHelp :: T.Canonical -> JS.Expr -> JS.Expr
32+encodeHelp :: T.Canonical -> JS.Expr -> JS.Generator JS.Expr
3033encodeHelp tipe expr =
3134 case tipe of
3235 T.Aliased _ args t ->
@@ -39,12 +42,12 @@ encodeHelp tipe expr =
3942 error "encodeHelp: type variable"
4043
4144 T.Type name
42− | Var.isPrim "Float" name -> expr
43− | Var.isPrim "Int" name -> expr
44− | Var.isPrim "Bool" name -> expr
45− | Var.isPrim "String" name -> expr
46− | Var.isJson name -> expr
47− | Var.isTuple name -> JS.Null
45+ | Var.isPrim "Float" name -> pure expr
46+ | Var.isPrim "Int" name -> pure expr
47+ | Var.isPrim "Bool" name -> pure expr
48+ | Var.isPrim "String" name -> pure expr
49+ | Var.isJson name -> pure expr
50+ | Var.isTuple name -> pure JS.Null
4851 | otherwise -> error "encodeHelp: bad type"
4952
5053 T.App (T.Type name) [arg]
@@ -65,44 +68,41 @@ encodeHelp tipe expr =
6568 T.Record fields Nothing ->
6669 let
6770 convert (k, t) =
68− k ==> encodeHelp t (JS.DotRef expr (JS.Id k))
71+ (==>) k <$> encodeHelp t (JS.DotRef expr (JS.Id k))
6972 in
70− JS.Object (map convert fields)
73+ JS.Object <$> traverse convert fields
7174
7275
73−fromMaybe :: T.Canonical -> JS.Expr -> JS.Expr
76+fromMaybe :: T.Canonical -> JS.Expr -> JS.Generator JS.Expr
7477fromMaybe tipe expr =
75− JS.If
76− (JS.Infix JS.OpStrictEq (JS.DotRef expr (JS.Id "ctor")) (JS.String "Nothing"))
77− (JS.Null)
78− (encodeHelp tipe (JS.DotRef expr (JS.Id "_0")))
78+ do js <- encodeHelp tipe (JS.DotRef expr (JS.Id "_0"))
79+ let isNothing = JS.Infix JS.OpStrictEq (JS.DotRef expr (JS.Id "ctor")) (JS.String "Nothing")
80+ return $ JS.If isNothing JS.Null js
7981
8082
81−fromList :: T.Canonical -> JS.Expr -> JS.Expr
83+fromList :: T.Canonical -> JS.Expr -> JS.Generator JS.Expr
8284fromList tipe expr =
83− let
84− array =
85− error "TODO port fromList" expr -- Var.coreNative "List" "toArray" <| expr
86− in
87− JS.DotRef array (JS.Id "map") <| encode tipe
85+ do let var = Var.Global (ModuleName.inCore "Elm.Kernel.List") "toArray"
86+ toArray <- JS.global var
87+ encoder <- encode tipe
88+ return $ JS.DotRef (toArray <| expr) (JS.Id "map") <| encoder
8889
8990
90−fromArray :: T.Canonical -> JS.Expr -> JS.Expr
91+fromArray :: T.Canonical -> JS.Expr -> JS.Generator JS.Expr
9192fromArray tipe expr =
92− let
93− array =
94− error "TODO port fromArray" expr -- Var.coreNative "Array" "toJSArray" <| expr
95− in
96− JS.DotRef array (JS.Id "map") <| encode tipe
93+ do let var = Var.Global (ModuleName.inCore "Elm.Kernel.Array") "toJSArray"
94+ toArray <- JS.global var
95+ encoder <- encode tipe
96+ return $ JS.DotRef (toArray <| expr) (JS.Id "map") <| encoder
9797
9898
99−fromTuple :: [T.Canonical] -> JS.Expr -> JS.Expr
99+fromTuple :: [T.Canonical] -> JS.Expr -> JS.Generator JS.Expr
100100fromTuple types expr =
101101 let
102102 convert subType n =
103103 encodeHelp subType $ JS.DotRef expr (JS.Id (Text.pack ('_':show n)))
104104 in
105− JS.Array (zipWith convert types [ 0 .. length types ])
105+ JS.Array <$> zipWithM convert types [ 0 .. length types ]
106106
107107
108108