@@ -23,49 +23,51 @@ import Data.Data
2323import Data.Graph
2424import Data.Generics
2525import Data.List (nub, intersect)
26+import Control.Applicative ((<$>))
2627
2728import Language.PureScript.Declarations
2829import Language.PureScript.Names
2930import Language.PureScript.Values
3031import Language.PureScript.Types
32+import Debug.Trace (trace)
3133
32−createBindingGroupsModule :: [Module] -> [Module]
33−createBindingGroupsModule = map $ \(Module name ds) -> Module name (createBindingGroups ds)
34+createBindingGroupsModule :: [Module] -> Either String [Module]
35+createBindingGroupsModule = mapM $ \(Module name ds) -> Module name <$> createBindingGroups ds
3436
3537collapseBindingGroupsModule :: [Module] -> [Module]
3638collapseBindingGroupsModule = map $ \(Module name ds) -> Module name (collapseBindingGroups ds)
3739
38−createBindingGroups :: [Declaration] -> [Declaration]
39−createBindingGroups ds =
40− let
41− values = filter isValueDecl ds
42− dataDecls = filter isDataDecl ds
43− nonValues = filter (\d -> not (isValueDecl d) && not (isDataDecl d)) ds
44− allProperNames = map getProperName dataDecls
45− dataVerts = map (\d -> (d, getProperName d, usedProperNames d `intersect` allProperNames)) dataDecls
46− dataBindingGroupDecls = map toDataBindingGroup $ stronglyConnComp dataVerts
47− allIdents = map getIdent values
48− valueVerts = map (\d -> (d, getIdent d, usedIdents d `intersect` allIdents)) values
49− bindingGroupDecls = map toBindingGroup $ stronglyConnComp valueVerts
50− in
51− dataBindingGroupDecls ++ nonValues ++ bindingGroupDecls
40+createBindingGroups :: [Declaration] -> Either String [Declaration]
41+createBindingGroups ds = do
42+ let values = filter isValueDecl ds
43+ dataDecls = filter isDataDecl ds
44+ allProperNames = map getProperName dataDecls
45+ dataVerts = map (\d -> (d, getProperName d, usedProperNames d `intersect` allProperNames)) dataDecls
46+ dataBindingGroupDecls <- mapM toDataBindingGroup $ stronglyConnComp dataVerts
47+ let allIdents = map getIdent values
48+ valueVerts = map (\d -> (d, getIdent d, usedIdents d `intersect` allIdents)) values
49+ bindingGroupDecls = map toBindingGroup $ stronglyConnComp valueVerts
50+ return $ filter isImportDecl ds ++
51+ filter isExternDataDecl ds ++
52+ dataBindingGroupDecls ++
53+ filter isTypeClassDeclaration ds ++
54+ filter isFixityDecl ds ++
55+ filter isExternDecl ds ++
56+ bindingGroupDecls
5257
5358collapseBindingGroups :: [Declaration] -> [Declaration]
5459collapseBindingGroups ds = concatMap go ds
5560 where
56− go (DataBindingGroupDeclaration ds) = map (\(name, args, dctors) -> DataDeclaration name args dctors) ds
61+ go (DataBindingGroupDeclaration ds) = ds
5762 go (BindingGroupDeclaration ds) = map (\(ident, val) -> ValueDeclaration ident [] Nothing val) ds
5863 go other = [other]
5964
6065usedIdents :: (Data d) => d -> [Ident]
61−usedIdents = nub . everything (++) (mkQ [] namesV `extQ` namesS)
66+usedIdents = nub . everything (++) (mkQ [] names)
6267 where
63− namesV :: Value -> [Ident]
64− namesV (Var (Qualified Nothing name)) = [name]
65− namesV _ = []
66− namesS :: Statement -> [Ident]
67− namesS (VariableIntroduction name _) = [name]
68− namesS _ = []
68+ names :: Value -> [Ident]
69+ names (Var (Qualified Nothing name)) = [name]
70+ names _ = []
6971
7072usedProperNames :: (Data d) => d -> [ProperName]
7173usedProperNames = nub . everything (++) (mkQ [] names)
@@ -74,20 +76,13 @@ usedProperNames = nub . everything (++) (mkQ [] names)
7476 names (TypeConstructor (Qualified Nothing name)) = [name]
7577 names _ = []
7678
77−isValueDecl :: Declaration -> Bool
78−isValueDecl (ValueDeclaration _ _ _ _) = True
79−isValueDecl _ = False
80−
81−isDataDecl :: Declaration -> Bool
82−isDataDecl (DataDeclaration _ _ _) = True
83−isDataDecl _ = False
84−
8579getIdent :: Declaration -> Ident
8680getIdent (ValueDeclaration ident _ _ _) = ident
8781getIdent _ = error "Expected ValueDeclaration"
8882
8983getProperName :: Declaration -> ProperName
9084getProperName (DataDeclaration pn _ _) = pn
85+getProperName (TypeSynonymDeclaration pn _ _) = pn
9186getProperName _ = error "Expected DataDeclaration"
9287
9388toBindingGroup :: SCC Declaration -> Declaration
@@ -95,16 +90,18 @@ toBindingGroup (AcyclicSCC d) = d
9590toBindingGroup (CyclicSCC [d]) = d
9691toBindingGroup (CyclicSCC ds') = BindingGroupDeclaration $ map fromValueDecl ds'
9792
98−toDataBindingGroup :: SCC Declaration -> Declaration
99−toDataBindingGroup (AcyclicSCC d) = d
100−toDataBindingGroup (CyclicSCC [d]) = d
101−toDataBindingGroup (CyclicSCC ds') = DataBindingGroupDeclaration $ map fromDataDecl ds'
93+toDataBindingGroup :: SCC Declaration -> Either String Declaration
94+toDataBindingGroup (AcyclicSCC d) = return d
95+toDataBindingGroup (CyclicSCC [TypeSynonymDeclaration pn _ _]) = Left $ "Cycle in type synonym " ++ show pn
96+toDataBindingGroup (CyclicSCC [d]) = return d
97+toDataBindingGroup (CyclicSCC ds')
98+ | all isTypeSynonym ds' = Left "Cycle in type synonyms"
99+ | otherwise = return $ DataBindingGroupDeclaration ds'
100+ where
101+ isTypeSynonym (TypeSynonymDeclaration _ _ _) = True
102+ isTypeSynonym _ = False
102103
103104fromValueDecl :: Declaration -> (Ident, Value)
104105fromValueDecl (ValueDeclaration ident [] Nothing val) = (ident, val)
105106fromValueDecl (ValueDeclaration _ _ _ _) = error "Binders should have been desugared"
106107fromValueDecl _ = error "Expected ValueDeclaration"
107−
108−fromDataDecl :: Declaration -> (ProperName, [String], [(ProperName, Maybe Type)])
109−fromDataDecl (DataDeclaration pn args ctors) = (pn, args, ctors)
110−fromDataDecl _ = error "Expected DataDeclaration"