diff options
| -rw-r--r-- | .gitignore | 5 | ||||
| -rw-r--r-- | LibLang.hs | 9 | ||||
| -rw-r--r-- | Main.hs | 55 | ||||
| -rw-r--r-- | Makefile | 29 | ||||
| -rw-r--r-- | langhs.cabal | 47 | 
5 files changed, 93 insertions, 52 deletions
@@ -1,5 +1,2 @@ -main -obj -obsolete  z_output* -liblang.o +dist-newstyle/ diff --git a/LibLang.hs b/LibLang.hs new file mode 100644 index 0000000..3ca54ed --- /dev/null +++ b/LibLang.hs @@ -0,0 +1,9 @@ +{-# LANGUAGE TemplateHaskell #-} +module LibLang where + +import Data.ByteString (ByteString) +import Data.FileEmbed + + +libLangSource :: ByteString +libLangSource = $(embedFile "liblang.asm") @@ -2,16 +2,19 @@ module Main where  import Control.Exception (bracket)  import Control.Monad +import qualified Data.ByteString as BS  import System.Directory (removeFile)  import System.Environment  import System.Exit  import System.IO  import System.Process  import qualified System.Posix.Temp as Posix +import qualified System.Info as System  import BuildIR  import CodeGen  import Defs +import LibLang  import Optimiser  import OptionParser  import Pretty @@ -51,6 +54,9 @@ mkTempFile = do      hClose handle      return path +withTempFile :: (FilePath -> IO a) -> IO a +withTempFile = bracket mkTempFile removeFile +  main :: IO ()  main = do      opts <- getArgs >>= eitherToIO . optionParser @@ -103,27 +109,38 @@ main = do          exitSuccess -    let objfnameIO = case laststage of -            StageObject -> return outname -            StageExecutable -> mkTempFile +    let withObjfile = case laststage of +            StageObject -> ($ outname) +            StageExecutable -> withTempFile              _ -> undefined -    let rmObjfileIO = case outname of -            "-" -> const $ return () -            _ -> removeFile +    let yasmFormat = case System.os of +            "linux" -> "elf64" +            "darwin" -> "macho64" +            os -> error $ "Your OS (" ++ os ++ ") is unknown, can't create binary" + +    let yasmToFile outfname writer = do +            let yasmprocspec = +                    (proc "yasm" ["-w+all", "-f" ++ yasmFormat, "-", "-o", outfname]) +                        {std_in = CreatePipe} +            yasmcode <- withCreateProcess yasmprocspec $ \(Just pipe) _ _ ph -> do +                _ <- writer pipe +                hFlush pipe +                hClose pipe +                waitForProcess ph +            case yasmcode of +                ExitSuccess -> return () +                ExitFailure _ -> die "yasm failed!" -    bracket objfnameIO rmObjfileIO $ \objfname -> do +    withObjfile $ \objfname -> do          hPutStrLn stderr "Assembling with yasm..." -        let yasmprocspec = (proc "yasm" ["-w+all", "-fmacho64", "-", "-o", objfname]) {std_in = CreatePipe} -        yasmcode <- withCreateProcess yasmprocspec $ \(Just pipe) _ _ ph -> do -            hPutStr pipe asm -            hFlush pipe -            hClose pipe -            waitForProcess ph -        case yasmcode of -            ExitSuccess -> return () -            ExitFailure _ -> die "yasm failed!" -        when (laststage == StageObject) exitSuccess +        yasmToFile objfname (\pipe -> hPutStr pipe asm) -        hPutStrLn stderr "Linking with ld..." -        callProcess "ld" [objfname, "liblang.o", "-o", outname] +        case laststage of +            StageObject -> return () +            StageExecutable -> +                withTempFile $ \liblangfname -> do +                    yasmToFile liblangfname (\pipe -> BS.hPut pipe libLangSource) +                    hPutStrLn stderr "Linking with ld..." +                    callProcess "ld" [objfname, liblangfname, "-o", outname] +            _ -> undefined diff --git a/Makefile b/Makefile deleted file mode 100644 index 5602120..0000000 --- a/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -RUNFLAGS = -GHCFLAGS = -Wall -Widentities -Wno-unused-imports -odir obj -hidir obj -j4 -ifneq ($(PROFILE),) -	RUNFLAGS += +RTS -xc -	GHCFLAGS += -prof -fprof-auto -else -	GHCFLAGS += -O3 -endif - -TARGET = main - -.PHONY: all clean run - -all: $(TARGET) liblang.o - -clean: -	rm -f $(TARGET) -	rm -rf obj - -run: $(TARGET) -	./$(TARGET) $(RUNFLAGS) - - -$(TARGET): $(wildcard *.hs) -	@mkdir -p obj -	ghc $(GHCFLAGS) Main.hs -o $@ - -liblang.o: liblang.asm -	yasm -w+all -fmacho64 $< -o $@ diff --git a/langhs.cabal b/langhs.cabal new file mode 100644 index 0000000..73ac567 --- /dev/null +++ b/langhs.cabal @@ -0,0 +1,47 @@ +cabal-version:       >=1.10 +name:                langhs +synopsis:            Compiler for a made-up language to x64 +version:             0.1.0.0 +license:             MIT +author:              Tom Smeding +maintainer:          tom@tomsmeding.com +build-type:          Simple + +executable langhs +  main-is:             Main.hs +  other-modules: +    AST +    BuildIR +    CodeGen +    Defs +    Intermediate +    LibLang +    -- LifetimeAnalysis2 +    LifetimeAnalysis +    LifetimeAnalysisOld +    Optimiser +    OptionParser +    Pretty +    ProgramParser +    RegAlloc +    ReplaceRefs +    TypeCheck +    TypeRules +    Utils +    Verify +    X64 +    X64Optimiser +  build-depends:       base >= 4.13 && < 4.15, +                       parsec >= 3.1 && < 3.2, +                       mtl >= 2.2 && < 2.3, +                       containers >= 0.6 && < 0.7, +                       directory >= 1.3 && < 1.4, +                       process >= 1.6 && < 1.7, +                       unix >= 2.7 && < 2.8, +                       bytestring, +                       -- vector >= 0.12 && < 0.13, +                       -- primitive >= 0.7 && < 0.8, +                       file-embed >= 0.0.13 && < 0.0.14 +  hs-source-dirs:      . +  default-language:    Haskell2010 +  ghc-options:         -Wall -O2 -threaded -Widentities -Wno-unused-imports  | 
