@@ -81,14 +81,18 @@ importToJs mt opts mn = JSVariableIntroduction (moduleNameToJs mn) (Just moduleB
81 Globals -> JSAccessor (moduleNameToJs mn) (JSVar (fromJust (optionsBrowserNamespace opts)))
81 Globals -> JSAccessor (moduleNameToJs mn) (JSVar (fromJust (optionsBrowserNamespace opts)))
83imports :: Declaration -> [ModuleName]
83imports :: Declaration -> [ModuleName]
84−imports =
84+imports (ImportDeclaration mn _ _) = [mn]
85− let (f, _, _, _, _) = everythingOnValues (++) (const []) collect (const []) (const []) (const [])
86+ let (f, _, _, _, _) = everythingOnValues (++) (const []) collectV collectB (const []) (const [])
88− collect :: Value -> [ModuleName]
89+ collectV :: Value -> [ModuleName]
89− collect (Var (Qualified (Just mn) _)) = [mn]
90+ collectV (Var (Qualified (Just mn) _)) = [mn]
90− collect (Constructor (Qualified (Just mn) _)) = [mn]
91+ collectV (Constructor (Qualified (Just mn) _)) = [mn]
91− collect _ = []
92+ collectV _ = []
93+ collectB :: Binder -> [ModuleName]
94+ collectB (ConstructorBinder (Qualified (Just mn) _) _) = [mn]
94-- Generate code in the simplified Javascript intermediate representation for a declaration
98-- Generate code in the simplified Javascript intermediate representation for a declaration
@@ -102,16 +106,24 @@ declToJs opts mp (BindingGroupDeclaration vals) e = do
102 js <- valueToJs opts mp e val
106 js <- valueToJs opts mp e val
103 return $ JSVariableIntroduction (identToJs ident) (Just js)
107 return $ JSVariableIntroduction (identToJs ident) (Just js)
104 return $ Just jss
108 return $ Just jss
105−declToJs _ mp (DataDeclaration _ _ ctors) _ = do
109+declToJs _ _ (DataDeclaration _ _ ctors) _ = do
106 return $ Just $ flip concatMap ctors $ \(pn@(ProperName ctor), tys) ->
110 return $ Just $ flip concatMap ctors $ \(pn@(ProperName ctor), tys) ->
111+ let _ctor = '_' : ctor
107− [JSVariableIntroduction ctor (Just (go pn 0 tys []))]
112+ in [ JSVariableIntroduction _ctor (Just (makeConstructor (length tys)))
113+ , JSVariableIntroduction ctor (Just (go pn 0 (length tys) []))
116+ makeConstructor :: Int -> JS
119+ args = [ "value" ++ show index | index <- [0..n-1] ]
120+ body = [ JSAssignment (JSAccessor arg (JSVar "this")) (JSVar arg) | arg <- args ]
121+ in JSFunction Nothing args (JSBlock body)
109− go :: ProperName -> Integer -> [Type] -> [JS] -> JS
122+ go :: ProperName -> Int -> Int -> [JS] -> JS
110− go pn _ [] values =
123+ go pn _ 0 values = JSApp (JSNew (JSVar ('_' : runProperName pn))) (reverse values)
111− JSObjectLiteral [ ("ctor", JSStringLiteral (show (Qualified (Just mp) pn))), ("values", JSArrayLiteral $ reverse values) ]
112− go pn index (_ : tys') values =
124+ go pn index n values =
113 JSFunction Nothing ["value" ++ show index]
125 JSFunction Nothing ["value" ++ show index]
114− (JSBlock [JSReturn (go pn (index + 1) tys' (JSVar ("value" ++ show index) : values))])
126+ (JSBlock [JSReturn (go pn (index + 1) (n - 1) (JSVar ("value" ++ show index) : values))])
115declToJs opts mp (DataBindingGroupDeclaration ds) e = do
127declToJs opts mp (DataBindingGroupDeclaration ds) e = do
116 jss <- mapM (\decl -> declToJs opts mp decl e) ds
128 jss <- mapM (\decl -> declToJs opts mp decl e) ds
117 return $ Just $ concat $ catMaybes jss
129 return $ Just $ concat $ catMaybes jss
@@ -123,7 +135,7 @@ declToJs _ _ _ _ = return Nothing
123-- Generate key//value pairs for an object literal exporting values from a module.
135-- Generate key//value pairs for an object literal exporting values from a module.
125exportToJs :: DeclarationRef -> [(String, JS)]
137exportToJs :: DeclarationRef -> [(String, JS)]
126−exportToJs (TypeRef _ (Just dctors)) = map ((\n -> (n, var (Ident n))) . runProperName) dctors
138+exportToJs (TypeRef _ (Just dctors)) = concatMap ((\n -> [('_' : n, var (Ident ('_' : n))), (n, var (Ident n))]) . runProperName) dctors
127exportToJs (ValueRef name) = [(runIdent name, var name)]
139exportToJs (ValueRef name) = [(runIdent name, var name)]
128exportToJs (TypeInstanceRef name) = [(runIdent name, var name)]
140exportToJs (TypeInstanceRef name) = [(runIdent name, var name)]
129exportToJs _ = []
141exportToJs _ = []
@@ -291,23 +303,25 @@ binderToJs _ _ varName done (BooleanBinder False) =
291 return [JSIfElse (JSUnary Not (JSVar varName)) (JSBlock done) Nothing]
303 return [JSIfElse (JSUnary Not (JSVar varName)) (JSBlock done) Nothing]
292binderToJs _ _ varName done (VarBinder ident) =
304binderToJs _ _ varName done (VarBinder ident) =
293 return (JSVariableIntroduction (identToJs ident) (Just (JSVar varName)) : done)
305 return (JSVariableIntroduction (identToJs ident) (Just (JSVar varName)) : done)
294−binderToJs m e varName done (ConstructorBinder ctor bs) = do
306+binderToJs m e varName done (ConstructorBinder ctor@(Qualified ctorModule (ProperName ctorName)) bs) = do
295 js <- go 0 done bs
307 js <- go 0 done bs
296 if isOnlyConstructor e ctor
308 if isOnlyConstructor e ctor
298 return js
310 return js
300− return [JSIfElse (JSBinary EqualTo (JSAccessor "ctor" (JSVar varName)) (JSStringLiteral (show ctor)))
312+ return [JSIfElse (JSInstanceOf (JSVar varName) (qualifiedToJS m (Ident . runProperName) _ctor))
301 (JSBlock js)
313 (JSBlock js)
316+ _ctor :: Qualified ProperName
317+ _ctor = Qualified ctorModule (ProperName ('_' : ctorName))
304 go :: (Functor m, Applicative m, Monad m) => Integer -> [JS] -> [Binder] -> SupplyT m [JS]
318 go :: (Functor m, Applicative m, Monad m) => Integer -> [JS] -> [Binder] -> SupplyT m [JS]
305 go _ done' [] = return done'
319 go _ done' [] = return done'
306 go index done' (binder:bs') = do
320 go index done' (binder:bs') = do
307 argVar <- freshName
321 argVar <- freshName
308 done'' <- go (index + 1) done' bs'
322 done'' <- go (index + 1) done' bs'
309 js <- binderToJs m e argVar done'' binder
323 js <- binderToJs m e argVar done'' binder
310− return (JSVariableIntroduction argVar (Just (JSIndexer (JSNumericLiteral (Left index)) (JSAccessor "values" (JSVar varName)))) : js)
324+ return (JSVariableIntroduction argVar (Just (JSAccessor ("value" ++ show index) (JSVar varName))) : js)
311binderToJs m e varName done (ObjectBinder bs) = go done bs
325binderToJs m e varName done (ObjectBinder bs) = go done bs
313 go :: (Functor m, Applicative m, Monad m) => [JS] -> [(String, Binder)] -> SupplyT m [JS]
327 go :: (Functor m, Applicative m, Monad m) => [JS] -> [(String, Binder)] -> SupplyT m [JS]