@@ -23,49 +23,51 @@ import Data.Data
23import Data.Graph
23import Data.Graph
24import Data.Generics
24import Data.Generics
25import Data.List (nub, intersect)
25import Data.List (nub, intersect)
26+import Control.Applicative ((<$>))
27import Language.PureScript.Declarations
28import Language.PureScript.Declarations
28import Language.PureScript.Names
29import Language.PureScript.Names
29import Language.PureScript.Values
30import Language.PureScript.Values
30import Language.PureScript.Types
31import Language.PureScript.Types
32+import Debug.Trace (trace)
32−createBindingGroupsModule :: [Module] -> [Module]
34+createBindingGroupsModule :: [Module] -> Either String [Module]
33−createBindingGroupsModule = map $ \(Module name ds) -> Module name (createBindingGroups ds)
35+createBindingGroupsModule = mapM $ \(Module name ds) -> Module name <$> createBindingGroups ds
35collapseBindingGroupsModule :: [Module] -> [Module]
37collapseBindingGroupsModule :: [Module] -> [Module]
36collapseBindingGroupsModule = map $ \(Module name ds) -> Module name (collapseBindingGroups ds)
38collapseBindingGroupsModule = map $ \(Module name ds) -> Module name (collapseBindingGroups ds)
38−createBindingGroups :: [Declaration] -> [Declaration]
40+createBindingGroups :: [Declaration] -> Either String [Declaration]
39−createBindingGroups ds =
41+createBindingGroups ds = do
41− values = filter isValueDecl ds
42+ let values = filter isValueDecl ds
42− dataDecls = filter isDataDecl ds
43+ dataDecls = filter isDataDecl ds
43− nonValues = filter (\d -> not (isValueDecl d) && not (isDataDecl d)) ds
44− allProperNames = map getProperName dataDecls
44+ allProperNames = map getProperName dataDecls
45− dataVerts = map (\d -> (d, getProperName d, usedProperNames d `intersect` allProperNames)) dataDecls
45+ dataVerts = map (\d -> (d, getProperName d, usedProperNames d `intersect` allProperNames)) dataDecls
46− dataBindingGroupDecls = map toDataBindingGroup $ stronglyConnComp dataVerts
46+ dataBindingGroupDecls <- mapM toDataBindingGroup $ stronglyConnComp dataVerts
47− allIdents = map getIdent values
47+ let allIdents = map getIdent values
48− valueVerts = map (\d -> (d, getIdent d, usedIdents d `intersect` allIdents)) values
48+ valueVerts = map (\d -> (d, getIdent d, usedIdents d `intersect` allIdents)) values
49− bindingGroupDecls = map toBindingGroup $ stronglyConnComp valueVerts
49+ bindingGroupDecls = map toBindingGroup $ stronglyConnComp valueVerts
50− in
50+ return $ filter isImportDecl ds ++
51+ filter isExternDataDecl ds ++
51− dataBindingGroupDecls ++ nonValues ++ bindingGroupDecls
52+ dataBindingGroupDecls ++
53+ filter isTypeClassDeclaration ds ++
54+ filter isFixityDecl ds ++
55+ filter isExternDecl ds ++
53collapseBindingGroups :: [Declaration] -> [Declaration]
58collapseBindingGroups :: [Declaration] -> [Declaration]
54collapseBindingGroups ds = concatMap go ds
59collapseBindingGroups ds = concatMap go ds
56− go (DataBindingGroupDeclaration ds) = map (\(name, args, dctors) -> DataDeclaration name args dctors) ds
61+ go (DataBindingGroupDeclaration ds) = ds
57 go (BindingGroupDeclaration ds) = map (\(ident, val) -> ValueDeclaration ident [] Nothing val) ds
62 go (BindingGroupDeclaration ds) = map (\(ident, val) -> ValueDeclaration ident [] Nothing val) ds
58 go other = [other]
63 go other = [other]
60usedIdents :: (Data d) => d -> [Ident]
65usedIdents :: (Data d) => d -> [Ident]
61−usedIdents = nub . everything (++) (mkQ [] namesV `extQ` namesS)
66+usedIdents = nub . everything (++) (mkQ [] names)
63− namesV :: Value -> [Ident]
68+ names :: Value -> [Ident]
64− namesV (Var (Qualified Nothing name)) = [name]
69+ names (Var (Qualified Nothing name)) = [name]
65− namesV _ = []
70+ names _ = []
66− namesS :: Statement -> [Ident]
67− namesS (VariableIntroduction name _) = [name]
70usedProperNames :: (Data d) => d -> [ProperName]
72usedProperNames :: (Data d) => d -> [ProperName]
71usedProperNames = nub . everything (++) (mkQ [] names)
73usedProperNames = nub . everything (++) (mkQ [] names)
@@ -74,20 +76,13 @@ usedProperNames = nub . everything (++) (mkQ [] names)
74 names (TypeConstructor (Qualified Nothing name)) = [name]
76 names (TypeConstructor (Qualified Nothing name)) = [name]
75 names _ = []
77 names _ = []
77−isValueDecl :: Declaration -> Bool
78−isValueDecl (ValueDeclaration _ _ _ _) = True
81−isDataDecl :: Declaration -> Bool
82−isDataDecl (DataDeclaration _ _ _) = True
85getIdent :: Declaration -> Ident
79getIdent :: Declaration -> Ident
86getIdent (ValueDeclaration ident _ _ _) = ident
80getIdent (ValueDeclaration ident _ _ _) = ident
87getIdent _ = error "Expected ValueDeclaration"
81getIdent _ = error "Expected ValueDeclaration"
89getProperName :: Declaration -> ProperName
83getProperName :: Declaration -> ProperName
90getProperName (DataDeclaration pn _ _) = pn
84getProperName (DataDeclaration pn _ _) = pn
85+getProperName (TypeSynonymDeclaration pn _ _) = pn
91getProperName _ = error "Expected DataDeclaration"
86getProperName _ = error "Expected DataDeclaration"
93toBindingGroup :: SCC Declaration -> Declaration
88toBindingGroup :: SCC Declaration -> Declaration
@@ -95,16 +90,18 @@ toBindingGroup (AcyclicSCC d) = d
95toBindingGroup (CyclicSCC [d]) = d
90toBindingGroup (CyclicSCC [d]) = d
96toBindingGroup (CyclicSCC ds') = BindingGroupDeclaration $ map fromValueDecl ds'
91toBindingGroup (CyclicSCC ds') = BindingGroupDeclaration $ map fromValueDecl ds'
98−toDataBindingGroup :: SCC Declaration -> Declaration
93+toDataBindingGroup :: SCC Declaration -> Either String Declaration
99−toDataBindingGroup (AcyclicSCC d) = d
94+toDataBindingGroup (AcyclicSCC d) = return d
100−toDataBindingGroup (CyclicSCC [d]) = d
95+toDataBindingGroup (CyclicSCC [TypeSynonymDeclaration pn _ _]) = Left $ "Cycle in type synonym " ++ show pn
96+toDataBindingGroup (CyclicSCC [d]) = return d
101−toDataBindingGroup (CyclicSCC ds') = DataBindingGroupDeclaration $ map fromDataDecl ds'
97+toDataBindingGroup (CyclicSCC ds')
98+ | all isTypeSynonym ds' = Left "Cycle in type synonyms"
99+ | otherwise = return $ DataBindingGroupDeclaration ds'
101+ isTypeSynonym (TypeSynonymDeclaration _ _ _) = True
102+ isTypeSynonym _ = False
103fromValueDecl :: Declaration -> (Ident, Value)
104fromValueDecl :: Declaration -> (Ident, Value)
104fromValueDecl (ValueDeclaration ident [] Nothing val) = (ident, val)
105fromValueDecl (ValueDeclaration ident [] Nothing val) = (ident, val)
105fromValueDecl (ValueDeclaration _ _ _ _) = error "Binders should have been desugared"
106fromValueDecl (ValueDeclaration _ _ _ _) = error "Binders should have been desugared"
106fromValueDecl _ = error "Expected ValueDeclaration"
107fromValueDecl _ = error "Expected ValueDeclaration"
108−fromDataDecl :: Declaration -> (ProperName, [String], [(ProperName, Maybe Type)])
109−fromDataDecl (DataDeclaration pn args ctors) = (pn, args, ctors)
110−fromDataDecl _ = error "Expected DataDeclaration"