1module Generate.JavaScript.Foreign (input, output) where
3import qualified Data.List as List
4import Generate.JavaScript.Helpers
5import AST.PrettyPrint (pretty)
7import qualified AST.Variable as Var
8import Language.ECMAScript3.Syntax
19typeToString :: JSType -> String
22 JSNumber -> "a number"
23 JSBoolean -> "a boolean (true or false)"
24 JSString -> "a string"
27 "an object with fields '" ++ List.intercalate "', '" fields ++ "'"
30_Array :: String -> Expression ()
32 useLazy ["Elm","Native","Array"] functionName
35_List :: String -> Expression ()
37 useLazy ["Elm","Native","List"] functionName
40_Maybe :: String -> Expression ()
42 useLazy ["Elm","Maybe"] functionName
45check :: Expression () -> JSType -> Expression () -> Expression ()
46check x jsType continue =
47 CondExpr () (jsFold OpLOr checks x) continue throw
49 jsFold op checks value =
50 foldl1 (InfixExpr () op) (map ($ value) checks)
53 obj ["_U","badPort"] `call` [ string (typeToString jsType), x ]
57 JSNumber -> [typeof "number"]
58 JSBoolean -> [typeof "boolean"]
59 JSString -> [typeof "string", instanceof "String"]
60 JSArray -> [instanceof "Array"]
62 [jsFold OpLAnd (typeof "object" : map member fields)]
67input :: String -> CanonicalType -> Expression ()
70 [ string name, string (show (pretty t)), toTypeFunction t ]
77 | Var.isStream signal ->
78 obj ["_P","inputStream"] `call` args t
80 | Var.isVarying signal ->
81 obj ["_P","inputVarying"] `call` args t
84 obj ["_P","inputValue"] `call` args tipe
87toTypeFunction :: CanonicalType -> Expression ()
89 ["v"] ==> toType tipe (ref "v")
92toType :: CanonicalType -> Expression () -> Expression ()
96 error "functions should not be allowed through input ports"
99 error "type variables should not be allowed through input ports"
104 Type (Var.Canonical Var.BuiltIn name)
105 | name == "Int" -> from JSNumber
106 | name == "Float" -> from JSNumber
107 | name == "Bool" -> from JSBoolean
108 | name == "String" -> from JSString
110 from checks = check x checks x
116 | Var.isTuple name ->
120 error "bad type got to foreign input conversion"
125 | Var.isMaybe name ->
127 (equal x (NullLit ()))
129 (_Maybe "Just" <| toType t x)
132 check x JSArray (_List "fromArray" <| array)
134 | Var.isArray name ->
135 check x JSArray (_Array "fromJSArray" <| array)
137 array = DotRef () x (var "map") <| toTypeFunction t
140 | Var.isTuple name ->
143 _ -> error "bad ADT got to foreign input conversion"
146 error "bad record got to foreign input conversion"
148 Record fields Nothing ->
149 check x (JSObject (map fst fields)) object
151 object = ObjectLit () $ (prop "_", ObjectLit () []) : keys
152 keys = map convert fields
153 convert (f,t) = (prop f, toType t (DotRef () x (var f)))
156toTuple :: [CanonicalType] -> Expression () -> Expression ()
158 check x JSArray (ObjectLit () fields)
161 (prop "ctor", ctor) : zipWith convert [0..] types
164 string ("_Tuple" ++ show (length types))
168 , toType t (BracketRef () x (IntLit () n))
174output :: String -> CanonicalType -> Expression () -> Expression ()
175output name tipe value =
177 [ string name, fromTypeFunction t, value ]
183 App (Type signal) [t]
184 | Var.isStream signal ->
185 obj ["_P","outputStream"] `call` args t
187 | Var.isVarying signal ->
188 obj ["_P","outputVarying"] `call` args t
191 obj ["_P","outputValue"] `call` args tipe
194fromTypeFunction :: CanonicalType -> Expression ()
195fromTypeFunction tipe =
196 ["v"] ==> fromType tipe (ref "v")
199fromType :: CanonicalType -> Expression () -> Expression ()
206 | numArgs > 1 && numArgs < 10 ->
207 func (ref ('A':show numArgs) `call` (x:values))
209 func (foldl (<|) x values)
211 ts = T.collectLambdas tipe
212 numArgs = length ts - 1
213 args = map (\n -> '_' : show n) [0..]
214 values = zipWith toType (init ts) (map ref args)
216 function (take numArgs args)
217 [ VarDeclStmt () [VarDecl () (var "_r") (Just body)]
218 , ret (fromType (last ts) (ref "_r"))
222 error "type variables should not be allowed through outputs"
224 Type (Var.Canonical Var.BuiltIn name)
225 | name `elem` ["Int","Float","Bool","String"] ->
229 | Var.isJson name -> x
230 | Var.isTuple name -> ArrayLit () []
231 | otherwise -> error "bad type got to an output"
236 | Var.isMaybe name ->
238 (equal (DotRef () x (var "ctor")) (string "Nothing"))
240 (fromType t (DotRef () x (var "_0")))
242 | Var.isArray name ->
243 DotRef () (_Array "toJSArray" <| x) (var "map") <| fromTypeFunction t
246 DotRef () (_List "toArray" <| x) (var "map") <| fromTypeFunction t
249 | Var.isTuple name ->
250 let convert n t = fromType t $ DotRef () x $ var ('_':show n)
251 in ArrayLit () $ zipWith convert [0..] ts
253 _ -> error "bad ADT got to an output"
256 error "bad record got to an output"
258 Record fields Nothing ->
261 keys = map convert fields
263 (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