@@ -3,6 +3,7 @@
3module Generate.JavaScript.Foreign (encode, decode) where
3module Generate.JavaScript.Foreign (encode, decode) where
5import Prelude hiding (maybe)
5import Prelude hiding (maybe)
6+import Control.Monad (zipWithM)
6import qualified Data.List as List
7import qualified Data.List as List
7import qualified Data.Text as Text
8import qualified Data.Text as Text
8import Data.Text (Text)
9import Data.Text (Text)
@@ -15,18 +16,20 @@ import qualified AST.Variable as Var
15import qualified Generate.JavaScript.Builder as JS
16import qualified Generate.JavaScript.Builder as JS
16import qualified Generate.JavaScript.Helpers as JS (function, ref)
17import qualified Generate.JavaScript.Helpers as JS (function, ref)
17import Generate.JavaScript.Helpers ((<|), (==>))
18import Generate.JavaScript.Helpers ((<|), (==>))
19+import qualified Generate.JavaScript.Variable as JS (Generator, global)
24−encode :: T.Canonical -> JS.Expr
26+encode :: T.Canonical -> JS.Generator JS.Expr
25encode tipe =
27encode 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) ]
29−encodeHelp :: T.Canonical -> JS.Expr -> JS.Expr
32+encodeHelp :: T.Canonical -> JS.Expr -> JS.Generator JS.Expr
30encodeHelp tipe expr =
33encodeHelp tipe expr =
31 case tipe of
34 case tipe of
32 T.Aliased _ args t ->
35 T.Aliased _ args t ->
@@ -39,12 +42,12 @@ encodeHelp tipe expr =
39 error "encodeHelp: type variable"
42 error "encodeHelp: type variable"
41 T.Type name
44 T.Type name
42− | Var.isPrim "Float" name -> expr
45+ | Var.isPrim "Float" name -> pure expr
43− | Var.isPrim "Int" name -> expr
46+ | Var.isPrim "Int" name -> pure expr
44− | Var.isPrim "Bool" name -> expr
47+ | Var.isPrim "Bool" name -> pure expr
45− | Var.isPrim "String" name -> expr
48+ | Var.isPrim "String" name -> pure expr
46− | Var.isJson name -> expr
49+ | Var.isJson name -> pure expr
47− | Var.isTuple name -> JS.Null
50+ | Var.isTuple name -> pure JS.Null
48 | otherwise -> error "encodeHelp: bad type"
51 | otherwise -> error "encodeHelp: bad type"
50 T.App (T.Type name) [arg]
53 T.App (T.Type name) [arg]
@@ -65,44 +68,41 @@ encodeHelp tipe expr =
65 T.Record fields Nothing ->
68 T.Record fields Nothing ->
67 convert (k, t) =
70 convert (k, t) =
68− k ==> encodeHelp t (JS.DotRef expr (JS.Id k))
71+ (==>) k <$> encodeHelp t (JS.DotRef expr (JS.Id k))
70− JS.Object (map convert fields)
73+ JS.Object <$> traverse convert fields
73−fromMaybe :: T.Canonical -> JS.Expr -> JS.Expr
76+fromMaybe :: T.Canonical -> JS.Expr -> JS.Generator JS.Expr
74fromMaybe tipe expr =
77fromMaybe tipe expr =
75− JS.If
78+ do js <- encodeHelp tipe (JS.DotRef expr (JS.Id "_0"))
76− (JS.Infix JS.OpStrictEq (JS.DotRef expr (JS.Id "ctor")) (JS.String "Nothing"))
79+ let isNothing = JS.Infix JS.OpStrictEq (JS.DotRef expr (JS.Id "ctor")) (JS.String "Nothing")
77− (JS.Null)
80+ return $ JS.If isNothing JS.Null js
78− (encodeHelp tipe (JS.DotRef expr (JS.Id "_0")))
81−fromList :: T.Canonical -> JS.Expr -> JS.Expr
83+fromList :: T.Canonical -> JS.Expr -> JS.Generator JS.Expr
82fromList tipe expr =
84fromList tipe expr =
83− let
85+ do let var = Var.Global (ModuleName.inCore "Elm.Kernel.List") "toArray"
84− array =
86+ toArray <- JS.global var
85− error "TODO port fromList" expr -- Var.coreNative "List" "toArray" <| expr
87+ encoder <- encode tipe
87− JS.DotRef array (JS.Id "map") <| encode tipe
88+ return $ JS.DotRef (toArray <| expr) (JS.Id "map") <| encoder
90−fromArray :: T.Canonical -> JS.Expr -> JS.Expr
91+fromArray :: T.Canonical -> JS.Expr -> JS.Generator JS.Expr
91fromArray tipe expr =
92fromArray tipe expr =
92− let
93+ do let var = Var.Global (ModuleName.inCore "Elm.Kernel.Array") "toJSArray"
93− array =
94+ toArray <- JS.global var
94− error "TODO port fromArray" expr -- Var.coreNative "Array" "toJSArray" <| expr
95+ encoder <- encode tipe
96− JS.DotRef array (JS.Id "map") <| encode tipe
96+ return $ JS.DotRef (toArray <| expr) (JS.Id "map") <| encoder
99−fromTuple :: [T.Canonical] -> JS.Expr -> JS.Expr
99+fromTuple :: [T.Canonical] -> JS.Expr -> JS.Generator JS.Expr
100fromTuple types expr =
100fromTuple types expr =
102 convert subType n =
102 convert subType n =
103 encodeHelp subType $ JS.DotRef expr (JS.Id (Text.pack ('_':show n)))
103 encodeHelp subType $ JS.DotRef expr (JS.Id (Text.pack ('_':show n)))
105− JS.Array (zipWith convert types [ 0 .. length types ])
105+ JS.Array <$> zipWithM convert types [ 0 .. length types ]