Switch to modules containing lists of ordered declarations, rather than just a list of declarations.

This commit is contained in:
2016-07-19 18:20:44 -07:00
parent c542476365
commit 6649b190ac
5 changed files with 48 additions and 42 deletions

View File

@@ -19,6 +19,7 @@ executable bang
base >= 4.7 && < 5.0, base >= 4.7 && < 5.0,
bytestring >= 0.10.6 && < 0.13, bytestring >= 0.10.6 && < 0.13,
containers >= 0.5.4 && < 0.8, containers >= 0.5.4 && < 0.8,
GraphSCC >= 1.0.4 && < 1.4,
lens >= 4.14 && < 4.16, lens >= 4.14 && < 4.16,
llvm-pretty >= 0.4.0.1 && < 0.8, llvm-pretty >= 0.4.0.1 && < 0.8,
optparse-applicative >= 0.12.1.0 && < 0.15, optparse-applicative >= 0.12.1.0 && < 0.15,

View File

@@ -21,10 +21,10 @@ import Text.PrettyPrint.Annotated(Doc, empty, text, (<+>), ($+$))
data Module = Module { data Module = Module {
_moduleName :: Name _moduleName :: Name
, _moduleDeclarations :: [Declaration] , _moduleDeclarations :: [[Declaration]]
} }
mkModule :: Name -> [Declaration] -> Module mkModule :: Name -> [[Declaration]] -> Module
mkModule = Module mkModule = Module
makeLenses ''Module makeLenses ''Module
@@ -34,9 +34,10 @@ ppModule m = text "module" <+> ppName (view moduleName m) $+$
dump (view moduleName m) (view moduleDeclarations m) dump (view moduleName m) (view moduleDeclarations m)
where where
dump _ [] = empty dump _ [] = empty
dump prev (x:rest) dump prev ([]:rest) = dump prev rest
dump prev ((x:rest):lr)
| prev == view declName x = | prev == view declName x =
ppDeclaration x $+$ dump prev rest ppDeclaration x $+$ dump prev (rest:lr)
| otherwise = | otherwise =
text "" $+$ dump (view declName x) (x:rest) text "" $+$ dump (view declName x) ((x:rest):lr)

View File

