1module Generate.JavaScript.Port
2 ( inbound, inboundStream
3 , outbound, outboundStream
6import qualified Data.List as List
7import Language.ECMAScript3.Syntax
9import AST.PrettyPrint (pretty)
11import qualified AST.Variable as Var
12import Generate.JavaScript.Helpers
23typeToString :: JSType -> String
26 JSNumber -> "a number"
27 JSBoolean -> "a boolean (true or false)"
28 JSString -> "a string"
31 "an object with fields '" ++ List.intercalate "', '" fields ++ "'"
34_Array :: String -> Expression ()
36 useLazy ["Elm","Native","Array"] functionName
39_List :: String -> Expression ()
41 useLazy ["Elm","Native","List"] functionName
44_Maybe :: String -> Expression ()
46 useLazy ["Elm","Maybe"] functionName
49_Port :: String -> Expression ()
51 useLazy ["Elm","Native","Port"] functionName
54check :: Expression () -> JSType -> Expression () -> Expression ()
55check x jsType continue =
56 CondExpr () (jsFold OpLOr checks x) continue throw
58 jsFold op checks value =
59 foldl1 (InfixExpr () op) (map ($ value) checks)
62 obj ["_U","badPort"] `call` [ string (typeToString jsType), x ]
66 JSNumber -> [typeof "number"]
67 JSBoolean -> [typeof "boolean"]
68 JSString -> [typeof "string", instanceof "String"]
69 JSArray -> [instanceof "Array"]
71 [jsFold OpLAnd (typeof "object" : map member fields)]
76inbound :: String -> CanonicalType -> Expression ()
78 _Port "inbound" `call`
80 , string (show (pretty tipe))
85inboundStream :: String -> CanonicalType -> Expression ()
86inboundStream name tipe =
87 _Port "inboundStream" `call`
89 , string (show (pretty tipe))
94toTypeFunction :: CanonicalType -> Expression ()
96 ["v"] ==> toType tipe (ref "v")
99toType :: CanonicalType -> Expression () -> Expression ()
103 error "functions should not be allowed through input ports"
106 error "type variables should not be allowed through input ports"
109 toType (dealias args t) x
111 Type (Var.Canonical Var.BuiltIn name)
112 | name == "Int" -> from JSNumber
113 | name == "Float" -> from JSNumber
114 | name == "Bool" -> from JSBoolean
115 | name == "String" -> from JSString
117 from checks = check x checks x
120 | Var.isJavaScript name ->
123 | Var.isTuple name ->
127 error "bad type got to foreign input conversion"
132 | Var.isMaybe name ->
134 (equal x (NullLit ()))
136 (_Maybe "Just" <| toType t x)
139 check x JSArray (_List "fromArray" <| array)
141 | Var.isArray name ->
142 check x JSArray (_Array "fromJSArray" <| array)
144 array = DotRef () x (var "map") <| toTypeFunction t
147 | Var.isTuple name ->
150 _ -> error "bad ADT got to foreign input conversion"
153 error "bad record got to foreign input conversion"
155 Record fields Nothing ->
156 check x (JSObject (map fst fields)) object
158 object = ObjectLit () $ (prop "_", ObjectLit () []) : keys
159 keys = map convert fields
160 convert (f,t) = (prop f, toType t (DotRef () x (var f)))
163toTuple :: [CanonicalType] -> Expression () -> Expression ()
165 check x JSArray (ObjectLit () fields)
168 (prop "ctor", ctor) : zipWith convert [0..] types
171 string ("_Tuple" ++ show (length types))
175 , toType t (BracketRef () x (IntLit () n))
181outbound :: String -> CanonicalType -> Expression () -> Expression ()
182outbound name tipe expr =
183 _Port "outbound" `call` [ string name, fromTypeFunction tipe, expr ]
186outboundStream :: String -> CanonicalType -> Expression () -> Expression ()
187outboundStream name tipe expr =
188 _Port "outboundStream" `call` [ string name, fromTypeFunction tipe, expr ]
191fromTypeFunction :: CanonicalType -> Expression ()
192fromTypeFunction tipe =
193 ["v"] ==> fromType tipe (ref "v")
196fromType :: CanonicalType -> Expression () -> Expression ()
200 fromType (dealias args t) x
203 | numArgs > 1 && numArgs < 10 ->
204 func (ref ('A':show numArgs) `call` (x:values))
206 func (foldl (<|) x values)
208 ts = T.collectLambdas tipe
209 numArgs = length ts - 1
210 args = map (\n -> '_' : show n) [0..]
211 values = zipWith toType (init ts) (map ref args)
213 function (take numArgs args)
214 [ VarDeclStmt () [VarDecl () (var "_r") (Just body)]
215 , ret (fromType (last ts) (ref "_r"))
219 error "type variables should not be allowed through outputs"
221 Type (Var.Canonical Var.BuiltIn name)
222 | name `elem` ["Int","Float","Bool","String"] ->
226 | Var.isJavaScript name -> x
227 | Var.isTuple name -> ArrayLit () []
228 | otherwise -> error "bad type got to an output"
233 | Var.isMaybe name ->
235 (equal (DotRef () x (var "ctor")) (string "Nothing"))
237 (fromType t (DotRef () x (var "_0")))
239 | Var.isArray name ->
240 DotRef () (_Array "toJSArray" <| x) (var "map") <| fromTypeFunction t
243 DotRef () (_List "toArray" <| x) (var "map") <| fromTypeFunction t
246 | Var.isTuple name ->
247 let convert n t = fromType t $ DotRef () x $ var ('_':show n)
248 in ArrayLit () $ zipWith convert [0..] ts
250 _ -> error "bad ADT got to an output"
253 error "bad record got to an output"
255 Record fields Nothing ->
258 keys = map convert fields
260 (PropId () (var f), fromType t (DotRef () x (var f)))
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