packages feed

ddc-build 0.4.1.3 → 0.4.2.1

raw patch · 24 files changed

+1486/−365 lines, 24 filesdep +ddc-core-babeldep +timedep −ddc-core-evaldep ~basedep ~ddc-basedep ~ddc-corePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: ddc-core-babel, time

Dependencies removed: ddc-core-eval

Dependency ranges changed: base, ddc-base, ddc-core, ddc-core-flow, ddc-core-llvm, ddc-core-salt, ddc-core-simpl, ddc-core-tetra, ddc-source-tetra, deepseq, filepath, mtl

API changes (from Hackage documentation)

- DDC.Build.Builder: buildAs :: Builder -> FilePath -> FilePath -> IO ()
- DDC.Build.Builder: buildBaseLibDir :: Builder -> FilePath
- DDC.Build.Builder: buildBaseSrcDir :: Builder -> FilePath
- DDC.Build.Builder: buildCC :: Builder -> FilePath -> FilePath -> IO ()
- DDC.Build.Builder: buildHost :: Builder -> Platform
- DDC.Build.Builder: buildLdExe :: Builder -> FilePath -> FilePath -> IO ()
- DDC.Build.Builder: buildLdLibShared :: Builder -> [FilePath] -> FilePath -> IO ()
- DDC.Build.Builder: buildLdLibStatic :: Builder -> [FilePath] -> FilePath -> IO ()
- DDC.Build.Builder: buildLlc :: Builder -> FilePath -> FilePath -> IO ()
- DDC.Build.Builder: buildSpec :: Builder -> Platform
- DDC.Build.Builder: buildTarget :: Builder -> Platform
- DDC.Build.Builder: builderConfigBaseLibDir :: BuilderConfig -> FilePath
- DDC.Build.Builder: builderConfigBaseSrcDir :: BuilderConfig -> FilePath
- DDC.Build.Builder: builderName :: Builder -> String
- DDC.Build.Builder: instance Eq BuilderResult
- DDC.Build.Builder: instance Pretty Builder
- DDC.Build.Builder: instance Show Builder
- DDC.Build.Builder: instance Show BuilderResult
- DDC.Build.Language: bundleFragment :: Bundle s n err -> Fragment n err
- DDC.Build.Language: bundleMakeNamifierT :: Bundle s n err -> Env n -> Namifier s n
- DDC.Build.Language: bundleMakeNamifierX :: Bundle s n err -> Env n -> Namifier s n
- DDC.Build.Language: bundleModules :: Bundle s n err -> Map ModuleName (Module (AnTEC () n) n)
- DDC.Build.Language: bundleRewriteRules :: Bundle s n err -> Map String (RewriteRule (AnTEC () n) n)
- DDC.Build.Language: bundleSimplifier :: Bundle s n err -> Simplifier s (AnTEC () n) n
- DDC.Build.Language: bundleStateInit :: Bundle s n err -> s
- DDC.Build.Language: fragmentCheckExp :: Fragment n -> forall a. Exp a n -> Maybe (err a)
- DDC.Build.Language: fragmentCheckModule :: Fragment n -> forall a. Module a n -> Maybe (err a)
- DDC.Build.Language: fragmentExtension :: Fragment n -> String
- DDC.Build.Language: fragmentLexExp :: Fragment n -> String -> Int -> String -> [Token (Tok n)]
- DDC.Build.Language: fragmentLexModule :: Fragment n -> String -> Int -> String -> [Token (Tok n)]
- DDC.Build.Language: fragmentProfile :: Fragment n -> Profile n
- DDC.Build.Language: fragmentReadName :: Fragment n -> String -> Maybe n
- DDC.Build.Language.Eval: bundle :: Bundle Int Name Error
- DDC.Build.Language.Eval: fragment :: Fragment Name Error
- DDC.Build.Language.Eval: language :: Language
- DDC.Build.Language.Eval: profile :: Profile Name
- DDC.Build.Language.Flow: instance Pretty (Error a)
- DDC.Build.Language.Flow: instance Show (Error a)
- DDC.Build.Language.Lite: bundle :: Bundle Int Name Error
- DDC.Build.Language.Lite: fragment :: Fragment Name Error
- DDC.Build.Language.Lite: freshT :: Env Name -> Bind Name -> State Int Name
- DDC.Build.Language.Lite: freshX :: Env Name -> Bind Name -> State Int Name
- DDC.Build.Language.Lite: language :: Language
- DDC.Build.Language.Zero: instance Eq Name
- DDC.Build.Language.Zero: instance NFData Name
- DDC.Build.Language.Zero: instance Ord Name
- DDC.Build.Language.Zero: instance Pretty (Error a)
- DDC.Build.Language.Zero: instance Pretty Name
- DDC.Build.Language.Zero: instance Show (Error a)
- DDC.Build.Language.Zero: instance Show Name
- DDC.Build.Language.Zero: instance Typeable Name
- DDC.Build.Pipeline: ErrorLiteConvert :: !err -> Error
- DDC.Build.Pipeline: PipeCoreAsLite :: ![PipeLite] -> PipeCore (AnTEC () Name) Name
- DDC.Build.Pipeline: PipeLiteOutput :: !Sink -> PipeLite
- DDC.Build.Pipeline: PipeLiteToSalt :: !Platform -> !Config -> ![PipeCore () Name] -> PipeLite
- DDC.Build.Pipeline: data PipeLite
- DDC.Build.Pipeline: pipeBuilder :: PipeLlvm -> Builder
- DDC.Build.Pipeline: pipeFileAsm :: PipeLlvm -> FilePath
- DDC.Build.Pipeline: pipeFileExe :: PipeLlvm -> Maybe FilePath
- DDC.Build.Pipeline: pipeFileLlvm :: PipeLlvm -> FilePath
- DDC.Build.Pipeline: pipeFileObject :: PipeLlvm -> FilePath
- DDC.Build.Pipeline: pipeKeepAsmFiles :: PipeLlvm -> Bool
- DDC.Build.Pipeline: pipeKeepLlvmFiles :: PipeLlvm -> Bool
- DDC.Build.Pipeline: pipeLite :: Module (AnTEC () Name) Name -> PipeLite -> IO [Error]
- DDC.Build.Pipeline.Core: PipeCoreAsLite :: ![PipeLite] -> PipeCore (AnTEC () Name) Name
- DDC.Build.Pipeline.Core: PipeLiteOutput :: !Sink -> PipeLite
- DDC.Build.Pipeline.Core: PipeLiteToSalt :: !Platform -> !Config -> ![PipeCore () Name] -> PipeLite
- DDC.Build.Pipeline.Core: data PipeLite
- DDC.Build.Pipeline.Core: pipeLite :: Module (AnTEC () Name) Name -> PipeLite -> IO [Error]
- DDC.Build.Pipeline.Error: ErrorLiteConvert :: !err -> Error
- DDC.Build.Pipeline.Error: instance NFData Error
- DDC.Build.Pipeline.Error: instance Pretty Error
- DDC.Build.Pipeline.Llvm: instance Show PipeLlvm
- DDC.Build.Pipeline.Llvm: pipeBuilder :: PipeLlvm -> Builder
- DDC.Build.Pipeline.Llvm: pipeFileAsm :: PipeLlvm -> FilePath
- DDC.Build.Pipeline.Llvm: pipeFileExe :: PipeLlvm -> Maybe FilePath
- DDC.Build.Pipeline.Llvm: pipeFileLlvm :: PipeLlvm -> FilePath
- DDC.Build.Pipeline.Llvm: pipeFileObject :: PipeLlvm -> FilePath
- DDC.Build.Pipeline.Llvm: pipeKeepAsmFiles :: PipeLlvm -> Bool
- DDC.Build.Pipeline.Llvm: pipeKeepLlvmFiles :: PipeLlvm -> Bool
- DDC.Build.Pipeline.Salt: instance Show a => Show (PipeSalt a)
- DDC.Build.Pipeline.Sink: instance Show Sink
- DDC.Build.Platform: instance Eq Arch
- DDC.Build.Platform: instance Eq Os
- DDC.Build.Platform: instance Eq Platform
- DDC.Build.Platform: instance Pretty Arch
- DDC.Build.Platform: instance Pretty Os
- DDC.Build.Platform: instance Pretty Platform
- DDC.Build.Platform: instance Show Arch
- DDC.Build.Platform: instance Show Os
- DDC.Build.Platform: instance Show Platform
- DDC.Build.Platform: platformArch :: Platform -> Arch
- DDC.Build.Platform: platformOs :: Platform -> Os
+ DDC.Build.Builder: [buildAs] :: Builder -> FilePath -> FilePath -> IO ()
+ DDC.Build.Builder: [buildBaseLibDir] :: Builder -> FilePath
+ DDC.Build.Builder: [buildBaseSrcDir] :: Builder -> FilePath
+ DDC.Build.Builder: [buildCC] :: Builder -> FilePath -> FilePath -> IO ()
+ DDC.Build.Builder: [buildHost] :: Builder -> Platform
+ DDC.Build.Builder: [buildLdExe] :: Builder -> [FilePath] -> FilePath -> IO ()
+ DDC.Build.Builder: [buildLdLibShared] :: Builder -> [FilePath] -> FilePath -> IO ()
+ DDC.Build.Builder: [buildLdLibStatic] :: Builder -> [FilePath] -> FilePath -> IO ()
+ DDC.Build.Builder: [buildLlc] :: Builder -> FilePath -> FilePath -> IO ()
+ DDC.Build.Builder: [buildSpec] :: Builder -> Platform
+ DDC.Build.Builder: [buildTarget] :: Builder -> Platform
+ DDC.Build.Builder: [builderConfigBaseLibDir] :: BuilderConfig -> FilePath
+ DDC.Build.Builder: [builderConfigBaseSrcDir] :: BuilderConfig -> FilePath
+ DDC.Build.Builder: [builderConfigLibFile] :: BuilderConfig -> FilePath -> FilePath -> FilePath
+ DDC.Build.Builder: [builderName] :: Builder -> String
+ DDC.Build.Builder: instance DDC.Base.Pretty.Pretty DDC.Build.Builder.Builder
+ DDC.Build.Builder: instance GHC.Classes.Eq DDC.Build.Builder.BuilderResult
+ DDC.Build.Builder: instance GHC.Show.Show DDC.Build.Builder.Builder
+ DDC.Build.Builder: instance GHC.Show.Show DDC.Build.Builder.BuilderResult
+ DDC.Build.Interface.Base: Interface :: FilePath -> UTCTime -> String -> ModuleName -> Maybe (Module ta Name) -> Maybe (Module sa Name) -> Interface ta sa
+ DDC.Build.Interface.Base: [interfaceFilePath] :: Interface ta sa -> FilePath
+ DDC.Build.Interface.Base: [interfaceModuleName] :: Interface ta sa -> ModuleName
+ DDC.Build.Interface.Base: [interfaceSaltModule] :: Interface ta sa -> Maybe (Module sa Name)
+ DDC.Build.Interface.Base: [interfaceTetraModule] :: Interface ta sa -> Maybe (Module ta Name)
+ DDC.Build.Interface.Base: [interfaceTimeStamp] :: Interface ta sa -> UTCTime
+ DDC.Build.Interface.Base: [interfaceVersion] :: Interface ta sa -> String
+ DDC.Build.Interface.Base: data Interface ta sa
+ DDC.Build.Interface.Base: instance DDC.Base.Pretty.Pretty (DDC.Build.Interface.Base.Interface ta sa)
+ DDC.Build.Interface.Base: isInterfaceTearLine :: String -> Bool
+ DDC.Build.Interface.Base: makeInterfaceTearLine :: String -> String
+ DDC.Build.Interface.Base: takeInterfaceTearLine :: String -> Maybe String
+ DDC.Build.Interface.Load: ErrorBadMagic :: FilePath -> Int -> Error
+ DDC.Build.Interface.Load: ErrorDuplicate :: Error
+ DDC.Build.Interface.Load: ErrorEmpty :: Error
+ DDC.Build.Interface.Load: ErrorLoadSalt :: (Error Name Error) -> Error
+ DDC.Build.Interface.Load: ErrorLoadTetra :: (Error Name Error) -> Error
+ DDC.Build.Interface.Load: ErrorNoMeta :: Error
+ DDC.Build.Interface.Load: ErrorParse :: FilePath -> Int -> Error
+ DDC.Build.Interface.Load: ErrorParseEnd :: Error
+ DDC.Build.Interface.Load: [errorFilePath] :: Error -> FilePath
+ DDC.Build.Interface.Load: [errorLine] :: Error -> Int
+ DDC.Build.Interface.Load: data Error
+ DDC.Build.Interface.Load: instance DDC.Base.Pretty.Pretty DDC.Build.Interface.Load.Error
+ DDC.Build.Interface.Load: instance GHC.Show.Show DDC.Build.Interface.Load.Component
+ DDC.Build.Interface.Load: loadInterface :: FilePath -> UTCTime -> String -> Either Error InterfaceAA
+ DDC.Build.Interface.Load: type InterfaceAA = Interface (AnTEC SourcePos Name) ()
+ DDC.Build.Interface.Store: Meta :: FilePath -> UTCTime -> ModuleName -> Meta
+ DDC.Build.Interface.Store: Super :: Name -> ModuleName -> Type Name -> Type Name -> ImportValue Name -> Super
+ DDC.Build.Interface.Store: [metaFilePath] :: Meta -> FilePath
+ DDC.Build.Interface.Store: [metaModuleName] :: Meta -> ModuleName
+ DDC.Build.Interface.Store: [metaTimeStamp] :: Meta -> UTCTime
+ DDC.Build.Interface.Store: [superImportValue] :: Super -> ImportValue Name
+ DDC.Build.Interface.Store: [superModuleName] :: Super -> ModuleName
+ DDC.Build.Interface.Store: [superName] :: Super -> Name
+ DDC.Build.Interface.Store: [superSaltType] :: Super -> Type Name
+ DDC.Build.Interface.Store: [superTetraType] :: Super -> Type Name
+ DDC.Build.Interface.Store: data Meta
+ DDC.Build.Interface.Store: data Store
+ DDC.Build.Interface.Store: data Super
+ DDC.Build.Interface.Store: findSuper :: Store -> Name -> [ModuleName] -> IO [Super]
+ DDC.Build.Interface.Store: getInterfaces :: Store -> IO [InterfaceAA]
+ DDC.Build.Interface.Store: getMeta :: Store -> IO [Meta]
+ DDC.Build.Interface.Store: getModuleNames :: Store -> IO [ModuleName]
+ DDC.Build.Interface.Store: instance DDC.Base.Pretty.Pretty DDC.Build.Interface.Store.Meta
+ DDC.Build.Interface.Store: instance GHC.Show.Show DDC.Build.Interface.Store.Meta
+ DDC.Build.Interface.Store: load :: FilePath -> IO (Either Error InterfaceAA)
+ DDC.Build.Interface.Store: new :: IO Store
+ DDC.Build.Interface.Store: wrap :: Store -> InterfaceAA -> IO ()
+ DDC.Build.Language: [bundleFragment] :: Bundle s n err -> Fragment n err
+ DDC.Build.Language: [bundleMakeNamifierT] :: Bundle s n err -> Env n -> Namifier s n
+ DDC.Build.Language: [bundleMakeNamifierX] :: Bundle s n err -> Env n -> Namifier s n
+ DDC.Build.Language: [bundleModules] :: Bundle s n err -> Map ModuleName (Module (AnTEC () n) n)
+ DDC.Build.Language: [bundleRewriteRules] :: Bundle s n err -> Map String (RewriteRule (AnTEC () n) n)
+ DDC.Build.Language: [bundleSimplifier] :: Bundle s n err -> Simplifier s (AnTEC () n) n
+ DDC.Build.Language: [bundleStateInit] :: Bundle s n err -> s
+ DDC.Build.Language: [fragmentCheckExp] :: Fragment n -> forall a. Exp a n -> Maybe (err a)
+ DDC.Build.Language: [fragmentCheckModule] :: Fragment n -> forall a. Module a n -> Maybe (err a)
+ DDC.Build.Language: [fragmentExtension] :: Fragment n -> String
+ DDC.Build.Language: [fragmentLexExp] :: Fragment n -> String -> Int -> String -> [Token (Tok n)]
+ DDC.Build.Language: [fragmentLexModule] :: Fragment n -> String -> Int -> String -> [Token (Tok n)]
+ DDC.Build.Language: [fragmentProfile] :: Fragment n -> Profile n
+ DDC.Build.Language: [fragmentReadName] :: Fragment n -> String -> Maybe n
+ DDC.Build.Language.Flow: instance DDC.Base.Pretty.Pretty (DDC.Build.Language.Flow.Error a)
+ DDC.Build.Language.Flow: instance GHC.Show.Show (DDC.Build.Language.Flow.Error a)
+ DDC.Build.Language.Zero: instance Control.DeepSeq.NFData DDC.Build.Language.Zero.Name
+ DDC.Build.Language.Zero: instance DDC.Base.Name.CompoundName DDC.Build.Language.Zero.Name
+ DDC.Build.Language.Zero: instance DDC.Base.Pretty.Pretty (DDC.Build.Language.Zero.Error a)
+ DDC.Build.Language.Zero: instance DDC.Base.Pretty.Pretty DDC.Build.Language.Zero.Name
+ DDC.Build.Language.Zero: instance GHC.Classes.Eq DDC.Build.Language.Zero.Name
+ DDC.Build.Language.Zero: instance GHC.Classes.Ord DDC.Build.Language.Zero.Name
+ DDC.Build.Language.Zero: instance GHC.Show.Show (DDC.Build.Language.Zero.Error a)
+ DDC.Build.Language.Zero: instance GHC.Show.Show DDC.Build.Language.Zero.Name
+ DDC.Build.Pipeline: ErrorFlowConvert :: !err -> Error
+ DDC.Build.Pipeline: PipeFlowToTetra :: [PipeCore () Name] -> PipeFlow (AnTEC () Name)
+ DDC.Build.Pipeline: PipeTetraCurry :: ![PipeCore () Name] -> PipeTetra (AnTEC a Name)
+ DDC.Build.Pipeline: PipeTetraToPHP :: !Sink -> PipeTetra a
+ DDC.Build.Pipeline: [pipeBuilder] :: PipeLlvm -> Builder
+ DDC.Build.Pipeline: [pipeFileAsm] :: PipeLlvm -> FilePath
+ DDC.Build.Pipeline: [pipeFileExe] :: PipeLlvm -> Maybe FilePath
+ DDC.Build.Pipeline: [pipeFileLlvm] :: PipeLlvm -> FilePath
+ DDC.Build.Pipeline: [pipeFileObject] :: PipeLlvm -> FilePath
+ DDC.Build.Pipeline: [pipeKeepAsmFiles] :: PipeLlvm -> Bool
+ DDC.Build.Pipeline: [pipeKeepLlvmFiles] :: PipeLlvm -> Bool
+ DDC.Build.Pipeline: [pipeLinkOtherObjects] :: PipeLlvm -> [FilePath]
+ DDC.Build.Pipeline.Core: PipeFlowToTetra :: [PipeCore () Name] -> PipeFlow (AnTEC () Name)
+ DDC.Build.Pipeline.Core: PipeTetraCurry :: ![PipeCore () Name] -> PipeTetra (AnTEC a Name)
+ DDC.Build.Pipeline.Core: PipeTetraToPHP :: !Sink -> PipeTetra a
+ DDC.Build.Pipeline.Error: ErrorFlowConvert :: !err -> Error
+ DDC.Build.Pipeline.Error: instance Control.DeepSeq.NFData DDC.Build.Pipeline.Error.Error
+ DDC.Build.Pipeline.Error: instance DDC.Base.Pretty.Pretty DDC.Build.Pipeline.Error.Error
+ DDC.Build.Pipeline.Llvm: [pipeBuilder] :: PipeLlvm -> Builder
+ DDC.Build.Pipeline.Llvm: [pipeFileAsm] :: PipeLlvm -> FilePath
+ DDC.Build.Pipeline.Llvm: [pipeFileExe] :: PipeLlvm -> Maybe FilePath
+ DDC.Build.Pipeline.Llvm: [pipeFileLlvm] :: PipeLlvm -> FilePath
+ DDC.Build.Pipeline.Llvm: [pipeFileObject] :: PipeLlvm -> FilePath
+ DDC.Build.Pipeline.Llvm: [pipeKeepAsmFiles] :: PipeLlvm -> Bool
+ DDC.Build.Pipeline.Llvm: [pipeKeepLlvmFiles] :: PipeLlvm -> Bool
+ DDC.Build.Pipeline.Llvm: [pipeLinkOtherObjects] :: PipeLlvm -> [FilePath]
+ DDC.Build.Pipeline.Llvm: instance GHC.Show.Show DDC.Build.Pipeline.Llvm.PipeLlvm
+ DDC.Build.Pipeline.Salt: instance GHC.Show.Show a => GHC.Show.Show (DDC.Build.Pipeline.Salt.PipeSalt a)
+ DDC.Build.Pipeline.Sink: instance GHC.Show.Show DDC.Build.Pipeline.Sink.Sink
+ DDC.Build.Platform: [platformArch] :: Platform -> Arch
+ DDC.Build.Platform: [platformOs] :: Platform -> Os
+ DDC.Build.Platform: instance DDC.Base.Pretty.Pretty DDC.Build.Platform.Arch
+ DDC.Build.Platform: instance DDC.Base.Pretty.Pretty DDC.Build.Platform.Os
+ DDC.Build.Platform: instance DDC.Base.Pretty.Pretty DDC.Build.Platform.Platform
+ DDC.Build.Platform: instance GHC.Classes.Eq DDC.Build.Platform.Arch
+ DDC.Build.Platform: instance GHC.Classes.Eq DDC.Build.Platform.Os
+ DDC.Build.Platform: instance GHC.Classes.Eq DDC.Build.Platform.Platform
+ DDC.Build.Platform: instance GHC.Show.Show DDC.Build.Platform.Arch
+ DDC.Build.Platform: instance GHC.Show.Show DDC.Build.Platform.Os
+ DDC.Build.Platform: instance GHC.Show.Show DDC.Build.Platform.Platform
+ DDC.Build.Spec: Spec :: String -> [Component] -> Spec
+ DDC.Build.Spec: SpecExecutable :: String -> ModuleName -> [ModuleName] -> [(String, String)] -> Component
+ DDC.Build.Spec: SpecLibrary :: String -> String -> [ModuleName] -> [(String, String)] -> Component
+ DDC.Build.Spec: [specComponents] :: Spec -> [Component]
+ DDC.Build.Spec: [specExecutableMeta] :: Component -> [(String, String)]
+ DDC.Build.Spec: [specExecutableName] :: Component -> String
+ DDC.Build.Spec: [specExecutableTetraMain] :: Component -> ModuleName
+ DDC.Build.Spec: [specExecutableTetraOther] :: Component -> [ModuleName]
+ DDC.Build.Spec: [specLibraryMeta] :: Component -> [(String, String)]
+ DDC.Build.Spec: [specLibraryName] :: Component -> String
+ DDC.Build.Spec: [specLibraryTetraModules] :: Component -> [ModuleName]
+ DDC.Build.Spec: [specLibraryVersion] :: Component -> String
+ DDC.Build.Spec: [specVersion] :: Spec -> String
+ DDC.Build.Spec: data Component
+ DDC.Build.Spec: data Spec
+ DDC.Build.Spec: specFieldsLibrary :: [(String, Bool)]
+ DDC.Build.Spec.Check: ErrorUnrecognisedField :: String -> String -> Error
+ DDC.Build.Spec.Check: [errorField] :: Error -> String
+ DDC.Build.Spec.Check: [errorValue] :: Error -> String
+ DDC.Build.Spec.Check: data Error
+ DDC.Build.Spec.Check: instance GHC.Show.Show DDC.Build.Spec.Check.Error
+ DDC.Build.Spec.Parser: ErrorEmpty :: FilePath -> Error
+ DDC.Build.Spec.Parser: ErrorMissingField :: FilePath -> String -> Error
+ DDC.Build.Spec.Parser: ErrorParse :: FilePath -> Int -> Error
+ DDC.Build.Spec.Parser: [errorFilePath] :: Error -> FilePath
+ DDC.Build.Spec.Parser: [errorLine] :: Error -> Int
+ DDC.Build.Spec.Parser: [errorMissing] :: Error -> String
+ DDC.Build.Spec.Parser: data Error
+ DDC.Build.Spec.Parser: instance DDC.Base.Pretty.Pretty DDC.Build.Spec.Parser.Error
+ DDC.Build.Spec.Parser: instance GHC.Show.Show DDC.Build.Spec.Parser.Error
+ DDC.Build.Spec.Parser: parseBuildSpec :: FilePath -> String -> Either Error Spec
- DDC.Build.Builder: Builder :: String -> Platform -> Platform -> Platform -> FilePath -> FilePath -> (FilePath -> FilePath -> IO ()) -> (FilePath -> FilePath -> IO ()) -> (FilePath -> FilePath -> IO ()) -> (FilePath -> FilePath -> IO ()) -> ([FilePath] -> FilePath -> IO ()) -> ([FilePath] -> FilePath -> IO ()) -> Builder
+ DDC.Build.Builder: Builder :: String -> Platform -> Platform -> Platform -> FilePath -> FilePath -> (FilePath -> FilePath -> IO ()) -> (FilePath -> FilePath -> IO ()) -> (FilePath -> FilePath -> IO ()) -> ([FilePath] -> FilePath -> IO ()) -> ([FilePath] -> FilePath -> IO ()) -> ([FilePath] -> FilePath -> IO ()) -> Builder
- DDC.Build.Builder: BuilderConfig :: FilePath -> FilePath -> BuilderConfig
+ DDC.Build.Builder: BuilderConfig :: FilePath -> FilePath -> (FilePath -> FilePath -> FilePath) -> BuilderConfig
- DDC.Build.Pipeline: PipeCoreAsTetra :: ![PipeTetra (AnTEC a Name)] -> PipeCore (AnTEC a Name) Name
+ DDC.Build.Pipeline: PipeCoreAsTetra :: ![PipeTetra a] -> PipeCore a Name
- DDC.Build.Pipeline: PipeLlvmCompile :: Builder -> FilePath -> FilePath -> FilePath -> Maybe FilePath -> Bool -> Bool -> PipeLlvm
+ DDC.Build.Pipeline: PipeLlvmCompile :: Builder -> FilePath -> FilePath -> FilePath -> Maybe FilePath -> [FilePath] -> Bool -> Bool -> PipeLlvm
- DDC.Build.Pipeline: PipeTextLoadSourceTetra :: !Sink -> !Sink -> !Sink -> ![PipeCore (AnTEC SourcePos Name) Name] -> PipeText n err
+ DDC.Build.Pipeline: PipeTextLoadSourceTetra :: !Sink -> !Sink -> !Sink -> !Sink -> !Sink -> !Store -> ![PipeCore (AnTEC SourcePos Name) Name] -> PipeText n err
- DDC.Build.Pipeline.Core: PipeCoreAsTetra :: ![PipeTetra (AnTEC a Name)] -> PipeCore (AnTEC a Name) Name
+ DDC.Build.Pipeline.Core: PipeCoreAsTetra :: ![PipeTetra a] -> PipeCore a Name
- DDC.Build.Pipeline.Llvm: PipeLlvmCompile :: Builder -> FilePath -> FilePath -> FilePath -> Maybe FilePath -> Bool -> Bool -> PipeLlvm
+ DDC.Build.Pipeline.Llvm: PipeLlvmCompile :: Builder -> FilePath -> FilePath -> FilePath -> Maybe FilePath -> [FilePath] -> Bool -> Bool -> PipeLlvm
- DDC.Build.Pipeline.Text: PipeTextLoadSourceTetra :: !Sink -> !Sink -> !Sink -> ![PipeCore (AnTEC SourcePos Name) Name] -> PipeText n err
+ DDC.Build.Pipeline.Text: PipeTextLoadSourceTetra :: !Sink -> !Sink -> !Sink -> !Sink -> !Sink -> !Store -> ![PipeCore (AnTEC SourcePos Name) Name] -> PipeText n err