@@ -13,7 +13,6 @@ module Bang.AST.Declaration
, ppValueDeclaration , ppValueDeclaration
, mkValueDecl , mkValueDecl
, vdName, vdLocation , vdName, vdLocation
, vdFreeTypeVariables, vdFreeValueVariables
, vdDeclaredType, vdValue , vdDeclaredType, vdValue
) )
where where
@@ -22,10 +21,11 @@ import Bang.AST.Expression(Expression, ppExpression)
import Bang.AST.Name(Name, ppName) import Bang.AST.Name(Name, ppName)
import Bang.AST.Type(Type(TypePrim), ppType) import Bang.AST.Type(Type(TypePrim), ppType)
import Bang.Syntax.Location(Location) import Bang.Syntax.Location(Location)
import Bang.Utils.FreeVars(CanHaveFreeVars(..))
import Control.Lens(Lens', view, set, lens) import Control.Lens(Lens', view, set, lens)
import Control.Lens(makeLenses) import Control.Lens(makeLenses)
import Text.PrettyPrint.Annotated(Doc, text, (<+>), ($+$), (<>), empty) import Data.List(delete, union)
import Text.PrettyPrint.Annotated(braces, punctuate, comma, hsep, space) import Text.PrettyPrint.Annotated(Doc, text, (<+>), ($+$), (<>), empty, space)
data TypeDeclaration = TypeDeclaration data TypeDeclaration = TypeDeclaration
{ _tdName :: Name { _tdName :: Name
@@ -50,13 +50,14 @@ instance MkTypeDecl TypeDeclaration where
instance MkTypeDecl Declaration where instance MkTypeDecl Declaration where
mkTypeDecl n l t = DeclType (TypeDeclaration n l t) mkTypeDecl n l t = DeclType (TypeDeclaration n l t)
instance CanHaveFreeVars TypeDeclaration where
freeVariables td = delete (_tdName td) (freeVariables (_tdType td))
-- ----------------------------------------------------------------------------- -- -----------------------------------------------------------------------------
data ValueDeclaration = ValueDeclaration data ValueDeclaration = ValueDeclaration
{ _vdName :: Name { _vdName :: Name
, _vdLocation :: Location , _vdLocation :: Location
, _vdFreeTypeVariables :: [Name]
, _vdFreeValueVariables :: [Name]
, _vdDeclaredType :: Maybe Type , _vdDeclaredType :: Maybe Type
, _vdValue :: Expression , _vdValue :: Expression
} }
@@ -66,13 +67,8 @@ class MkValueDecl a where
mkValueDecl :: Name -> Location -> Maybe Type -> Expression -> a mkValueDecl :: Name -> Location -> Maybe Type -> Expression -> a
ppValueDeclaration :: ValueDeclaration -> Doc a ppValueDeclaration :: ValueDeclaration -> Doc a
ppValueDeclaration vd = frees $+$ typedecl $+$ valuedecl ppValueDeclaration vd = typedecl $+$ valuedecl
where where
frees =
text "free type variables: " <+>
braces (hsep (punctuate comma (map ppName (_vdFreeTypeVariables vd)))) $+$
text "free value variables: " <+>
braces (hsep (punctuate comma (map ppName (_vdFreeValueVariables vd))))
typedecl typedecl
| Just t <- _vdDeclaredType vd = | Just t <- _vdDeclaredType vd =
ppName (_vdName vd) <+> text "::" <+> ppType t ppName (_vdName vd) <+> text "::" <+> ppType t
@@ -80,10 +76,16 @@ ppValueDeclaration vd = frees $+$ typedecl $+$ valuedecl
valuedecl = ppName (_vdName vd) <+> text "=" <+> ppExpression (_vdValue vd) valuedecl = ppName (_vdName vd) <+> text "=" <+> ppExpression (_vdValue vd)
instance MkValueDecl ValueDeclaration where instance MkValueDecl ValueDeclaration where
mkValueDecl n l mt e = ValueDeclaration n l [] [] mt e mkValueDecl n l mt e = ValueDeclaration n l mt e
instance MkValueDecl Declaration where instance MkValueDecl Declaration where
mkValueDecl n l mt e = DeclVal (ValueDeclaration n l [] [] mt e) mkValueDecl n l mt e = DeclVal (ValueDeclaration n l mt e)
instance CanHaveFreeVars ValueDeclaration where
freeVariables vd = delete (_vdName vd) (union valTypes typeTypes)
where
valTypes = freeVariables (_vdValue vd)
typeTypes = freeVariables (_vdDeclaredType vd)
-- ----------------------------------------------------------------------------- -- -----------------------------------------------------------------------------
@@ -95,6 +97,10 @@ ppDeclaration :: Declaration -> Doc a
ppDeclaration (DeclType d) = ppTypeDeclaration d ppDeclaration (DeclType d) = ppTypeDeclaration d
ppDeclaration (DeclVal d) = ppValueDeclaration d ppDeclaration (DeclVal d) = ppValueDeclaration d
instance CanHaveFreeVars Declaration where
freeVariables (DeclType td) = freeVariables td
freeVariables (DeclVal vd) = freeVariables vd
makeLenses ''TypeDeclaration makeLenses ''TypeDeclaration
makeLenses ''ValueDeclaration makeLenses ''ValueDeclaration

View File

@@ -120,7 +120,7 @@ top_module :: { Module }
{% {%
do let Located src (TypeIdent rawName) = $2 do let Located src (TypeIdent rawName) = $2
name <- registerName False src ModuleEnv rawName name <- registerName False src ModuleEnv rawName
return (mkModule name $3) } return (mkModule name [$3]) }
Declaration :: { Maybe Declaration } Declaration :: { Maybe Declaration }
: ValueDeclaration { Just $1 } : ValueDeclaration { Just $1 }

View File

@@ -7,16 +7,17 @@ import Bang.AST(Name, Module, moduleDeclarations, ppName)
import Bang.AST.Declaration(Declaration(..), declName, import Bang.AST.Declaration(Declaration(..), declName,
ValueDeclaration, ValueDeclaration,
vdName, vdLocation, vdDeclaredType, vdName, vdLocation, vdDeclaredType,
vdFreeTypeVariables, vdValue)
vdValue, vdFreeValueVariables)
import Bang.AST.Expression(isEmptyExpression) import Bang.AST.Expression(isEmptyExpression)
import Bang.AST.Type(Type) import Bang.AST.Type(Type)
import Bang.Monad(Compiler, BangError(..), err) import Bang.Monad(Compiler, BangError(..), err)
import Bang.Syntax.Location(Location, ppLocation) import Bang.Syntax.Location(Location, ppLocation)
import Bang.Utils.FreeVars(CanHaveFreeVars(..)) import Bang.Utils.FreeVars(CanHaveFreeVars(..))
import Bang.Utils.Pretty(BangDoc) import Bang.Utils.Pretty(BangDoc)
import Control.Lens(view, set, over) import Control.Lens(view, set)
import Control.Monad(foldM) import Control.Monad(foldM)
import Data.Graph(SCC(..))
import Data.Graph.SCC(stronglyConnComp)
import Data.Map.Strict(Map) import Data.Map.Strict(Map)
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import Text.PrettyPrint.Annotated(text, ($+$), (<+>), nest) import Text.PrettyPrint.Annotated(text, ($+$), (<+>), nest)
@@ -43,16 +44,17 @@ prettyError e =
runPostProcessor :: Module -> Compiler ps Module runPostProcessor :: Module -> Compiler ps Module
runPostProcessor mdl = runPostProcessor mdl =
do declTable <- makeDeclarationTable mdl do let decls = concat (view moduleDeclarations mdl)
mdl' <- combineTypeValueDeclarations declTable mdl declTable <- makeDeclarationTable decls
return (addFreeVarsToDecls mdl') decls' <- combineTypeValueDeclarations declTable decls
return (set moduleDeclarations (orderDecls decls') mdl)
-- ----------------------------------------------------------------------------- -- -----------------------------------------------------------------------------
type DeclarationTable = Map Name (Maybe (Type, Location), Maybe ValueDeclaration) type DeclarationTable = Map Name (Maybe (Type, Location), Maybe ValueDeclaration)
makeDeclarationTable :: Module -> Compiler ps DeclarationTable makeDeclarationTable :: [Declaration] -> Compiler ps DeclarationTable
makeDeclarationTable m = foldM combine Map.empty (view moduleDeclarations m) makeDeclarationTable decls = foldM combine Map.empty decls
where where
combine table d = combine table d =
do let name = view declName d do let name = view declName d
@@ -87,11 +89,10 @@ makeDeclarationTable m = foldM combine Map.empty (view moduleDeclarations m)
-- ----------------------------------------------------------------------------- -- -----------------------------------------------------------------------------
combineTypeValueDeclarations :: DeclarationTable -> Module -> Compiler ps Module combineTypeValueDeclarations :: DeclarationTable ->
combineTypeValueDeclarations table m = [Declaration] ->
do let decls = view moduleDeclarations m Compiler ps [Declaration]
decls' <- process decls combineTypeValueDeclarations table decls = process decls
return (set moduleDeclarations decls' m)
where where
process [] = return [] process [] = return []
process (x:rest) = process (x:rest) =
@@ -113,14 +114,11 @@ combineTypeValueDeclarations table m =
-- ----------------------------------------------------------------------------- -- -----------------------------------------------------------------------------
addFreeVarsToDecls :: Module -> Module orderDecls :: [Declaration] -> [[Declaration]]
addFreeVarsToDecls = over moduleDeclarations (map process) orderDecls decls = map unSCC (stronglyConnComp nodes)
where where
process (DeclVal vd) = unSCC (AcyclicSCC x) = [x]
let dtype = view vdDeclaredType vd unSCC (CyclicSCC xs) = xs
dval = view vdValue vd --
in DeclVal (set vdFreeTypeVariables (freeVariables dtype) $ nodes = map tuplify decls
set vdFreeValueVariables (freeVariables dval) vd) tuplify d = (d, view declName d, freeVariables d)
process x = x