@@ -25,7 +25,7 @@ module Language.PureScript.CodeGen.JS (
26import Data.Maybe (catMaybes, fromJust, fromMaybe)
26import Data.Maybe (catMaybes, fromJust, fromMaybe)
27import Data.Function (on)
27import Data.Function (on)
28−import Data.List (nub, (\\), delete)
28+import Data.List (nub, (\\), delete, sortBy)
30import Control.Monad (replicateM, forM)
30import Control.Monad (replicateM, forM)
31import Control.Applicative
31import Control.Applicative
@@ -42,7 +42,6 @@ import Language.PureScript.CodeGen.Common
42import Language.PureScript.Environment
42import Language.PureScript.Environment
43import Language.PureScript.Supply
43import Language.PureScript.Supply
44import Language.PureScript.Traversals (sndM)
44import Language.PureScript.Traversals (sndM)
46import qualified Language.PureScript.Constants as C
45import qualified Language.PureScript.Constants as C
@@ -89,6 +88,7 @@ imports other =
89 collectV :: Value -> [ModuleName]
88 collectV :: Value -> [ModuleName]
90 collectV (Var (Qualified (Just mn) _)) = [mn]
89 collectV (Var (Qualified (Just mn) _)) = [mn]
91 collectV (Constructor (Qualified (Just mn) _)) = [mn]
90 collectV (Constructor (Qualified (Just mn) _)) = [mn]
91+ collectV (TypeClassDictionaryConstructorApp (Qualified (Just mn) _) _) = [mn]
92 collectV _ = []
92 collectV _ = []
93 collectB :: Binder -> [ModuleName]
93 collectB :: Binder -> [ModuleName]
94 collectB (ConstructorBinder (Qualified (Just mn) _) _) = [mn]
94 collectB (ConstructorBinder (Qualified (Just mn) _) _) = [mn]
@@ -109,16 +109,16 @@ declToJs opts mp (BindingGroupDeclaration vals) e = do
109declToJs _ _ (DataDeclaration _ _ ctors) _ = do
109declToJs _ _ (DataDeclaration _ _ ctors) _ = do
110 return $ Just $ flip concatMap ctors $ \(pn@(ProperName ctor), tys) ->
110 return $ Just $ flip concatMap ctors $ \(pn@(ProperName ctor), tys) ->
111 let _ctor = '_' : ctor
111 let _ctor = '_' : ctor
112− in [ JSVariableIntroduction _ctor (Just (makeConstructor (length tys)))
112+ in [ makeConstructor _ctor (length tys)
113 , JSVariableIntroduction ctor (Just (go pn 0 (length tys) []))
113 , JSVariableIntroduction ctor (Just (go pn 0 (length tys) []))
116− makeConstructor :: Int -> JS
116+ makeConstructor :: String -> Int -> JS
117− makeConstructor n =
117+ makeConstructor ctorName n =
119 args = [ "value" ++ show index | index <- [0..n-1] ]
119 args = [ "value" ++ show index | index <- [0..n-1] ]
120 body = [ JSAssignment (JSAccessor arg (JSVar "this")) (JSVar arg) | arg <- args ]
120 body = [ JSAssignment (JSAccessor arg (JSVar "this")) (JSVar arg) | arg <- args ]
121− in JSFunction Nothing args (JSBlock body)
121+ in JSFunction (Just ctorName) args (JSBlock body)
122 go :: ProperName -> Int -> Int -> [JS] -> JS
122 go :: ProperName -> Int -> Int -> [JS] -> JS
123 go pn _ 0 values = JSApp (JSNew (JSVar ('_' : runProperName pn))) (reverse values)
123 go pn _ 0 values = JSApp (JSNew (JSVar ('_' : runProperName pn))) (reverse values)
124 go pn index n values =
124 go pn index n values =
@@ -127,6 +127,27 @@ declToJs _ _ (DataDeclaration _ _ ctors) _ = do
127declToJs opts mp (DataBindingGroupDeclaration ds) e = do
127declToJs opts mp (DataBindingGroupDeclaration ds) e = do
128 jss <- mapM (\decl -> declToJs opts mp decl e) ds
128 jss <- mapM (\decl -> declToJs opts mp decl e) ds
129 return $ Just $ concat $ catMaybes jss
129 return $ Just $ concat $ catMaybes jss
130+declToJs _ _ (TypeClassDeclaration name _ supers members) _ =
132+ JSFunction (Just $ runProperName name) (identToJs `map` args)
133+ (JSBlock $ assn `map` args)]
136+ assn arg = JSAssignment (accessor arg (JSVar "this")) (var arg)
138+ args = sortBy (compare `on` runIdent) $ memberNames ++ superNames
139+ memberNames :: [Ident]
140+ memberNames = memberToName `map` members
141+ superNames :: [Ident]
142+ superNames = [ toSuperName superclass index
143+ | (index, (superclass, _)) <- zip [0..] supers
145+ toSuperName :: Qualified ProperName -> Integer -> Ident
146+ toSuperName pn index = Ident $ C.__superclass_ ++ show pn ++ "_" ++ show index
147+ memberToName :: Declaration -> Ident
148+ memberToName (TypeDeclaration ident _) = ident
149+ memberToName (PositionedDeclaration _ d) = memberToName d
150+ memberToName _ = error "Invalid declaration in type class definition"
130declToJs _ _ (ExternDeclaration _ _ (Just js) _) _ = return $ Just [js]
151declToJs _ _ (ExternDeclaration _ _ (Just js) _) _ = return $ Just [js]
131declToJs opts mp (PositionedDeclaration _ d) e = declToJs opts mp d e
152declToJs opts mp (PositionedDeclaration _ d) e = declToJs opts mp d e
132declToJs _ _ _ _ = return Nothing
153declToJs _ _ _ _ = return Nothing
@@ -138,6 +159,7 @@ exportToJs :: DeclarationRef -> [(String, JS)]
138exportToJs (TypeRef _ (Just dctors)) = concatMap ((\n -> [('_' : n, var (Ident ('_' : n))), (n, var (Ident n))]) . runProperName) dctors
159exportToJs (TypeRef _ (Just dctors)) = concatMap ((\n -> [('_' : n, var (Ident ('_' : n))), (n, var (Ident n))]) . runProperName) dctors
139exportToJs (ValueRef name) = [(runIdent name, var name)]
160exportToJs (ValueRef name) = [(runIdent name, var name)]
140exportToJs (TypeInstanceRef name) = [(runIdent name, var name)]
161exportToJs (TypeInstanceRef name) = [(runIdent name, var name)]
162+exportToJs (TypeClassRef name) = [(runProperName name, var $ Ident $ runProperName name)]
141exportToJs _ = []
163exportToJs _ = []
@@ -169,6 +191,10 @@ valueToJs _ _ _ (StringLiteral s) = return $ JSStringLiteral s
169valueToJs _ _ _ (BooleanLiteral b) = return $ JSBooleanLiteral b
191valueToJs _ _ _ (BooleanLiteral b) = return $ JSBooleanLiteral b
170valueToJs opts m e (ArrayLiteral xs) = JSArrayLiteral <$> mapM (valueToJs opts m e) xs
192valueToJs opts m e (ArrayLiteral xs) = JSArrayLiteral <$> mapM (valueToJs opts m e) xs
171valueToJs opts m e (ObjectLiteral ps) = JSObjectLiteral <$> mapM (sndM (valueToJs opts m e)) ps
193valueToJs opts m e (ObjectLiteral ps) = JSObjectLiteral <$> mapM (sndM (valueToJs opts m e)) ps
194+valueToJs opts m e (TypeClassDictionaryConstructorApp name (TypedValue _ (ObjectLiteral ps) _)) =
195+ JSApp (JSNew (qualifiedToJS m (Ident . runProperName) name)) <$> mapM (valueToJs opts m e . snd) (sortBy (compare `on` fst) ps)
196+valueToJs _ _ _ TypeClassDictionaryConstructorApp{} =
197+ error "TypeClassDictionaryConstructorApp did not contain object literal"
172valueToJs opts m e (ObjectUpdate o ps) = do
198valueToJs opts m e (ObjectUpdate o ps) = do
173 obj <- valueToJs opts m e o
199 obj <- valueToJs opts m e o
174 sts <- mapM (sndM (valueToJs opts m e)) ps
200 sts <- mapM (sndM (valueToJs opts m e)) ps