Files

DDC/Build/Builder.hs view
@@ -9,11 +9,13 @@ where import DDC.Build.Platform import DDC.Base.Pretty                          hiding ((</>))+import Data.List import System.FilePath                         -import System.Exit+import System.Exit                              hiding (die) import System.Process import qualified DDC.Core.Salt.Platform         as Llvm + -- | Configuration information for a builder that is not platform specific. data BuilderConfig         = BuilderConfig@@ -23,9 +25,12 @@            -- | Directory that holds the shared objects for the runtime           --   system and base library.-        , builderConfigBaseLibDir       :: FilePath }+        , builderConfigBaseLibDir       :: FilePath +          -- | Runtime library link with.+        , builderConfigLibFile          :: FilePath -> FilePath -> FilePath } + -- | Actions to use to invoke external compilation tools. data Builder         = Builder@@ -63,7 +68,7 @@         , buildAs               :: FilePath -> FilePath -> IO ()            -- | Link an executable.-        , buildLdExe            :: FilePath -> FilePath -> IO () +        , buildLdExe            :: [FilePath] -> FilePath -> IO ()             -- | Link a static library.         , buildLdLibStatic      :: [FilePath] -> FilePath -> IO ()@@ -175,19 +180,18 @@         , buildBaseSrcDir       = builderConfigBaseSrcDir config         , buildBaseLibDir       = builderConfigBaseLibDir config -        -- Use -disable-cfi to disable Call Frame Identification (CFI) directives-        -- because the OSX system assembler doesn't support them.         , buildLlc                     = \llFile sFile                 -> doCmd "LLVM compiler"        [(2, BuilderCanceled)]-                [ "llc -O3 -march=x86 -relocation-model=pic -disable-cfi" -                ,       llFile +                [ "opt -O3"+                , llFile+                , "| llc -O3 -march=x86 -relocation-model=pic"                 , "-o", sFile ]          , buildCC                 = \cFile oFile                 -> doCmd "C compiler"           [(2, BuilderCanceled)]-                [ "gcc -Werror -std=c99 -O3 -m32"+                [ "cc -Werror -std=c99 -O3 -m32"                 , "-c", cFile                 , "-o", oFile                 , "-I" ++ builderConfigBaseSrcDir config </> "sea/runtime"@@ -196,17 +200,20 @@         , buildAs                 = \sFile oFile                 -> doCmd "assembler"            [(2, BuilderCanceled)]-                [ "as -arch i386"  +                [ "llvm-mc -arch x86 -filetype=obj"                   , "-o", oFile                 ,       sFile ]          , buildLdExe-                = \oFile binFile+                = \oFiles binFile                 -> doCmd "linker"               [(2, BuilderCanceled)]-                [ "gcc -m32" +                [ "cc -m32 -Wl,-dead_strip"                  , "-o", binFile-                , oFile-                , builderConfigBaseLibDir config </> "libddc-runtime.dylib" ]+                , intercalate " " oFiles+                , builderConfigBaseLibDir config+                        </> builderConfigLibFile config+                                "libddc-runtime.a"+                                "libddc-runtime.dylib" ]          , buildLdLibStatic                 = \oFiles libFile@@ -216,7 +223,7 @@         , buildLdLibShared                 = \oFiles libFile                 -> doCmd "linker"               [(2, BuilderCanceled)]-                $ [ "gcc -m32 -dynamiclib -undefined dynamic_lookup"+                $ [ "cc -m32 -dynamiclib -undefined dynamic_lookup"                   , "-o", libFile ] ++ oFiles         } @@ -230,19 +237,18 @@         , buildBaseSrcDir       = builderConfigBaseSrcDir config         , buildBaseLibDir       = builderConfigBaseLibDir config -        -- Use -disable-cfi to disable Call Frame Identification (CFI) directives-        -- because the OSX system assembler doesn't support them.         , buildLlc                     = \llFile sFile                 -> doCmd "LLVM compiler"        [(2, BuilderCanceled)]-                [ "llc -O3 -march=x86-64 -relocation-model=pic -disable-cfi" -                ,       llFile +                [ "opt -O3"+                , llFile+                , "| llc -O3 -march=x86-64 -relocation-model=pic"                 , "-o", sFile ]          , buildCC                 = \cFile oFile                 -> doCmd "C compiler"           [(2, BuilderCanceled)]-                [ "gcc -Werror -std=c99 -O3 -m64"+                [ "cc -Werror -std=c99 -O3 -m64"                 , "-c", cFile                 , "-o", oFile                 , "-I" ++ builderConfigBaseSrcDir config </> "sea/runtime"@@ -251,17 +257,20 @@         , buildAs                 = \sFile oFile                 -> doCmd "assembler"            [(2, BuilderCanceled)]-                [ "as -arch x86_64"  +                [ "llvm-mc -arch x86-64 -filetype=obj"                   , "-o", oFile                 ,       sFile ]          , buildLdExe  -                = \oFile binFile+                = \oFiles binFile                 -> doCmd "linker"               [(2, BuilderCanceled)]-                [ "gcc -m64" +                [ "cc -m64 -Wl,-dead_strip"                  , "-o", binFile-                , oFile-                , builderConfigBaseLibDir config </> "libddc-runtime.dylib" ]+                , intercalate " " oFiles+                , builderConfigBaseLibDir config +                        </> builderConfigLibFile config +                                "libddc-runtime.a"+                                "libddc-runtime.dylib" ]          , buildLdLibStatic                 = \oFiles libFile@@ -271,7 +280,7 @@         , buildLdLibShared                 = \oFiles libFile                 -> doCmd "linker"               [(2, BuilderCanceled)]-                $ [ "gcc -m64 -dynamiclib -undefined dynamic_lookup"+                $ [ "cc -m64 -dynamiclib -undefined dynamic_lookup"                   , "-o", libFile ] ++ oFiles         } @@ -311,12 +320,15 @@                 ,       sFile ]          , buildLdExe  -                = \oFile binFile+                = \oFiles binFile                 -> doCmd "linker"               [(2, BuilderCanceled)]                 [ "gcc -m32"                  , "-o", binFile-                , oFile-                , builderConfigBaseLibDir config </> "libddc-runtime.so" ]+                , intercalate " " oFiles+                , builderConfigBaseLibDir config +                        </> builderConfigLibFile config+                                "libddc-runtime.a"+                                "libddc-runtime.so" ]          , buildLdLibStatic                 = \oFiles libFile@@ -365,12 +377,15 @@                 , sFile ]           , buildLdExe  -                = \oFile binFile+                = \oFiles binFile                 -> doCmd "linker"               [(2, BuilderCanceled)]                 [ "gcc -m64"                 , "-o", binFile-                , oFile-                , builderConfigBaseLibDir config </> "libddc-runtime.so" ]+                , intercalate " " oFiles+                , builderConfigBaseLibDir config+                        </> builderConfigLibFile config+                                "libddc-runtime.a"+                                "libddc-runtime.so" ]          , buildLdLibStatic                 = \oFiles libFile@@ -418,12 +433,15 @@                 , sFile ]          , buildLdExe  -                = \oFile binFile+                = \oFiles binFile                 -> doCmd "linker"               [(2, BuilderCanceled)]                 [ "gcc -m32"                  , "-o", binFile-                , oFile-                , builderConfigBaseLibDir config </> "libddc-runtime.so" ]+                , intercalate " " $ map normalise oFiles+                , builderConfigBaseLibDir config+                        </> builderConfigLibFile config+                                "libddc-runtime.a"+                                "libddc-runtime.so" ]          , buildLdLibStatic                 = \oFiles libFile@@ -473,12 +491,14 @@     -- Note on Cygwin we need to use 'gcc-4' explicitly because plain 'gcc'     -- is a symlink, which Windows doesn't really support.         , buildLdExe  -                = \oFile binFile+                = \oFiles binFile                 -> doCmd "linker"               [(2, BuilderCanceled)]                 [ "gcc-4 -m32"                  , "-o", normalise binFile-                , normalise oFile-                , normalise $ builderConfigBaseLibDir config </> "libddc-runtime.a" ]+                , intercalate " " $ map normalise oFiles+                , normalise $ builderConfigBaseLibDir config+                        </> "libddc-runtime.a" ] +                        -- configRuntimeLinkStrategy is ignored          , buildLdLibStatic                 = \oFiles libFile@@ -526,12 +546,14 @@                 , normalise sFile ]          , buildLdExe  -                = \oFile binFile+                = \oFiles binFile                 -> doCmd "linker"               [(2, BuilderCanceled)]                 [ "gcc -m32"                  , "-o", normalise binFile-                , normalise oFile-                , normalise $ builderConfigBaseLibDir config </> "libddc-runtime.a" ]+                , intercalate " " $ map normalise oFiles+                , normalise $ builderConfigBaseLibDir config +                        </> "libddc-runtime.a" ] +                        -- configRuntimeLinkStrategy is ignored          , buildLdLibStatic                 = \oFiles libFile
+ DDC/Build/Interface/Base.hs view
@@ -0,0 +1,93 @@++module DDC.Build.Interface.Base +        ( Interface (..)+        , makeInterfaceTearLine+        , takeInterfaceTearLine+        , isInterfaceTearLine)+where+import DDC.Core.Module+import DDC.Core.Pretty+import DDC.Core.Exp.Annot+import Data.Maybe+import Data.Time.Clock+import qualified Data.Char              as Char+import qualified DDC.Core.Tetra         as Tetra+import qualified DDC.Core.Salt          as Salt+++---------------------------------------------------------------------------------------------------+-- | Module interface.+data Interface ta sa+        = Interface+        { -- | Path that the interface was loaded from.+          interfaceFilePath     :: FilePath++          -- | Last modification time of the interface file,+          --   used to determine when the source needs to be rebuilt.+        , interfaceTimeStamp    :: UTCTime++        , interfaceVersion      :: String+        , interfaceModuleName   :: ModuleName+        , interfaceTetraModule  :: Maybe (Module ta Tetra.Name)+        , interfaceSaltModule   :: Maybe (Module sa Salt.Name) }+++---------------------------------------------------------------------------------------------------+instance Pretty (Interface ta sa) where+ ppr i+  =     (text "ddc interface" <+> text (interfaceVersion i))+         <> line <> line+         <> vcat [ text $ makeInterfaceTearLine "Meta"+                 , text "module-meta"   <+> lbrace <> line+                        <> indent 8 (vcat+                                [ hsep [text "name:", ppr $ interfaceModuleName i ] ])+                        <> line <> rbrace]++        -- Include the full unoptimised core code in interface files.+        --   We include the unoptimised code so that the modules that inline+        --   functions from this one are not sensitive to the optimisation flags+        --   use here. If we included the optimised code it would make it harder+        --   to reason about the overall compilation process.+        <> (case interfaceTetraModule i of+                Just m  -> vcat [ line +                                , text $ makeInterfaceTearLine "Tetra"+                                , ppr m ]+                Nothing -> empty)++        -- Include the header of the Salt module.+        --   We don't need the function definitions because inlining is performed+        --   using the higher level Tetra code.+        <> (case interfaceSaltModule i of+                Just m  -> +                 -- zap the module body so we don't get the function definitions.+                 let m' = m { moduleBody = xUnit (annotOfExp $ moduleBody m) }+                 in  vcat [ line+                          , text $ makeInterfaceTearLine "Salt"+                          , ppr m' ]+                Nothing -> empty)+++---------------------------------------------------------------------------------------------------+-- | Tear line to separate sections of the interface file. +--   We use '~' because it's not used in the core language syntax.+makeInterfaceTearLine :: String -> String+makeInterfaceTearLine name+        = "~~ " ++ name ++ " " ++ replicate (80 - 4 - length name) '~'++-- | Take the name from an interface tear line, if it is one.+takeInterfaceTearLine  :: String -> Maybe String+takeInterfaceTearLine str+        | '~' : '~' : ' ' : str2  <- str+        , (name, str3)            <- span (not . Char.isSpace) str2+        , (' ' : rest)            <- str3+        , all (== '~') rest+        = Just name++        | otherwise+        = Nothing++-- | Check if this string is an interface tear line.+isInterfaceTearLine :: String -> Bool+isInterfaceTearLine str+        = isJust $ takeInterfaceTearLine str+
+ DDC/Build/Interface/Load.hs view
@@ -0,0 +1,285 @@++-- | Loader for DDC interface files.+module DDC.Build.Interface.Load+        ( loadInterface+        , Error (..)+        , InterfaceAA)+where+import DDC.Build.Interface.Base+import DDC.Core.Check                           (AnTEC)+import DDC.Core.Module+import DDC.Base.Pretty+import DDC.Core.Transform.Reannotate+import Data.Time.Clock+import Control.Monad+import qualified DDC.Core.Load                  as Load+import qualified DDC.Core.Tetra                 as Tetra+import qualified DDC.Build.Language.Tetra       as Tetra+import qualified DDC.Core.Salt                  as Salt+import qualified DDC.Build.Language.Salt        as Salt+import qualified DDC.Data.SourcePos             as BP+import qualified Data.Char                      as Char+import qualified Data.List                      as List+++---------------------------------------------------------------------------------------------------+-- | Problems that can arise when loading an interface file.+data Error+        -- | Empty Interface file.+        = ErrorEmpty++        -- | No module meta information.+        | ErrorNoMeta++        -- | Duplicate module information.+        | ErrorDuplicate++        -- | Bad magic numbers / header information in alleged interface file.+        --   This probably isn't an interface file.+        | ErrorBadMagic+        { errorFilePath :: FilePath +        , errorLine     :: Int }++        -- | Parse error in Interface file.+        | ErrorParse+        { errorFilePath :: FilePath+        , errorLine     :: Int}++        -- | Parser error at end of input.+        | ErrorParseEnd++        -- | Error when loading a tetra core module from the interface file.+        | ErrorLoadTetra (Load.Error Tetra.Name Tetra.Error)++        -- | Error when loading a salt  core module from the interface file.+        | ErrorLoadSalt  (Load.Error  Salt.Name  Salt.Error)+++instance Pretty Error where+ ppr ErrorEmpty+  = vcat [ text "Empty interface file." ]++ ppr ErrorNoMeta+  = vcat [ text "No metadata section in interface file." ]++ ppr ErrorDuplicate+  = vcat [ text "Duplicate section in interface file." ]++ ppr (ErrorBadMagic path l)+  = vcat [ text path <> text ":" <> int l+         , text "Bad header in interface file." ]++ ppr (ErrorParse path l)+  = vcat [ text path <> text ":" <> int l+         , text "Parse error in interface file." ]++ ppr ErrorParseEnd+  = vcat [ text "Parse error at end of interface file." ]++ ppr (ErrorLoadTetra err)+  = vcat [ text "Error when loading Tetra module from interface file."+         , indent 2 $ ppr err ]++ ppr (ErrorLoadSalt err)+  = vcat [ text "Error when loading Salt module from interface file."+         , indent 2 $ ppr err ]+++---------------------------------------------------------------------------------------------------+-- | Line numbers.+type LineNumber  = Int++-- | Parser for some thing.+type Parser a    +        =  [(LineNumber, String)]+        -> Either Error a++-- | Type of annotated interface.+--   As don't store full Salt code in interface files,+--   we just set the annotation for it to ()+type InterfaceAA +        = Interface (AnTEC BP.SourcePos Tetra.Name) ()+++---------------------------------------------------------------------------------------------------+-- | Load an interface file.+loadInterface +        :: FilePath     -- ^ File path of interface file, for error messages.+        -> UTCTime      -- ^ TimeStamp of interface file.+        -> String       -- ^ Interface file source.+        -> Either Error InterfaceAA++loadInterface pathInterface timeStamp str+ = let  -- Attach line numbers to ach line+        ls      = lines str+        lsNum   = zip [1..] ls+   in   pInterface pathInterface timeStamp lsNum+++-- | Parse an interface file.+pInterface +        :: FilePath             -- ^ Path of interface file.+        -> UTCTime              -- ^ TimeStamp of interface file.+        -> Parser InterfaceAA++pInterface _pathInt _timeStamp []+        = Left ErrorEmpty++pInterface pathInt timeStamp ((n, str) : rest)+        -- Skip over blank lines+        | all (\c -> Char.isSpace c || c == '\n') str+        = pInterface pathInt timeStamp rest++        -- The interface needs to start with the magic words and version number.+        | ["ddc", "interface", version] <- words str+        = do    cs              <- pComponents pathInt rest++                -- We need exactly one module meta-data component.+                modName <- case [m | m@ComponentMeta{} <- cs] of+                                [m]     -> return $ componentModuleName m+                                _       -> Left $ ErrorNoMeta++                -- Accept a tetra module in the interface file.+                mTetra  <- case [m | m@ComponentTetraModule{} <- cs] of+                                []      -> return Nothing+                                [m]     -> return $ Just $ componentTetraModule m+                                _       -> Left ErrorDuplicate++                -- Accept a salt module in the interface file.+                mSalt   <- case [m | m@ComponentSaltModule{}  <- cs] of+                                []      -> return Nothing+                                [m]     -> return $ Just $ componentSaltModule m+                                _       -> Left ErrorDuplicate++                return  $ Interface+                        { interfaceFilePath     = pathInt+                        , interfaceTimeStamp    = timeStamp+                        , interfaceVersion      = version+                        , interfaceModuleName   = modName+                        , interfaceTetraModule  = mTetra+                        , interfaceSaltModule   = liftM (reannotate (const ())) mSalt }++        | otherwise+        = Left $ ErrorBadMagic pathInt n+++---------------------------------------------------------------------------------------------------+-- | A component of the interface file. +--   We use this as an intermediate form during parsing.+data Component+        = ComponentMeta+        { componentModuleName   :: ModuleName}++        | ComponentTetraModule+        { componentTetraModule  :: Module (AnTEC BP.SourcePos Tetra.Name) Tetra.Name }++        | ComponentSaltModule+        { componentSaltModule   :: Module (AnTEC BP.SourcePos Salt.Name)  Salt.Name  }+        deriving Show+++---------------------------------------------------------------------------------------------------+-- | Parse some components of an interface file.+pComponents :: FilePath -> Parser [Component]+pComponents _ []+        = return []++pComponents pathInterface (l : ls)+        -- skip blank lines+        | all Char.isSpace (snd l)+        = pComponents pathInterface ls++        -- parse a single section+        | isInterfaceTearLine (snd l)+        = do   let (ls', rest) = List.break (isInterfaceTearLine . snd) ls+               c       <- pComponent  pathInterface (l : ls')+               cs      <- pComponents pathInterface rest+               return  $ c : cs++        | otherwise+        = Left $ ErrorParse pathInterface (fst l)+++---------------------------------------------------------------------------------------------------+-- | Parse a single component of an interface file.+pComponent :: FilePath -> Parser Component+pComponent _ []   + = Left $ ErrorParseEnd++pComponent pathInt ((n, l) : rest)+        -- skip blank lines+        | all Char.isSpace l+        = pComponent pathInt rest++        -- load a module meta-data section.+        | Just "Meta"  <- takeInterfaceTearLine l+        = pComponentMeta pathInt rest++        -- load a Tetra core module section.+        | Just "Tetra" <- takeInterfaceTearLine l+        = case Load.loadModuleFromString Tetra.fragment pathInt (n + 1)+                       Load.Recon (unlines $ map snd rest) of+                (Left err, _)   -> Left $ ErrorLoadTetra  err+                (Right m,  _)   -> return $ ComponentTetraModule m++        -- load a Salt core module section.+        | Just "Salt"  <- takeInterfaceTearLine l+        = case Load.loadModuleFromString Salt.fragment pathInt (n + 1)+                       Load.Recon (unlines $ map snd rest) of+               (Left err, _)   -> Left $ ErrorLoadSalt err +               (Right m,  _)   -> return $ ComponentSaltModule  m++        -- this thing didn't parse.+        | otherwise+        = Left $ ErrorParse pathInt n+++---------------------------------------------------------------------------------------------------+-- | Parse module meta data from an interface file.+pComponentMeta :: FilePath -> Parser Component+pComponentMeta _pathInt [] +        = Left ErrorParseEnd++pComponentMeta pathInt nls@((n, _) : _)+        | "module-meta" : "{" : "name:" : strModName : "}" : []+                <- tokenize $ concatMap snd nls+        , Just modName     <- moduleNameOfString strModName+        = return $ ComponentMeta +                 { componentModuleName   = modName }++        | otherwise+        = Left   $ ErrorParse pathInt n+++---------------------------------------------------------------------------------------------------+-- | Tokenise the interface header containing module meta data.+tokenize :: String -> [String]+tokenize str+ = go [] str+ where  go acc []         = pop acc []++        go acc (c : cs)+         | Char.isSpace c = pop acc (go [] cs)+         | c == '{'       = pop acc ("{" : go [] cs)+         | c == '}'       = pop acc ("}" : go [] cs)+         | otherwise      = go (c : acc) cs++        pop acc x+         = case acc of+                []      -> x+                _       -> reverse acc : x+++-- | Parse a String as a `ModuleName`, or Nothing if it isn't one.+moduleNameOfString :: String -> Maybe ModuleName+moduleNameOfString str+ = Just $ ModuleName $ go str+ where+        go s+         | elem '.' s+         , (n, '.' : rest) <- span (/= '.') s+         = n : go rest++         | otherwise+         = [s]+
+ DDC/Build/Interface/Store.hs view
@@ -0,0 +1,256 @@++module DDC.Build.Interface.Store+        ( Store+        , new, wrap, load++        , Meta  (..)+        , getMeta+        , getModuleNames+        , getInterfaces++        , Super (..)+        , findSuper)+where+import DDC.Base.Pretty+import DDC.Build.Interface.Base         +import DDC.Build.Interface.Load+import DDC.Core.Call+import DDC.Core.Module+import DDC.Type.Exp+import System.Directory+import Data.Time.Clock+import Data.IORef+import Data.Maybe+import Data.Map                         (Map)+import qualified DDC.Core.Tetra         as E+import qualified DDC.Core.Salt          as A+import qualified Data.Map               as Map+++---------------------------------------------------------------------------------------------------+-- | Abstract API to a collection of module interfaces.+--+--   This lives in IO land because in future we want to demand-load the+--   inferface files as needed, rather than loading the full dependency+--   tree. Keeping it in IO means that callers must also be in IO.+data Store+        = Store+        { -- | Metadata for interface files currently in the store.+          storeMeta       :: IORef [Meta]++          -- | Lookup the definition of the given top-level super, +          --   from one or more of the provided modules.+        , storeSupers     :: IORef (Map ModuleName (Map E.Name Super)) ++          -- | Fully loaded interface files.+          --   In future we want to load parts of interface files on demand, +          --   and not the whole lot.+        , storeInterfaces :: IORef [InterfaceAA] }+++---------------------------------------------------------------------------------------------------+-- | Metadata for interfaces currently loaded into the store.+data Meta+        = Meta+        { metaFilePath     :: FilePath+        , metaTimeStamp    :: UTCTime+        , metaModuleName   :: ModuleName }+        deriving Show++instance Pretty Meta where+        ppr (Meta path stamp name)+         = hsep [ padL 60 $ text (show path)+                , padL 30 $ text (show stamp)+                , text (show name)]+++-- | Interface for some top-level super.+data Super+        = Super+        { -- | Name of the super.+          superName             :: E.Name++          -- | Where the super was imported from.+          --+          --   This is the module that the name was resolved from. If that+          --   module re-exported an imported name then this may not be the+          --   module the super was actually defined in.+        , superModuleName       :: ModuleName++          -- | Tetra type for the super.+        , superTetraType        :: Type E.Name++          -- | Salt type for the super.+        , superSaltType         :: Type A.Name ++          -- | Import source for the super.+          --+          --   This can be used to refer to the super from a client module.+        , superImportValue      :: ImportValue E.Name }+++---------------------------------------------------------------------------------------------------+-- | An empty interface store.+new :: IO Store+new+ = do   refMeta         <- newIORef []+        refSupers       <- newIORef Map.empty+        refInterfaces   <- newIORef []+        return  $ Store +                { storeMeta             = refMeta+                , storeSupers           = refSupers +                , storeInterfaces       = refInterfaces }+++-- | Add a pre-loaded interface file to the store.+wrap    :: Store -> InterfaceAA -> IO ()+wrap store ii+ = do   modifyIORef (storeMeta store)+         $ \meta   -> meta ++ [metaOfInterface ii] ++        modifyIORef (storeSupers store)+         $ \supers -> Map.insert (interfaceModuleName ii)+                                 (supersOfInterface   ii)+                                 supers++        modifyIORef (storeInterfaces store)+         $ \iis    -> iis ++ [ii]+++-- | Load a new interface from a file.+load    :: FilePath -> IO (Either Error InterfaceAA)+load filePath+ = do   timeStamp  <- getModificationTime filePath+        str        <- readFile filePath+        return $ loadInterface filePath timeStamp str+++-- | Get metadata of interfaces currently in the store.+getMeta :: Store -> IO [Meta]+getMeta store+ = do   mm      <- readIORef (storeMeta store)+        return  $ mm+++-- | Get names of the modules currently in the store.+getModuleNames :: Store -> IO [ModuleName]+getModuleNames store+ = do   supers  <- readIORef (storeSupers store)+        return  $ Map.keys supers+++-- | Get the fully loaded interfaces.+getInterfaces :: Store -> IO [InterfaceAA]+getInterfaces store+ = do   ints    <- readIORef (storeInterfaces store)+        return ints+++-- | See if a super is defined in any of the given modules, and if so+--   return the module name and super type.+--+--   NOTE: This function returns an IO [Super] in preparation for the case+--   where we load data from interface files on demand. We want to ensure+--   that the caller is also in IO, to make the refactoring easier later.+--+findSuper+        :: Store+        -> E.Name               -- ^ Name of desired super.+        -> [ModuleName]         -- ^ Names of modules to search.+        -> IO [Super]++findSuper store n modNames + = do   supers  <- readIORef (storeSupers store)+        return $ mapMaybe+                (\modName -> do+                        nSupers <- Map.lookup modName supers+                        Map.lookup n nSupers)+                modNames+++---------------------------------------------------------------------------------------------------+-- | Extract metadata from an interface.+metaOfInterface   :: InterfaceAA -> Meta+metaOfInterface ii+        = Meta+        { metaFilePath   = interfaceFilePath   ii+        , metaTimeStamp  = interfaceTimeStamp  ii+        , metaModuleName = interfaceModuleName ii }+++-- | Extract a map of super interfaces from the given module interface.+--+--   This contains all the information needed to import a super into+--   a client module.+--+supersOfInterface :: InterfaceAA -> Map E.Name Super+supersOfInterface ii+ | Just mmTetra <- interfaceTetraModule ii+ , Just mmSalt  <- interfaceSaltModule  ii+ = let  +        -- The current module name.+        modName = interfaceModuleName ii++        -- Collect Tetra types for all supers exported by the module.+        ntsTetra    +         = Map.fromList+           [ (n, t)     | (n, esrc)     <- moduleExportValues mmTetra+                        , let Just t    =  takeTypeOfExportSource esrc ]++        -- Collect Salt  types of all supers exported by the module.+        ntsSalt +         = Map.fromList+           [ (n, t)     | (n, esrc)     <- moduleExportValues mmSalt+                        , let Just t    =  takeTypeOfExportSource esrc ]++        -- Build call patterns for all locally defined supers.+        --  The call pattern is the number of type parameters then value parameters+        --  for the super. We assume all supers are in prenex form, so they take+        --  all their type arguments before their value arguments.+        makeLocalArity b x+         | BName nSuper _       <- b+         , cs                   <- takeCallConsFromExp x+         , Just (csType, csValue, csBox) <- splitStdCallCons cs+         = (nSuper, (length csType, length csValue, length csBox))++         | otherwise = error "ddc-build.supersOfInterface: type is not in prenex form."++        nsLocalArities :: Map E.Name (Int, Int, Int)+                =  Map.fromList+                $  mapTopBinds makeLocalArity+                $  mmTetra++        -- Build an ImportSource for the given super name. A client module+        -- can use this to import the super into itself.+        makeImportValue n++         -- Super was defined as a top-level binding in the current module.+         | Just (aType, aValue, nBoxes) <- Map.lookup n nsLocalArities+         , Just tTetra                  <- Map.lookup n ntsTetra+         = ImportValueModule modName n tTetra (Just (aType, aValue, nBoxes))++         -- Super was imported into the current module from somewhere else.+         -- Pass along the same import declaration to the client.+         | Just impt            <- lookup n (moduleImportValues mmTetra)+         = impt++         | otherwise = error $ "ddc-build.supersOfInterface: no source" ++ show n++        makeSuper n tTetra+         | E.NameVar s  <- n+         = Just $ Super+                { superName         = n+                , superModuleName   = moduleName mmTetra+                , superTetraType    = tTetra+                , superSaltType     = let Just t = Map.lookup (A.NameVar s) ntsSalt  in t +                , superImportValue  = makeImportValue n }+         | otherwise    = Nothing+++   in   Map.fromList   +          [ (n, super)  | (n, tTetra)    <- Map.toList ntsTetra +                        , let Just super = makeSuper n tTetra ]++ | otherwise+ = Map.empty+
DDC/Build/Language.hs view
@@ -8,9 +8,7 @@ where import DDC.Core.Fragment import DDC.Build.Language.Base-import DDC.Build.Language.Lite  as Lite import DDC.Build.Language.Salt  as Salt-import DDC.Build.Language.Eval  as Eval import DDC.Build.Language.Flow  as Flow import DDC.Build.Language.Zero  as Zero import DDC.Build.Language.Tetra as Tetra@@ -18,19 +16,17 @@  -- | Supported language profiles. --   ---   One of @Tetra@, @Lite@, @Salt@, @Eval@, @Flow@, @Zero@.+--   One of @Tetra@, @Salt@, @Eval@, @Flow@, @Zero@. languages :: [(String, Language)] languages  =      [ ( "Tetra", Tetra.language) -        , ( "Lite",  Lite.language)         , ( "Salt",  Salt.language)-        , ( "Eval",  Eval.language)         , ( "Flow",  Flow.language)         , ( "Zero",  Zero.language) ]   -- | Return the language fragment definition corresponding to the given ---   file extension. eg @dcl@ gives the definition of the Lite language.+--   file extension. eg @dct@ gives the definition of the Tetra language. languageOfExtension :: String -> Maybe Language languageOfExtension ext  = let  -- Strip of dots at the front.@@ -41,9 +37,7 @@                         _               -> ext    in case ext' of         "dct"   -> Just Tetra.language-        "dcl"   -> Just Lite.language         "dcs"   -> Just Salt.language-        "dcv"   -> Just Eval.language         "dcf"   -> Just Flow.language         "dcz"   -> Just Zero.language         _       -> Nothing
DDC/Build/Language/Base.hs view
@@ -10,6 +10,7 @@ import DDC.Core.Transform.Namify import DDC.Core.Transform.Rewrite import DDC.Base.Pretty+import DDC.Base.Name import Control.DeepSeq import Data.Typeable import Data.Map                         (Map)@@ -27,7 +28,8 @@           , Pretty n           , Pretty (err (AnTEC BP.SourcePos n))           , Pretty (err (AnTEC () n))-          , NFData n)+          , NFData n+          , CompoundName n)         => Language (Bundle s n err)  
− DDC/Build/Language/Eval.hs
@@ -1,75 +0,0 @@---- | The `Eval` fragment can be interpreted with our semantic interpreter.-module DDC.Build.Language.Eval-        ( language-        , bundle-        , fragment-        , profile)-where-import DDC.Build.Language.Base-import DDC.Core.Simplifier-import DDC.Core.Transform.Namify-import DDC.Core.Eval.Profile-import DDC.Core.Eval.Name-import DDC.Core.Fragment-import DDC.Core.Eval.Check              as Eval-import DDC.Type.Exp-import DDC.Type.Env                     (Env)-import qualified DDC.Type.Env           as Env-import qualified Data.Map               as Map-import Control.Monad.State.Strict----- | Language definition for Disciple Core Eval.-language    :: Language-language    = Language bundle----- | Language bundle for Disciple Core Eval.-bundle      :: Bundle Int Name Eval.Error-bundle  = Bundle-        { bundleFragment        = fragment-        , bundleModules         = Map.empty-        , bundleStateInit       = 0 :: Int-        , bundleSimplifier      = Trans Id-        , bundleMakeNamifierT   = makeNamifier freshT-        , bundleMakeNamifierX   = makeNamifier freshX-        , bundleRewriteRules    = Map.empty }----- | Fragment definition for Disciple Core Eval.-fragment :: Fragment Name Eval.Error-fragment-        = Fragment-        { fragmentProfile       = evalProfile-        , fragmentExtension     = "dcv"-        , fragmentReadName      = readName-        , fragmentLexModule     = lexModuleString-        , fragmentLexExp        = lexExpString-        , fragmentCheckModule   = checkCapsModule-        , fragmentCheckExp      = checkCapsX  }---profile = evalProfile---- | Create a new type variable name that is not in the given environment.-freshT :: Env Name -> Bind Name -> State Int Name-freshT env bb- = do   i       <- get-        put (i + 1)-        let n =  NameVar ("t" ++ show i)-        case Env.lookupName n env of-         Nothing -> return n-         _       -> freshT env bb----- | Create a new value variable name that is not in the given environment.-freshX :: Env Name -> Bind Name -> State Int Name-freshX env bb- = do   i       <- get-        put (i + 1)-        let n = NameVar ("v" ++ show i)-        case Env.lookupName n env of-         Nothing -> return n-         _       -> freshX env bb-
DDC/Build/Language/Flow.hs view
@@ -18,15 +18,14 @@ import qualified Data.Map               as Map  --- | Language definition for Disciple Core Lite.+-- | Language definition for Disciple Core Flow. language    :: Language language    = Language bundle  --- | Language bundle for Disciple Core Lite.+-- | Language bundle for Disciple Core Flow. bundle  :: Bundle Int Name Error-bundle-        = Bundle+bundle  = Bundle         { bundleFragment        = fragment         , bundleModules         = Map.empty         , bundleStateInit       = 0 :: Int@@ -36,7 +35,7 @@         , bundleRewriteRules    = Map.empty }  --- | Fragement definition for Disciple Core Lite.+-- | Fragement definition for Disciple Core Flow. fragment :: Fragment Name Error fragment         = Fragment
− DDC/Build/Language/Lite.hs
@@ -1,73 +0,0 @@---- | The `Lite` fragment is a desugared version of Disciple Core that has all---   the polymorphism of System-F2 along with algebraic data types.-module DDC.Build.Language.Lite-        ( language-        , bundle-        , fragment-        , freshT-        , freshX)-where-import DDC.Build.Language.Base-import DDC.Core.Simplifier-import DDC.Core.Transform.Namify-import DDC.Core.Fragment-import DDC.Core.Lite                    as Lite-import DDC.Type.Exp-import DDC.Type.Env                     (Env)-import qualified DDC.Type.Env           as Env-import qualified Data.Map               as Map-import Control.Monad.State.Strict----- | Language definition for Disciple Core Lite.-language    :: Language-language    = Language bundle----- | Language bundle for Disciple Core Lite.-bundle  :: Bundle Int Name Lite.Error-bundle-        = Bundle-        { bundleFragment        = fragment-        , bundleModules         = Map.empty-        , bundleStateInit       = 0 :: Int-        , bundleSimplifier      = Trans Id-        , bundleMakeNamifierT   = makeNamifier freshT -        , bundleMakeNamifierX   = makeNamifier freshX -        , bundleRewriteRules    = Map.empty }----- | Fragement definition for Disciple Core Lite.-fragment :: Fragment Name Lite.Error-fragment-        = Fragment-        { fragmentProfile       = profile -        , fragmentExtension     = "dcl"-        , fragmentReadName      = readName-        , fragmentLexModule     = lexModuleString-        , fragmentLexExp        = lexExpString-        , fragmentCheckModule   = const Nothing-        , fragmentCheckExp      = const Nothing }----- | Create a new type variable name that is not in the given environment.-freshT :: Env Name -> Bind Name -> State Int Name-freshT env bb- = do   i       <- get-        put (i + 1)-        let n =  NameVar ("t" ++ show i)-        case Env.lookupName n env of-         Nothing -> return n-         _       -> freshT env bb----- | Create a new value variable name that is not in the given environment.-freshX :: Env Name -> Bind Name -> State Int Name-freshX env bb- = do   i       <- get-        put (i + 1)-        let n = NameVar ("x" ++ show i)-        case Env.lookupName n env of-         Nothing -> return n-         _       -> freshX env bb
DDC/Build/Language/Salt.hs view
@@ -12,9 +12,9 @@ import DDC.Core.Simplifier import DDC.Core.Transform.Namify import DDC.Core.Fragment-import DDC.Core.Salt                    as Salt import DDC.Type.Exp import DDC.Type.Env                     (Env)+import qualified DDC.Core.Salt          as A import qualified DDC.Type.Env           as Env import qualified Data.Map               as Map import Control.Monad.State.Strict@@ -26,7 +26,7 @@   -- | Language bundle for Disciple Core Salt.-bundle   :: Bundle Int Name Salt.Error+bundle   :: Bundle Int A.Name A.Error bundle  = Bundle         { bundleFragment        = fragment         , bundleModules         = Map.empty@@ -38,35 +38,35 @@   -- | Fragment definition for Disciple Core Salt.-fragment :: Fragment Name Salt.Error+fragment :: Fragment A.Name A.Error fragment          = Fragment-        { fragmentProfile       = profile +        { fragmentProfile       = A.profile          , fragmentExtension     = "dcs"-        , fragmentReadName      = readName-        , fragmentLexModule     = lexModuleString-        , fragmentLexExp        = lexExpString+        , fragmentReadName      = A.readName+        , fragmentLexModule     = A.lexModuleString+        , fragmentLexExp        = A.lexExpString         , fragmentCheckModule   = const Nothing         , fragmentCheckExp      = const Nothing }   -- | Create a new type variable name that is not in the given environment.-freshT :: Env Name -> Bind Name -> State Int Name+freshT :: Env A.Name -> Bind A.Name -> State Int A.Name freshT env bb  = do   i       <- get         put (i + 1)-        let n =  NameVar ("t" ++ show i)+        let n =  A.NameVar ("t" ++ show i)         case Env.lookupName n env of          Nothing -> return n          _       -> freshT env bb   -- | Create a new value variable name that is not in the given environment.-freshX :: Env Name -> Bind Name -> State Int Name+freshX :: Env A.Name -> Bind A.Name -> State Int A.Name freshX env bb  = do   i       <- get         put (i + 1)-        let n = NameVar ("x" ++ show i)+        let n = A.NameVar ("x" ++ show i)         case Env.lookupName n env of          Nothing -> return n          _       -> freshX env bb
DDC/Build/Language/Tetra.hs view
@@ -44,4 +44,3 @@         , fragmentLexExp        = E.lexExpString         , fragmentCheckModule   = E.checkModule         , fragmentCheckExp      = const Nothing }-
DDC/Build/Language/Zero.hs view
@@ -13,6 +13,7 @@ import DDC.Core.Fragment                hiding (Error) import DDC.Core.Transform.Namify import DDC.Base.Pretty+import DDC.Base.Name import DDC.Data.Token import DDC.Type.Exp import Data.Typeable@@ -65,16 +66,31 @@ -- Wrap the names we use for the zero fragment,  -- so they get pretty printed properly. data Name -        = Name String+        = Name    String+        | NameExt Name String         deriving (Eq, Ord, Show, Typeable) + instance NFData Name where- rnf (Name str) = rnf str+ rnf (Name str)         = rnf str+ rnf (NameExt n str)    = rnf n `seq` rnf str + instance Pretty Name where- ppr (Name str) = text str+ ppr (Name str)         = text str+ ppr (NameExt n str)    = ppr n <> text "$" <> text str  +instance CompoundName Name where+ extendName n str       +  = NameExt n str+ + splitName nn+  = case nn of+        NameExt n str   -> Just (n, str)+        _               -> Nothing++ -- | Lex a string to tokens, using primitive names. -- --   The first argument gives the starting source line number.@@ -84,7 +100,7 @@  where rn (Token t sp)          = case renameTok (Just . Name) t of                 Just t' -> Token t' sp-                Nothing -> Token (KJunk "lexical error") sp+                Nothing -> Token (KErrorJunk "lexical error") sp   -- | Lex a string to tokens, using primitive names.@@ -96,7 +112,7 @@  where rn (Token t sp)          = case renameTok (Just . Name) t of                 Just t' -> Token t' sp-                Nothing -> Token (KJunk "lexical error") sp+                Nothing -> Token (KErrorJunk "lexical error") sp   -- | Create a new type variable name that is not in the given environment.
DDC/Build/Pipeline.hs view
@@ -21,10 +21,6 @@         , PipeTetra       (..)         , pipeTetra -          -- * Core Lite modules-        , PipeLite        (..)-        , pipeLite-           -- * Core Flow modules         , PipeFlow        (..)         , pipeFlow
DDC/Build/Pipeline/Core.hs view
@@ -7,9 +7,6 @@         , PipeTetra (..)         , pipeTetra -        , PipeLite (..)-        , pipeLite-         , PipeFlow (..)         , pipeFlow) where@@ -19,40 +16,46 @@ import DDC.Build.Language import DDC.Core.Simplifier import DDC.Base.Pretty+import DDC.Base.Name import DDC.Data.Canned import DDC.Llvm.Pretty                                  ()  import qualified DDC.Core.Flow                          as Flow import qualified DDC.Core.Flow.Profile                  as Flow-import qualified DDC.Core.Flow.Transform.Slurp          as Flow+import qualified DDC.Core.Flow.Transform.Forward        as Flow import qualified DDC.Core.Flow.Transform.Melt           as Flow import qualified DDC.Core.Flow.Transform.Wind           as Flow import qualified DDC.Core.Flow.Transform.Rates.SeriesOfVector as Flow+import qualified DDC.Core.Flow.Convert                  as Flow -import qualified DDC.Core.Tetra                         as Tetra+import qualified DDC.Core.Tetra.Transform.Curry         as Tetra import qualified DDC.Core.Tetra.Transform.Boxing        as Tetra+import qualified DDC.Core.Tetra                         as Tetra -import qualified DDC.Core.Lite                          as Lite+import qualified DDC.Core.Babel.PHP                     as PHP  import qualified DDC.Core.Salt.Platform                 as Salt import qualified DDC.Core.Salt.Runtime                  as Salt import qualified DDC.Core.Salt                          as Salt +import qualified DDC.Core.Transform.Unshare             as C import qualified DDC.Core.Transform.Reannotate          as C-import qualified DDC.Core.Transform.Deannotate          as C import qualified DDC.Core.Transform.Namify              as C-import qualified DDC.Core.Transform.Forward             as Forward import qualified DDC.Core.Transform.Snip                as Snip import qualified DDC.Core.Transform.Flatten             as Flatten import qualified DDC.Core.Transform.Eta                 as Eta+import qualified DDC.Core.Transform.Beta                as Beta+import qualified DDC.Core.Transform.Lambdas             as Lambdas+import qualified DDC.Core.Transform.Forward             as Forward import qualified DDC.Core.Simplifier                    as C  import qualified DDC.Core.Fragment                      as C import qualified DDC.Core.Check                         as C import qualified DDC.Core.Pretty                        as C import qualified DDC.Core.Module                        as C-import qualified DDC.Core.Exp                           as C +import qualified DDC.Core.Exp.Annot                     as C+ import qualified DDC.Type.Env                           as Env  import qualified Control.Monad.State.Strict             as S@@ -60,6 +63,7 @@ import Control.DeepSeq  +--------------------------------------------------------------------------------------------------- -- | Process a core module. data PipeCore a n where   -- Plumb the module on without transforming it.@@ -99,7 +103,8 @@    -- Apply a simplifier to a module.   PipeCoreSimplify  -        :: !(Fragment n err)+        :: (Pretty a, CompoundName n)+        => !(Fragment n err)         -> !s         -> !(Simplifier s a n)         -> ![PipeCore () n] @@ -107,21 +112,16 @@    -- Treat a module as belonging to the Core Tetra fragment from now on.   PipeCoreAsTetra-        :: ![PipeTetra (C.AnTEC a Tetra.Name)]-        -> PipeCore (C.AnTEC a Tetra.Name) Tetra.Name--  -- Treat a module as belonging to the Core Lite fragment from now on.-  PipeCoreAsLite-        :: ![PipeLite]-        -> PipeCore (C.AnTEC () Lite.Name) Lite.Name+        :: ![PipeTetra a]+        -> PipeCore a Tetra.Name -  -- Treat a module as beloning to the Core Flow fragment from now on.+  -- Treat a module as belonging to the Core Flow fragment from now on.   PipeCoreAsFlow          :: Pretty a         => ![PipeFlow a]         -> PipeCore a Flow.Name -  -- Treat a module as beloning to the Core Salt fragment from now on.+  -- Treat a module as belonging to the Core Salt fragment from now on.   PipeCoreAsSalt         :: Pretty a          => ![PipeSalt a] @@ -217,10 +217,6 @@          -> {-# SCC "PipeCoreAsTetra" #-}             liftM concat $ mapM (pipeTetra mm) pipes -        PipeCoreAsLite !pipes-         -> {-# SCC "PipeCoreAsLite" #-}-            liftM concat $ mapM (pipeLite mm) pipes-         PipeCoreAsFlow !pipes          -> {-# SCC "PipeCoreAsFlow" #-}             liftM concat $ mapM (pipeFlow mm) pipes@@ -248,7 +244,7 @@                 go (errs ++ err) rest  --- PipeTetra ------------------------------------------------------------------+-- PipeTetra -------------------------------------------------------------------------------------- -- | Process a Core Tetra module. data PipeTetra a where         -- Output the module in core language syntax.@@ -256,6 +252,12 @@          :: !Sink          -> PipeTetra a +        -- Manage currying of functions.+        PipeTetraCurry+         :: (NFData a, Show a)+         => ![PipeCore () Tetra.Name]+         -> PipeTetra  (C.AnTEC a Tetra.Name)+         -- Manage boxing of numeric values.         PipeTetraBoxing          :: (NFData a, Show a)@@ -270,7 +272,14 @@          -> ![PipeCore a Salt.Name]          -> PipeTetra  (C.AnTEC a Tetra.Name) +        -- Print as PHP code+        PipeTetraToPHP+         :: (NFData a, Show a)+         => !Sink+         -> PipeTetra a ++ -- | Process a Core Tetra module. pipeTetra          :: C.Module a Tetra.Name@@ -281,8 +290,14 @@  = case pp of         PipeTetraOutput !sink          -> {-# SCC "PipeTetraOutput" #-}-            pipeSink (renderIndent $ ppr mm) sink+            pipeSink (renderIndent $ ppr mm)  sink +        PipeTetraCurry  !pipes+         -> {-# SCC "PipeTetraCurry"  #-}+            case Tetra.curryModule (C.unshareModule mm) of+             Left err  -> return [ErrorTetraConvert err]+             Right mm' -> pipeCores mm' pipes+         PipeTetraBoxing !pipes          -> {-# SCC "PipeTetraBoxing" #-}             pipeCores (Tetra.boxingModule mm) pipes@@ -297,43 +312,22 @@              of  Left  err  -> return [ErrorTetraConvert err]                  Right mm'  -> pipeCores mm' pipes  ----- PipeLite ---------------------------------------------------------------------- | Process a Core Lite module.-data PipeLite-        -- | Output the module in core language syntax.-        = PipeLiteOutput !Sink--        -- | Convert the module to the Core Salt Fragment.-        | PipeLiteToSalt !Salt.Platform -                         !Salt.Config-                         ![PipeCore () Salt.Name]----- | Process a Core Lite module.-pipeLite :: C.Module (C.AnTEC () Lite.Name) Lite.Name-         -> PipeLite-         -> IO [Error]+        PipeTetraToPHP !sink+         -> {-# SCC "PipeTetraToPHP" #-}+            let -- Snip program to expose intermediate bindings.+                mm_snip         = Flatten.flatten +                                $ Snip.snip (Snip.configZero) mm -pipeLite !mm !pp- = case pp of-        PipeLiteOutput !sink-         -> {-# SCC "PipeLiteOutput" #-}-            pipeSink (renderIndent $ ppr mm) sink+                -- The floater needs bindings to be fully named.+                namifierT       = C.makeNamifier Tetra.freshT Env.empty+                namifierX       = C.makeNamifier Tetra.freshX Env.empty+                mm_namified     = S.evalState (C.namify namifierT namifierX mm_snip) 0 -        PipeLiteToSalt !platform !runConfig !pipes-         -> {-# SCC "PipeLiteToSalt" #-}-            case Lite.saltOfLiteModule platform runConfig -                        (C.profilePrimDataDefs Lite.profile) -                        (C.profilePrimKinds    Lite.profile)-                        (C.profilePrimTypes    Lite.profile)-                        mm -             of  Left  err  -> return [ErrorLiteConvert err]-                 Right mm'  -> pipeCores mm' pipes +                doc  = PHP.phpOfModule mm_namified+            in  pipeSink (renderIndent doc) sink  --- PipeFlow -------------------------------------------------------------------+-- PipeFlow --------------------------------------------------------------------------------------- -- | Process a Core Flow module. data PipeFlow a where   -- Output the module in core language syntax.@@ -378,7 +372,12 @@         :: [PipeCore () Flow.Name]         -> PipeFlow (C.AnTEC () Flow.Name) +  -- Wind loop# primops into tail recursive loops.+  PipeFlowToTetra+        :: [PipeCore () Salt.Name]+        -> PipeFlow (C.AnTEC () Flow.Name) + -- | Process a Core Flow module. pipeFlow :: C.Module a Flow.Name          -> PipeFlow a@@ -416,16 +415,7 @@                  -- Float worker functions and initializers into their use sites,                  -- leaving only flow operators at the top-level.-                isFloatable lts-                 = case lts of-                    C.LLet (C.BName _ _) x-                      |  Flow.isSeriesOperator (C.deannotate (const Nothing) x)-                      -> Forward.FloatDeny-                    _ -> Forward.FloatForce--                mm_float        = C.result $ Forward.forwardModule Flow.profile -                                        (Forward.Config isFloatable False)-                                        mm_namified+                mm_float        = Flow.forwardProcesses mm_namified              in  pipeCores mm_float pipes @@ -448,20 +438,26 @@                 namifierX       = C.makeNamifier Flow.freshX Env.empty                 mm_namified     = S.evalState (C.namify namifierT namifierX mm_snip) 0 -                -- Float worker functions and initializers into their use sites, -                -- leaving only flow operators at the top-level.-                isFloatable lts-                 = case lts of-                    C.LLet (C.BName _ _) x-                      |  Flow.isVectorOperator (C.deannotate (const Nothing) x)-                      -> Forward.FloatDeny-                    _ -> Forward.FloatForce -                mm_float        = C.result $ Forward.forwardModule Flow.profile -                                        (Forward.Config isFloatable False)-                                        mm_namified+                floatControl l+                 = case l of+                   C.LLet _ x+                     | Just _ <- C.takeXLamFlags x+                     -> Forward.FloatForceUsedOnce+                   _ -> Forward.FloatDeny +                -- Force forward all worker functions.+                -- Anything that's not a vector op will be treated as an external,+                -- so that's fine.+                mm_float        = C.result+                                $ Forward.forwardModule Flow.profile+                                    (Forward.Config floatControl False)+                                    $ C.reannotate (const ()) mm_namified+++                 goRate+                 -- Rate inference uses the types                  = case C.checkModule (C.configOfProfile Flow.profile) mm_float C.Recon of                      (Left err, _)                           -> return [ErrorCoreTransform err]@@ -470,8 +466,8 @@                       -> let mm_stripped = C.reannotate (const ()) mm'                              mm_flow     = fst $ Flow.seriesOfVectorModule mm_stripped                            -                             -- Check again to synthesise types-                         in case C.checkModule (C.configOfProfile Flow.profile) mm_flow C.Recon of+                            -- Synthesise the types of any newly created bindings.+                         in case C.checkModule (C.configOfProfile Flow.profile) mm_flow C.Synth of                              (Left err, _ct)                                        -> return [ErrorCoreTransform err]                             @@ -500,6 +496,59 @@             let mm_stripped     = C.reannotate (const ()) mm                 mm_wound        = Flow.windModule mm_stripped             in  pipeCores mm_wound pipes++        PipeFlowToTetra !pipes+         -> {-# SCC "PipeFlowToTetra" #-}+            let +                -- Apply any lambdas we can+                mm_beta         = C.result $ Beta.betaReduce Flow.profile+                                        (Beta.configZero { Beta.configBindRedexes = True})+                                        mm++                -- Eta-expand all the leftovers so they can be lifted+                mm_eta          = C.result $ Eta.etaModule   Flow.profile+                                        (Eta.configZero { Eta.configExpand = True})+                                        mm_beta+++                -- Lift up any remaining lambdas+                mm_lift         = Lambdas.lambdasModule Flow.profile mm_eta++                -- Snip program so arguments and case scrutinees are just variables+                mm_snip         = Flatten.flatten +                                $ Snip.snip +                                        Snip.configZero+                                        mm_lift++                -- The floater needs bindings to be fully named.+                namifierT       = C.makeNamifier Flow.freshT Env.empty+                namifierX       = C.makeNamifier Flow.freshX Env.empty+                mm_namified     = S.evalState (C.namify namifierT namifierX mm_snip) 0++            in  case Flow.tetraOfFlowModule mm_namified of+                 Left  err  -> return [ErrorFlowConvert err]+                 Right mm'  ->+                  case C.checkModule (C.configOfProfile Salt.profile) mm' C.Recon of+                   (Left err, _ct)         +                    -> return [ErrorCoreTransform err]+                   (Right mm_check', _ct) +                    -> let mm_reannot' = C.reannotate (const ()) mm_check'++                           floatControl l+                             = case l of+                               C.LLet b _+                                 | Just _ <- C.takeTFun $ C.typeOfBind b+                                 -> Forward.FloatForce+                               _ -> Forward.FloatAllow++                           -- Forward all functions+                           mm_float        = C.result+                                           $ Forward.forwardModule Salt.profile+                                               (Forward.Config floatControl True)+                                               $ C.reannotate (const ()) mm_reannot'++                       in  pipeCores mm_float pipes+   -- | Process a Flow module with several different pipes.
DDC/Build/Pipeline/Error.hs view
@@ -27,8 +27,8 @@         -- | Error converting the module from Tetra to Salt.         | forall err. Pretty err => ErrorTetraConvert !err -        -- | Error converting the module from Lite to Salt.-        | forall err. Pretty err => ErrorLiteConvert !err+        -- | Error converting the module from Tetra to Salt.+        | forall err. Pretty err => ErrorFlowConvert  !err          -- | Error when transforming core program.         | forall err. Pretty err => ErrorCoreTransform !err@@ -51,15 +51,15 @@                  , indent 2 (ppr err') ]          ErrorSaltConvert err'-         -> vcat [ text "Fragment violation when converting Salt module to C code."+         -> vcat [ text "Fragment violation when converting Salt module to target code."                  , indent 2 (ppr err') ]          ErrorTetraConvert err'          -> vcat [ text "Fragment violation when converting Tetra module to Salt module."                  , indent 2 (ppr err') ] -        ErrorLiteConvert err'-         -> vcat [ text "Fragment violation when converting Lite module to Salt module."+        ErrorFlowConvert err'+         -> vcat [ text "Fragment violation when converting Flow module to Tetra module."                  , indent 2 (ppr err') ]          ErrorCoreTransform err'@@ -67,5 +67,6 @@                  , indent 2 (ppr err') ]  -instance NFData Error+instance NFData Error where+ rnf !_ = () 
DDC/Build/Pipeline/Llvm.hs view
@@ -22,7 +22,8 @@         , pipeFileLlvm          :: FilePath         , pipeFileAsm           :: FilePath         , pipeFileObject        :: FilePath-        , pipeFileExe           :: Maybe FilePath +        , pipeFileExe           :: Maybe FilePath+        , pipeLinkOtherObjects  :: [FilePath]         , pipeKeepLlvmFiles     :: Bool          , pipeKeepAsmFiles      :: Bool }         deriving (Show)@@ -43,7 +44,7 @@             pipeSink (renderIndent $ ppr mm) sink          PipeLlvmCompile -                !builder !llPath !sPath !oPath !mExePath+                !builder !llPath !sPath !oPath !mExePath !osLinkOther                 !keepLlvmFiles !keepAsmFiles          -> {-# SCC "PipeLlvmCompile" #-}             do  -- Write out the LLVM source file.@@ -62,7 +63,7 @@                    -> return ()                    Just exePath-                   -> do buildLdExe builder oPath exePath+                   -> do buildLdExe builder (oPath : osLinkOther) exePath                          return ())                  -- Remove LLVM IR files if we weren't asked for them.
DDC/Build/Pipeline/Salt.hs view
@@ -101,9 +101,11 @@         PipeSaltToLlvm !platform !more          -> {-# SCC "PipeSaltToLlvm" #-}             do  let !mm_cut  = C.reannotate (const ()) mm-                let !mm'     = Llvm.convertModule platform mm_cut -                results <- mapM (pipeLlvm mm') more-                return  $ concat results+                case Llvm.convertModule platform mm_cut of+                 Left err       -> return [ErrorSaltConvert err]+                 Right mm'      +                  -> do results <- mapM (pipeLlvm mm') more+                        return $ concat results          PipeSaltCompile                  !platform !builder !cPath !oPath !mExePath@@ -124,7 +126,7 @@                     (case mExePath of                       Nothing -> return ()                       Just exePath-                       -> do buildLdExe builder oPath exePath+                       -> do buildLdExe builder [oPath] exePath                              return ())                      -- Remove intermediate .c files if we weren't asked for them.
DDC/Build/Pipeline/Text.hs view
@@ -1,17 +1,22 @@ {-# LANGUAGE GADTs #-} module DDC.Build.Pipeline.Text-        ( PipeText (..)+        ( -- InterfaceAA+          PipeText (..)         , pipeText) where import DDC.Build.Pipeline.Error import DDC.Build.Pipeline.Sink import DDC.Build.Pipeline.Core import DDC.Build.Language+import DDC.Build.Interface.Store                (Store) import DDC.Base.Pretty -import qualified DDC.Source.Tetra.ToCore           as SE+import qualified DDC.Build.Transform.Resolve       as B++import qualified DDC.Source.Tetra.Convert          as SE import qualified DDC.Source.Tetra.Transform.Defix  as SE import qualified DDC.Source.Tetra.Transform.Expand as SE+import qualified DDC.Source.Tetra.Pretty           () import qualified DDC.Source.Tetra.Parser           as SE import qualified DDC.Source.Tetra.Lexer            as SE import qualified DDC.Source.Tetra.Env              as SE@@ -20,13 +25,14 @@ import qualified DDC.Core.Tetra                    as CE import qualified DDC.Core.Tetra.Env                as CE -import qualified DDC.Core.Parser                   as C+import qualified DDC.Core.Fragment                 as C import qualified DDC.Core.Transform.SpreadX        as C import qualified DDC.Core.Check                    as C import qualified DDC.Core.Load                     as C import qualified DDC.Core.Lexer                    as C import qualified DDC.Base.Parser                   as BP import qualified DDC.Data.SourcePos                as SP+import qualified DDC.Data.Token                    as Token import Control.DeepSeq  @@ -45,9 +51,12 @@         -> PipeText n err    PipeTextLoadSourceTetra-        :: !Sink                -- Sink for source tokens.-        -> !Sink                -- Sink for core code before final type checking.-        -> !Sink                -- Sink for type checker trace.+        :: !Sink        -- Sink for source tokens.+        -> !Sink        -- Sink for desugared source code.+        -> !Sink        -- Sink for core tetra code after conversoin.+        -> !Sink        -- Sink for core tetra code before type checking.+        -> !Sink        -- Sink for type checker trace.+        -> !Store       -- Interface store.         -> ![PipeCore (C.AnTEC BP.SourcePos CE.Name) CE.Name]         -> PipeText n err @@ -83,29 +92,27 @@          PipeTextLoadSourceTetra                  sinkTokens-                sinkPreCheck -                sinkCheckerTrace pipes+                sinkDesugared sinkCore sinkPreCheck sinkCheckerTrace +                store pipes          -> {-# SCC "PipeTextLoadSourceTetra" #-}-            let goParse+            let +                goParse                  = do   -- Lex the input text into source tokens.                         let tokens  = SE.lexModuleString srcName srcLine str -                        pipeSink (unlines $ map show $ tokens) sinkTokens--                        -- Parse the source tokens.-                        let context = C.Context-                                { C.contextTrackedEffects         = True-                                , C.contextTrackedClosures        = True-                                , C.contextFunctionalEffects      = False-                                , C.contextFunctionalClosures     = False }+                        -- Dump tokens to file.+                        pipeSink (unlines $ map (show . Token.tokenTok) $ tokens) +                                sinkTokens +                        -- Parse the tokens into a Source Tetra module.                         case BP.runTokenParser C.describeTok srcName-                                (SE.pModule context) tokens of+                                (SE.pModule SE.context) tokens of                          Left err -> return [ErrorLoad err]                          Right mm -> goDesugar mm                  goDesugar mm-                 = case SE.defix SE.defaultFixTable mm of+                 =      -- Resolve fixity of infix operators.+                   case SE.defix SE.defaultFixTable mm of                         Left err  -> return [ErrorLoad err]                         Right mm' -> goToCore mm' @@ -114,23 +121,50 @@                         let mm_expand = SE.expand SE.configDefault                                              SE.primKindEnv SE.primTypeEnv mm +                        -- Dump desguared source code.+                        pipeSink (renderIndent $ ppr mm_expand) sinkDesugared+                         -- Convert Source Tetra to Core Tetra.-                        -- This source position is used to annotate the let expression-                        -- that holds all the top-level bindings.-                        let sp        = SP.SourcePos "<top level>" 1 1-                        let mm_core   = SE.toCoreModule sp mm_expand+                        -- This source position is used to annotate the +                        -- let-expression that holds all the top-level bindings.+                        let sp            = SP.SourcePos "<top level>" 1 1+                        case SE.coreOfSourceModule sp mm_expand of+                         Left err+                          -> return [ErrorLoad err] +                         Right mm_core+                          -> do -- Dump Core Tetra.+                                pipeSink (renderIndent $ ppr mm_core) sinkCore++                                -- Discover which module imported names are from, and+                                -- attach the meta-data which will be needed by follow-on+                                -- compilation, such as the arity of each super.+                                result <- B.resolveNamesInModule +                                                CE.primKindEnv CE.primTypeEnv+                                                store mm_core++                                case result of +                                 Left err          -> return [ErrorLoad err]+                                 Right mm_resolved -> goSpread mm_resolved++                goSpread mm+                 = do                         -- Spread types of data constructors into uses.-                        let mm_spread = C.spreadX -                                          CE.primKindEnv CE.primTypeEnv mm_core+                        let mm_spread   = C.spreadX CE.primKindEnv CE.primTypeEnv mm -                        -- Dump code before checking for debugging purposes.+                        -- Dump loaded code before type checking.                         pipeSink (renderIndent $ ppr mm_spread) sinkPreCheck -                        -- Use the existing checker pipeline to Synthesise-                        -- missing type annotations.+                        -- Type check the code, synthesising missing type annotations.+                        --  Insert casts to implicitly run suspended bindings along the way.+                        let fragment_implicit+                                = flip C.mapProfileOfFragment CE.fragment+                                $ C.mapFeaturesOfProfile +                                $ ( C.setFeature C.ImplicitRun True+                                  . C.setFeature C.ImplicitBox True)+                         pipeCore mm_spread-                           $ PipeCoreCheck CE.fragment C.Synth sinkCheckerTrace pipes+                          $ PipeCoreCheck fragment_implicit C.Synth sinkCheckerTrace pipes              in goParse @@ -138,8 +172,5 @@          = case mct of                 Nothing                 -> return []                 Just (C.CheckTrace doc) -> pipeSink (renderIndent doc) sink---  
+ DDC/Build/Spec.hs view
@@ -0,0 +1,9 @@++module DDC.Build.Spec +        ( Spec          (..)+        , Component     (..)+        , specFieldsLibrary)+where+import DDC.Build.Spec.Base++
+ DDC/Build/Spec/Base.hs view
@@ -0,0 +1,73 @@++module DDC.Build.Spec.Base+        ( Spec          (..)+        , Component     (..)+        , specFieldsLibrary)+where+import DDC.Core.Module  (ModuleName)++-- | A build specification.+--   This specifies how to build a particular library or exectutable,+--   and is equivalent to a Haskell Cabal file.+data Spec+        = Spec+        { -- | Version number set by the first line of the file.+          specVersion                   :: String++          -- | Components in this build specification.+        , specComponents                :: [Component] }+        deriving Show+++-- | A build component.+data Component+        = SpecLibrary+        { -- | Name of the library.+          specLibraryName               :: String++          -- | Library version.+        , specLibraryVersion            :: String++          -- | Tetra modules to build, in dependency order.+        , specLibraryTetraModules       :: [ModuleName] ++          -- | Optional library meta-data.+          --   These fields are for informational purposes and are not +          --   nessesary to build the library itself.+        , specLibraryMeta               :: [(String, String)] }+++        | SpecExecutable+        { -- | Name of executable+          specExecutableName            :: String++          -- | Name of main module.+        , specExecutableTetraMain       :: ModuleName++          -- | Tetra modules to build, in dependency order.+        , specExecutableTetraOther      :: [ModuleName] ++          -- | Optional library meta-data.+          --   These fields are for informational purposes and are not +          --   nessesary to build the executable itself.+        , specExecutableMeta            :: [(String, String)] }+        deriving Show+++-------------------------------------------------------------------------------++-- | Names of all allowable fields in library metadata, and whether each+--   field is nessesary or optional.+specFieldsLibrary :: [(String, Bool)]+specFieldsLibrary+ =  [ (str, True)  | str <- +        [ "name"+        , "version"+        , "tetra-modules" ]]++ ++ [ (str, False) | str <-+        [ "author"+        , "maintainer"+        , "homepage"+        , "license"+        , "synopsis" ]]
+ DDC/Build/Spec/Check.hs view
@@ -0,0 +1,11 @@++module DDC.Build.Spec.Check+        (Error(..))+where++-- | Errors that can appear in a Build Spec file.+data Error+        = ErrorUnrecognisedField+        { errorField    :: String+        , errorValue    :: String }+        deriving Show
+ DDC/Build/Spec/Parser.hs view
@@ -0,0 +1,234 @@++-- | Parser for DDC build spec files.+module DDC.Build.Spec.Parser+        ( parseBuildSpec+        , Error(..) )+where+import DDC.Build.Spec.Base+import DDC.Base.Pretty+import Control.Monad+import Data.List+import Data.Char+import Data.Maybe+import qualified DDC.Core.Module        as C+++---------------------------------------------------------------------------------------------------+-- | Problems that can arise when parsing a build spec file.+data Error +        -- | Empty Spec file.+        = ErrorEmpty+        { errorFilePath :: FilePath }++        -- | Parse error in Spec file.+        | ErrorParse+        { errorFilePath :: FilePath +        , errorLine     :: Int }++        -- | Required field is missing.+        | ErrorMissingField+        { errorFilePath :: FilePath+        , errorMissing  :: String }+        deriving Show+++instance Pretty Error where+ ppr err+  = case err of+        ErrorEmpty filePath+         -> vcat [ text filePath+                 , text "Empty file" ]++        ErrorParse filePath n+         -> vcat [ text filePath <> text ":" <> int n+                 , text "Parse error" ]++        ErrorMissingField filePath field+         -> vcat [ text filePath+                 , text "Missing field '" <> text field <> text "'" ]+++---------------------------------------------------------------------------------------------------+type LineNumber = Int+type StartCol   = Int++type Parser a   = [(LineNumber, StartCol, String)]  +                -> Either Error a+++-- | Parse a build specification.+parseBuildSpec :: FilePath -> String -> Either Error Spec+parseBuildSpec path str+ = let  -- Attach line numbers and starting column to each line.+        ls              = lines str+        lsNum           = zip [1..]  ls+        lsNumCols       = attachCols lsNum+   in   pBuildSpec path lsNumCols+++-- | Parse a build specification.+pBuildSpec :: FilePath -> Parser Spec+pBuildSpec path []+        = Left $ ErrorEmpty path++pBuildSpec path ((n, _s, str) : rest)+        -- Skip over blank lines+        | all (\c -> isSpace c || c == '\n') str+        = pBuildSpec path rest++        -- The build spec needs to start with the magic words and version number.+        | ["ddc", "build", version] <- words str+        = do    cs    <- pComponents path rest+                return  $ Spec+                        { specVersion           = version+                        , specComponents        = cs }++        | otherwise+        = Left $ ErrorParse path n+++-- | Parse a build component specification.+pComponents :: FilePath -> Parser [Component]+pComponents _path []+        = return []++pComponents path ((n, start, str) : rest)+        -- skip over blank lines+        | all (\c -> isSpace c || c == '\n') str+        = pComponents path rest++        -- parse a library specification+        | str == "library"+        , (lsLibrary, lsMore) +                <- span (\(_, start', _) -> start' == 0 || start' > start) rest+        = do    fs      <- pLibraryFields path lsLibrary+                more    <- pComponents    path lsMore+                return  $ fs : more++        -- parse an executable specification+        | str == "executable"+        , (lsExecutable, lsMore)+                <- span (\(_, start', _) -> start' == 0 || start' > start) rest+        = do    fs      <- pExecutableFields path lsExecutable+                more    <- pComponents       path lsMore+                return  $ fs : more++        | otherwise+        = Left $ ErrorParse path n+++---------------------------------------------------------------------------------------------------+-- | Parse the fields of a library specification.+pLibraryFields :: FilePath -> Parser Component+pLibraryFields path str+ = do   fs                          <- pFields path str+        (sName,         fs_name)    <- takeField path "name"             fs+        (sVersion,      fs_version) <- takeField path "version"          fs_name+        (sTetraModules, fs_modules) <- takeField path "tetra-modules"    fs_version++        let Just msTetra+                = sequence+                $ map C.readModuleName+                $ words $ sTetraModules++        return  $ SpecLibrary +                { specLibraryName          = sName+                , specLibraryVersion       = sVersion+                , specLibraryTetraModules  = msTetra+                , specLibraryMeta          = fs_modules }+++---------------------------------------------------------------------------------------------------+-- | Parse the fields of an executable specification.+pExecutableFields :: FilePath -> Parser Component+pExecutableFields path str+ = do   fs                          <- pFields path str+        (sName,           fs_name)  <- takeField      path "name"        fs+        (sTetraMain,      fs_main)  <- takeField      path "tetra-main"  fs_name+        let (sTetraOther, fs_other) =  takeFieldMaybe path "tetra-other" fs_main++        let Just mTetraMain+                = C.readModuleName sTetraMain++        let Just msTetra+                = sequence $ map C.readModuleName+                $ concat   $ maybeToList $ liftM words sTetraOther ++        return  $ SpecExecutable+                { specExecutableName       = sName+                , specExecutableTetraMain  = mTetraMain+                , specExecutableTetraOther = msTetra+                , specExecutableMeta       = fs_other }+++---------------------------------------------------------------------------------------------------+-- | Parse fields of a build specification.+pFields  :: FilePath -> Parser [(String, String)]+pFields _path []+        = return []++pFields path ((n, start, str) : rest)+        -- skip over blank lines+        | all (\c -> isSpace c || c == '\n') str+        = pFields path rest+        +        -- parse a single field.+        | (lsField, lsMore)      +                <- span (\(_, start', _) -> start' == 0 || start' > start) rest++        , (fieldName, ':' : fieldValue) +                <- span (\c -> c /= ':') +                $  str ++ concat [ s | (_, _, s) <- lsField]++        = do    let f   =  (chomp fieldName, chomp fieldValue)+                more    <- pFields path lsMore+                return  $ f : more++        | otherwise+        = Left $ ErrorParse path n+++-- | Take a named field from this list of fields.+takeField :: FilePath+          -> String -> [(String, String)] +          -> Either Error (String, [(String, String)])++takeField path name fs+ = case lookup name fs of+        Nothing -> Left $ ErrorMissingField path name+        Just s  -> return (s, delete (name, s) fs)+++-- | Take a named field from this list of fields.+takeFieldMaybe +        :: FilePath+        -> String -> [(String, String)] +        -> (Maybe String, [(String, String)])++takeFieldMaybe _path name fs+ = case lookup name fs of+        Nothing -> (Nothing, fs)+        Just s  -> (Just s,  delete (name, s) fs)+++---------------------------------------------------------------------------------------------------+-- | Attach starting column number to these lines.+attachCols +        :: [(LineNumber, String)] +        -> [(LineNumber, StartCol, String)]++attachCols lstrs+ = [ (ln, startCol 1 str, str) | (ln, str) <- lstrs ]+ where  startCol n ss  +         = case ss of+                []              -> 0+                ' '  : ss'      -> startCol (n + 1) ss'+                '\t' : ss'      -> startCol (n + 8) ss'+                _    : _        -> n+++-- | Remove whitespace from the beginning and end of a string.+chomp :: String -> String+chomp str+        = reverse $ dropWhile isSpace $ reverse $ dropWhile isSpace str+
+ DDC/Build/Transform/Resolve.hs view
@@ -0,0 +1,186 @@++-- | Gather up the set of free names and try to find matching export statements+--   in the imported modules. Add explicit imports that refer to the module where+--   each name is bound.+module DDC.Build.Transform.Resolve+        ( resolveNamesInModule )+where+import DDC.Core.Module+import DDC.Core.Exp+import DDC.Core.Collect.Support+import DDC.Type.DataDef+import DDC.Type.Env                             (KindEnv, TypeEnv)+import DDC.Base.Pretty+import DDC.Base.Panic+import Data.Map                                 (Map)+import DDC.Build.Interface.Store                (Store)+import DDC.Build.Interface.Base                 (Interface (..))+import qualified Data.Map                       as Map+import qualified Data.Set                       as Set+import qualified DDC.Build.Interface.Store      as Store+import qualified DDC.Core.Tetra                 as E+import Data.List+import Data.Function+++-- | For all the names that are free in this module, if there is a+--   corresponding export in one of the modules in the given map,+--   then add the appropriate import definition.+resolveNamesInModule +        :: KindEnv E.Name       -- ^ Kinds of primitive types.+        -> TypeEnv E.Name       -- ^ Types of primitive values.+        -> Store                -- ^ Interface store.+        -> Module a E.Name      -- ^ Module to resolve names in.+        -> IO (Either [Error] (Module a E.Name))++resolveNamesInModule kenv tenv store mm+ = do+        let sp      = support kenv tenv mm+        ints    <- Store.getInterfaces store+        let deps    = Map.fromList +                        [ ( interfaceModuleName i+                          , let Just m = interfaceTetraModule i in m)+                          | i <- ints ]+        modNames       <- Store.getModuleNames store++        let getDaVarImport (UName n) = do+                eImport <- findImportSourceForDaVar store modNames n+                case eImport of+                 Left err       -> return $ Left err+                 Right isrc     -> return $ Right (n, isrc)++            getDaVarImport u    =   panic "ddc-build" "resolveNamesInModule"+                                $   text  "Cannot resolve anonymous binder:"+                                <+> ppr u++        eimportsDaVar   <- mapM getDaVarImport $ Set.toList $ supportDaVar sp++        case sequence eimportsDaVar of+         Left err       -> return $ Left [err]++         Right importsDaVar+          -> return $ Right $ mm +           { moduleImportTypes   +                =  moduleImportTypes  mm +                ++ importsForTyCons   deps (Set.toList $ supportTyCon sp)++           , moduleImportDataDefs+                =  nubBy ((==) `on` dataDefTypeName)          +                $  moduleImportDataDefs mm +                ++ importsForDaTyCons deps (Set.toList $ supportTyCon sp)++           , moduleImportCaps+                = moduleImportCaps mm+                ++ importsCap deps++           , moduleImportValues  +                =  moduleImportValues mm +                ++ importsDaVar }+++---------------------------------------------------------------------------------------------------+-- | Import tycons defined in other modules.+importsForTyCons+        :: Ord n+        => Map ModuleName (Module b n)  -- ^ Modules which this one depends on.+        -> [Bound n]                    -- ^ Unbound type constructors to find imports for.+        -> [(n, ImportType n)]++importsForTyCons deps _tyCons+ = concat+        [ [(n, ImportTypeAbstract k)+                | (n, k)        <- Map.toList $ Map.unions +                                $  map importedTyConsAbs   $ Map.elems deps]++        , [(n, ImportTypeAbstract k)+                | (n, (_, k))   <- Map.toList $ Map.unions +                                $  map exportedTyConsLocal $ Map.elems deps]++        , [(n, ImportTypeBoxed k) +                | (n, k)        <- Map.toList $ Map.unions +                                $  map importedTyConsBoxed $ Map.elems deps] ]+++---------------------------------------------------------------------------------------------------+-- | Import caps defined in other modules.+importsCap+        :: Ord n+        => Map ModuleName (Module b n)+        -> [(n, ImportCap n)]++importsCap deps+ = concatMap moduleImportCaps $ Map.elems deps+++---------------------------------------------------------------------------------------------------+-- | Import data defs defined in other modules.+importsForDaTyCons+        :: Ord n+        => Map ModuleName (Module b n)+        -> [Bound n]+        -> [DataDef n]++importsForDaTyCons deps _tycons+        = concat+        $ [ moduleImportDataDefs m ++ moduleDataDefsLocal m+                | m <- Map.elems deps ]+++---------------------------------------------------------------------------------------------------+-- | Build import statements for the given list of unbound value variables.+--+--   We look in dependency modules for a matching export, +--   and produce the corresponding import statement to use it.+--+findImportSourceForDaVar+        :: Store                -- ^ Interface store.+        -> [ModuleName]         -- ^ Modules to search for matching exports.+        -> E.Name               -- ^ Name of value.+        -> IO (Either Error (ImportValue E.Name))++findImportSourceForDaVar store modNames nSuper+ = do   result  <- Store.findSuper store nSuper modNames+        case result of+         []      -> return $ Left  $ ErrorNotFound nSuper+         [super] -> return $ Right $ Store.superImportValue super+         supers  -> return $ Left  $ ErrorMultiple nSuper (map Store.superModuleName supers)+++---------------------------------------------------------------------------------------------------+-- | Get the tycons that are locally defined, then exported by a module.+exportedTyConsLocal :: Ord n => Module b n -> Map n (ModuleName, Kind n)+exportedTyConsLocal mm+        = Map.fromList+        $ [ (n, (moduleName mm, t)) +                        | (n, ExportSourceLocal _ t) <- moduleExportTypes mm ]++-- | Get the type constructors that are imported abstractly by a module.+importedTyConsAbs  :: Ord n => Module b n -> Map n (Kind n)+importedTyConsAbs mm+        = Map.fromList+        $ [ (n, k)      | (n, ImportTypeAbstract k)  <- moduleImportTypes mm ]+++-- | Get the type constructors that are imported as boxed foreign types.+importedTyConsBoxed :: Ord n => Module b n -> Map n (Kind n)+importedTyConsBoxed mm+        = Map.fromList+        $ [ (n, k)      | (n, ImportTypeBoxed k)      <- moduleImportTypes mm ]+++---------------------------------------------------------------------------------------------------+-- | Problems that can be uncovered when resolving names.+data Error+        = ErrorNotFound E.Name+        | ErrorMultiple E.Name [ModuleName]++instance Pretty Error where+ ppr err+  = case err of+        ErrorNotFound n+         -> vcat [ text "Not in scope: " <> squotes (ppr n) ]++        ErrorMultiple n ms+         -> vcat $  [ text "Variable" <+> squotes (ppr n) <+> text "defined in multiple modules:" ]+                 ++ (map ppr ms)+         
ddc-build.cabal view
@@ -1,5 +1,5 @@ Name:           ddc-build-Version:        0.4.1.3+Version:        0.4.2.1 License:        MIT License-file:   LICENSE Author:         The Disciplined Disciple Compiler Strike Force@@ -14,27 +14,30 @@  Library   Build-depends:-        base             >= 4.6 && < 4.8,+        base             >= 4.6 && < 4.9,         process          >= 1.1 && < 1.3,-        deepseq          == 1.3.*,+        deepseq          >= 1.3 && < 1.5,         containers       == 0.5.*,-        filepath         == 1.3.*,+        filepath         >= 1.3 && < 1.5,         directory        == 1.2.*,-        mtl              == 2.2.*,-        ddc-base         == 0.4.1.*,-        ddc-core         == 0.4.1.*,-        ddc-core-eval    == 0.4.1.*,-        ddc-core-simpl   == 0.4.1.*,-        ddc-core-salt    == 0.4.1.*,-        ddc-core-llvm    == 0.4.1.*,-        ddc-core-flow    == 0.4.1.*,-        ddc-core-tetra   == 0.4.1.*,-        ddc-source-tetra == 0.4.1.*+        mtl              == 2.2.1.*,+        time             >= 1.4 && < 1.6,+        ddc-base         == 0.4.2.*,+        ddc-core         == 0.4.2.*,+        ddc-core-simpl   == 0.4.2.*,+        ddc-core-salt    == 0.4.2.*,+        ddc-core-llvm    == 0.4.2.*,+        ddc-core-flow    == 0.4.2.*,+        ddc-core-tetra   == 0.4.2.*,+        ddc-core-babel   == 0.4.2.*,+        ddc-source-tetra == 0.4.2.*      Exposed-modules:-        DDC.Build.Language.Eval+        DDC.Build.Interface.Base+        DDC.Build.Interface.Load+        DDC.Build.Interface.Store+         DDC.Build.Language.Flow-        DDC.Build.Language.Lite         DDC.Build.Language.Salt         DDC.Build.Language.Tetra         DDC.Build.Language.Zero@@ -46,13 +49,19 @@         DDC.Build.Pipeline.Sink         DDC.Build.Pipeline.Text         +        DDC.Build.Spec.Check+        DDC.Build.Spec.Parser+         DDC.Build.Builder         DDC.Build.Language         DDC.Build.Pipeline         DDC.Build.Platform+        DDC.Build.Spec            Other-modules:         DDC.Build.Language.Base+        DDC.Build.Spec.Base+        DDC.Build.Transform.Resolve    Extensions:         BangPatterns@@ -65,6 +74,7 @@         KindSignatures         RankNTypes         DeriveDataTypeable+        ScopedTypeVariables    ghc-options:         -Wall