From 5f4025110947f853fdb2347773a08e562387d3ed Mon Sep 17 00:00:00 2001 From: Azim Muradov Date: Fri, 21 Jun 2024 18:42:34 +0300 Subject: [PATCH 1/8] Move to the new LLVM - Use `llvm-codegen` - Use LLVM 17 - Use GHC 9.4.8 - Use cabal 3.8 --- .github/workflows/build.yml | 8 +- .github/workflows/docs.yml | 8 +- app/Commands/Compile.hs | 15 ++- app/Commands/Run.hs | 5 +- app/Utils.hs | 8 -- cabal.project | 6 + cabal.project.freeze | 92 +++++++-------- lib/CodeGen/Llvm/LlvmIrGen.hs | 47 ++++---- lib/CodeGen/Llvm/Runner.hs | 29 +++-- lib/CodeGen/Module.hs | 13 +-- miniml.cabal | 208 +++++++++++++++++----------------- test/Sample/Utils.hs | 4 +- test/Utils.hs | 10 +- 13 files changed, 219 insertions(+), 234 deletions(-) create mode 100644 cabal.project diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 600a640..bf47d23 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,9 +12,9 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-20.04] - ghc: ["8.10.7"] - cabal: ["3.6"] + os: [ubuntu-22.04] + ghc: ["9.4.8"] + cabal: ["3.8"] steps: - name: Checkout code @@ -46,7 +46,7 @@ jobs: pattern: "**/*.hs" version: 0.3.1.0 - name: Install LLVM - run: sudo apt install -y llvm-9 llvm-9-dev + run: sudo apt install -y llvm-17 llvm-17-dev - name: Build project run: cabal build - name: Run tests diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 9b173d0..4666d60 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -11,9 +11,9 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-20.04] - ghc: ["8.10.7"] - cabal: ["3.6"] + os: [ubuntu-22.04] + ghc: ["9.4.8"] + cabal: ["3.8"] steps: - name: Checkout code @@ -34,7 +34,7 @@ jobs: key: ${{ runner.os }}-docs-${{ env.cache-name }}-${{ hashFiles('**/*.cabal') }}-${{ hashFiles('**/cabal.project') }} restore-keys: ${{ runner.os }}-docs-${{ env.cache-name }}- - name: Install LLVM - run: sudo apt install -y llvm-9 llvm-9-dev + run: sudo apt install -y llvm-17 llvm-17-dev - name: Build docs run: > cabal haddock diff --git a/app/Commands/Compile.hs b/app/Commands/Compile.hs index eaa5bb4..1d634bc 100644 --- a/app/Commands/Compile.hs +++ b/app/Commands/Compile.hs @@ -1,16 +1,18 @@ +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} module Commands.Compile (compile) where import CodeGen.Llvm.Runner (compileToBinary, compileToLlvmIr) import CodeGen.TimedValue (TimedValue (TimedValue)) -import Configuration.AppConfiguration (CompilationTarget (..), Compile (..), Debug (Yes), Output (..)) +import Configuration.AppConfiguration (CompilationTarget (..), Compile (..), Debug (Yes), Input (..), Output (..)) import Control.Monad (when) import Data.Text (Text) import qualified Data.Text as Txt import System.Exit (die) +import System.FilePath (takeBaseName) import qualified Text.Printf as Printf -import Utils (inputToModuleName, ns2s, readText) +import Utils (ns2s, readText) compile :: Compile -> Debug -> IO () compile (Compile input target output) debug = do @@ -20,10 +22,10 @@ compile (Compile input target output) debug = do TimedValue res compTime <- case target of TargetBinary -> do let outputFilePath = outputToFilePath output moduleName "out" - compileToBinary moduleName text outputFilePath + compileToBinary text outputFilePath TargetLlvmIr -> do let outputFilePath = outputToFilePath output moduleName "ll" - compileToLlvmIr moduleName text outputFilePath + compileToLlvmIr text outputFilePath when (debug == Yes) $ do putStrLn $ Printf.printf "Finished compiling in %0.5f sec" (ns2s compTime) @@ -31,6 +33,11 @@ compile (Compile input target output) debug = do either (die . Txt.unpack) return res +inputToModuleName :: Input -> Text +inputToModuleName = \case + StdInput -> "unnamed" + FileInput filePath -> Txt.pack $ takeBaseName filePath + outputToFilePath :: Output -> Text -> Text -> FilePath outputToFilePath output moduleName ext = case output of FileOutput filePath -> filePath diff --git a/app/Commands/Run.hs b/app/Commands/Run.hs index 8e27f20..6aa8b5b 100644 --- a/app/Commands/Run.hs +++ b/app/Commands/Run.hs @@ -11,14 +11,13 @@ import System.Exit (ExitCode (..), die, exitWith) import System.IO (hPutStr) import qualified System.IO as Sys import qualified Text.Printf as Printf -import Utils (inputToModuleName, ns2s, readText) +import Utils (ns2s, readText) run :: Run -> Debug -> IO () run (Run input) debug = do - let moduleName = inputToModuleName input text <- readText input - runResult <- Llvm.run moduleName text + runResult <- Llvm.run text case runResult of Success stdout compTime runTime -> do diff --git a/app/Utils.hs b/app/Utils.hs index 5182d37..ec00408 100644 --- a/app/Utils.hs +++ b/app/Utils.hs @@ -1,6 +1,4 @@ -{-# LANGUAGE LambdaCase #-} {-# LANGUAGE NumericUnderscores #-} -{-# LANGUAGE OverloadedStrings #-} module Utils where @@ -8,16 +6,10 @@ import CodeGen.TimedValue (Nanoseconds (..)) import Configuration.AppConfiguration (Input (..)) import Data.Text (Text) import qualified Data.Text as Txt -import System.FilePath (takeBaseName) readText :: Input -> IO Text readText (FileInput path) = Txt.pack <$> readFile path readText StdInput = Txt.pack <$> getContents -inputToModuleName :: Input -> Text -inputToModuleName = \case - StdInput -> "unnamed" - FileInput filePath -> Txt.pack $ takeBaseName filePath - ns2s :: Nanoseconds -> Double ns2s ns = let Nanoseconds ns' = ns in fromInteger ns' / 1_000_000_000 diff --git a/cabal.project b/cabal.project new file mode 100644 index 0000000..ffadd11 --- /dev/null +++ b/cabal.project @@ -0,0 +1,6 @@ +source-repository-package + type: git + location: https://github.com/luc-tielen/llvm-codegen.git + tag: 83b04cb576208ea74ddd62016e4fa03f0df138ac + +packages: . diff --git a/cabal.project.freeze b/cabal.project.freeze index edf61ee..ba7ba67 100644 --- a/cabal.project.freeze +++ b/cabal.project.freeze @@ -1,23 +1,21 @@ active-repositories: hackage.haskell.org:merge -constraints: any.Cabal ==3.6.3.0, - Cabal -bundled-binary-generic, +constraints: any.Cabal ==3.8.1.0, + any.Cabal-syntax ==3.8.1.0, any.StateVar ==1.2.2, - any.ansi-terminal ==1.0, + any.ansi-terminal ==1.1.1, ansi-terminal -example, - any.ansi-terminal-types ==0.11.5, + any.ansi-terminal-types ==1.1, any.array ==0.5.4.0, - any.assoc ==1.1, - assoc +tagged, + any.assoc ==1.1.1, + assoc -tagged, any.async ==2.2.5, async -bench, - any.attoparsec ==0.14.4, - attoparsec -developer, - any.base ==4.14.3.0, - any.base-orphans ==0.9.1, - any.bifunctors ==5.6.1, + any.base ==4.17.2.1, + any.base-orphans ==0.9.2, + any.bifunctors ==5.6.2, bifunctors +tagged, any.binary ==0.8.9.1, - any.bytestring ==0.11.2.0, + any.bytestring ==0.11.5.3, any.cabal-doctest ==1.0.9, any.call-stack ==0.4.0, any.case-insensitive ==1.2.1.0, @@ -26,44 +24,41 @@ constraints: any.Cabal ==3.6.3.0, any.colour ==2.3.6, any.comonad ==5.0.8, comonad +containers +distributive +indexed-traversable, - any.containers ==0.6.8, + any.containers ==0.6.7, any.contravariant ==1.5.5, contravariant +semigroups +statevar +tagged, - any.data-array-byte ==0.1.0.1, - any.data-fix ==0.3.2, - any.deepseq ==1.4.4.0, + any.data-fix ==0.3.3, + any.deepseq ==1.4.8.0, any.directory ==1.3.7.1, any.distributive ==0.6.2.1, distributive +semigroups +tagged, - any.exceptions ==0.10.4, - any.extra ==1.7.14, - any.fail ==4.9.0.0, - any.file-embed ==0.0.15.0, - any.filepath ==1.4.2.1, + any.dlist ==1.0, + dlist -werror, + any.exceptions ==0.10.5, + any.extra ==1.7.16, + any.file-embed ==0.0.16.0, + any.filepath ==1.4.2.2, any.foldable1-classes-compat ==0.1, foldable1-classes-compat +tagged, any.free ==5.2, - any.ghc-boot-th ==8.10.7, - any.ghc-prim ==0.6.1, - any.hashable ==1.4.3.0, - hashable +integer-gmp -random-initial-seed, - any.hsc2hs ==0.68.10, - hsc2hs -in-ghc-tree, - any.indexed-traversable ==0.1.3, - any.integer-gmp ==1.0.3.0, + any.ghc-bignum ==1.3, + any.ghc-boot-th ==9.4.8, + any.ghc-prim ==0.9.1, + any.hashable ==1.4.6.0, + hashable +arch-native +integer-gmp -random-initial-seed, + any.indexed-traversable ==0.1.4, any.integer-logarithms ==1.0.3.1, integer-logarithms -check-bounds +integer-gmp, - any.llvm-hs ==9.0.1, - llvm-hs -debug +shared-llvm, - any.llvm-hs-pretty ==0.9.0.0, - any.llvm-hs-pure ==9.0.0, + any.llvm-codegen ==0.1.0.0, any.logict ==0.8.0.0, - any.megaparsec ==9.2.1, + any.megaparsec ==9.6.1, megaparsec -dev, + any.mmorph ==1.2.0, any.mtl ==2.2.2, any.optparse-applicative ==0.18.1.0, optparse-applicative +process, - any.parsec ==3.1.17.0, + any.os-string ==2.0.3, + any.parsec ==3.1.16.1, any.parser-combinators ==1.3.0, parser-combinators -dev, any.pretty ==1.1.3.6, @@ -75,17 +70,18 @@ constraints: any.Cabal ==3.6.3.0, any.primitive ==0.9.0.0, any.process ==1.6.18.0, any.profunctors ==5.6.2, - any.random ==1.2.1.1, - any.recursion-schemes ==5.2.2.5, + any.quote-quot ==0.2.1.0, + any.random ==1.2.1.2, + any.recursion-schemes ==5.2.3, recursion-schemes +template-haskell, - any.rts ==1.0.1, - any.scientific ==0.3.7.0, - scientific -bytestring-builder -integer-simple, - any.semigroupoids ==6.0.0.1, + any.rts ==1.0.2, + any.scientific ==0.3.8.0, + scientific -integer-simple, + any.semigroupoids ==6.0.1, semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers, any.splitmix ==0.1.0.5, splitmix -optimised-mixer, - any.stm ==2.5.0.1, + any.stm ==2.5.1.0, any.string-conversions ==0.4.0.1, any.string-transform ==1.1.1, any.tagged ==0.8.8, @@ -95,12 +91,12 @@ constraints: any.Cabal ==3.6.3.0, any.tasty-golden ==2.3.5, tasty-golden -build-example, any.tasty-hunit ==0.10.1, - any.template-haskell ==2.16.0.0, + any.template-haskell ==2.19.0.0, any.temporary ==1.3, any.text ==2.0.2, - text -developer +simdutf, - any.th-abstraction ==0.6.0.0, - any.time ==1.9.3, + any.text-builder-linear ==0.1.2, + any.th-abstraction ==0.7.0.0, + any.time ==1.12.2, any.transformers ==0.5.6.2, any.transformers-base ==0.4.6, transformers-base +orphaninstances, @@ -110,7 +106,7 @@ constraints: any.Cabal ==3.6.3.0, any.unification-fd ==0.11.2, any.unix ==2.7.3, any.unliftio-core ==0.2.1.0, - any.unordered-containers ==0.2.19.1, + any.unordered-containers ==0.2.20, unordered-containers -debug, any.utf8-string ==1.0.2 -index-state: hackage.haskell.org 2024-01-02T19:29:37Z +index-state: hackage.haskell.org 2024-06-20T07:22:15Z diff --git a/lib/CodeGen/Llvm/LlvmIrGen.hs b/lib/CodeGen/Llvm/LlvmIrGen.hs index 2e579a1..43f83d4 100644 --- a/lib/CodeGen/Llvm/LlvmIrGen.hs +++ b/lib/CodeGen/Llvm/LlvmIrGen.hs @@ -11,19 +11,10 @@ import Control.Monad.State (MonadState, State, evalState, gets, modify) import Data.Map (Map) import qualified Data.Map as Map import Data.String.Conversions (cs) -import Data.String.Transform (toShortByteString) import Data.Text (Text) import qualified Data.Text as Txt import Foreign (fromBool) -import qualified LLVM.AST as LLVM hiding (function) -import qualified LLVM.AST.Constant as C -import qualified LLVM.AST.IntegerPredicate as LLVM -import qualified LLVM.AST.Type as LLVM -import qualified LLVM.IRBuilder.Constant as LLVM -import qualified LLVM.IRBuilder.Instruction as LLVM -import qualified LLVM.IRBuilder.Module as LLVM -import qualified LLVM.IRBuilder.Monad as LLVM -import LLVM.Pretty (ppllvm) +import qualified LLVM.Codegen as LLVM import MonadUtils (locally) import qualified StdLib import Transformations.Anf.Anf @@ -35,7 +26,7 @@ genLlvmIrModule :: Module -> LLVM.Module genLlvmIrModule = genModule ppLlvmModule :: LLVM.Module -> Text -ppLlvmModule = cs . ppllvm +ppLlvmModule = cs . LLVM.ppllvm -- * Implementation @@ -50,8 +41,8 @@ data Env = Env } genModule :: Module -> LLVM.Module -genModule (Module name (Program decls)) = flip evalState (Env Map.empty Map.empty Map.empty) $ - LLVM.buildModuleT (toShortByteString name) $ do +genModule (Module (Program decls)) = flip evalState (Env Map.empty Map.empty Map.empty) $ + LLVM.runModuleBuilderT $ do mapM_ genStdLibDecl StdLib.allDeclsWithArity mapM_ genGlobDecl decls @@ -74,7 +65,7 @@ genStdLibDecl decl = declareAsExtern decl >>= register decl declareAsExtern :: StdLib.DeclarationWithArity -> Llvm LLVM.Operand declareAsExtern (ident, arity) = LLVM.extern - (LLVM.mkName $ Txt.unpack ident) + (LLVM.Name ident) (replicate arity LLVM.i64) LLVM.i64 @@ -84,14 +75,14 @@ genStdLibDecl decl = declareAsExtern decl >>= register decl genGlobDecl :: GlobalDeclaration -> Llvm () genGlobDecl = \case GlobVarDecl ident _ -> do - var <- LLVM.global (LLVM.mkName $ genId ident) LLVM.i64 (C.Int 64 0) + var <- LLVM.global (LLVM.Name $ Txt.pack $ genId ident) LLVM.i64 (LLVM.Int 64 0) regGlobVar ident var GlobFunDecl ident params body -> mdo regFun ident fun (length params) fun <- locally $ do LLVM.function - (LLVM.mkName $ genId ident) - ((LLVM.i64,) . LLVM.ParameterName . toShortByteString . genId <$> params) + (LLVM.Name $ Txt.pack $ genId ident) + ((LLVM.i64,) . LLVM.ParameterName . Txt.pack . genId <$> params) LLVM.i64 $ \args -> do mapM_ (uncurry regLocVar) (params `zip` args) @@ -109,7 +100,7 @@ genExpr = \case ExprAtom atom -> genAtom atom ExprComp ce -> genComp ce ExprLetIn (ident, val) expr -> do - val' <- genExpr val `LLVM.named` toShortByteString (genId ident) + val' <- genExpr val regLocVar ident val' genExpr expr @@ -126,22 +117,22 @@ genComp = \case f' <- findAny f arg' <- genAtom arg applyF <- findFun (Txt "miniml_apply") - LLVM.call applyF [(f', []), (arg', [])] + LLVM.call applyF [f', arg'] CompIte c t e -> mdo rv <- allocate' c' <- genAtom c >>= intToBool LLVM.condBr c' tBlock eBlock - tBlock <- LLVM.block `LLVM.named` "if.then" + tBlock <- LLVM.blockNamed "if.then" store' rv =<< genExpr t LLVM.br end - eBlock <- LLVM.block `LLVM.named` "if.else" + eBlock <- LLVM.blockNamed "if.else" store' rv =<< genExpr e LLVM.br end - end <- LLVM.block `LLVM.named` "if.end" + end <- LLVM.blockNamed "if.end" load' rv CompBinOp op lhs rhs -> do @@ -156,7 +147,7 @@ genComp = \case ArithOp DivOp -> ( \lhs'' rhs'' -> do divF <- findFun (Txt "miniml_div") - LLVM.call divF [(lhs'', []), (rhs'', [])] + LLVM.call divF [lhs'', rhs''] ) CompOp cOp -> let cOpF = case cOp of @@ -187,24 +178,24 @@ findAny ident = do Just (fun, arity) -> do funToPafF <- findFun (Txt "miniml_fun_to_paf") fun' <- LLVM.ptrtoint fun LLVM.i64 - LLVM.call funToPafF [(fun', []), (LLVM.int64 (toInteger arity), [])] + LLVM.call funToPafF [fun', LLVM.int64 (toInteger arity)] Nothing -> load' =<< findGlobVar ident -findGlobVar :: MonadState Env m => Identifier' -> m LLVM.Operand +findGlobVar :: (MonadState Env m) => Identifier' -> m LLVM.Operand findGlobVar ident = gets ((Map.! ident) . globVars) findFun :: Identifier' -> CodeGenM LLVM.Operand findFun ident = gets (fst . (Map.! ident) . funs) -regLocVar :: MonadState Env m => Identifier' -> LLVM.Operand -> m () +regLocVar :: (MonadState Env m) => Identifier' -> LLVM.Operand -> m () regLocVar ident var = modify $ \env -> env {locVars = Map.insert ident var (locVars env)} -regGlobVar :: MonadState Env m => Identifier' -> LLVM.Operand -> m () +regGlobVar :: (MonadState Env m) => Identifier' -> LLVM.Operand -> m () regGlobVar ident gVar = modify $ \env -> env {globVars = Map.insert ident gVar (globVars env)} -regFun :: MonadState Env m => Identifier' -> LLVM.Operand -> Arity -> m () +regFun :: (MonadState Env m) => Identifier' -> LLVM.Operand -> Arity -> m () regFun ident fun paramsCnt = modify $ \env -> env {funs = Map.insert ident (fun, paramsCnt) (funs env)} diff --git a/lib/CodeGen/Llvm/Runner.hs b/lib/CodeGen/Llvm/Runner.hs index ba0b623..e1002d2 100644 --- a/lib/CodeGen/Llvm/Runner.hs +++ b/lib/CodeGen/Llvm/Runner.hs @@ -11,7 +11,6 @@ import Control.Monad.Except (Except, runExcept) import Data.FileEmbed (embedFile, makeRelativeToProject) import Data.String.Conversions (cs) import Data.Text (Text) -import qualified Data.Text as Txt import qualified Data.Text.Encoding as Txt import qualified Data.Text.IO as Txt import System.Directory (removePathForcibly, withCurrentDirectory) @@ -20,9 +19,9 @@ import System.IO (IOMode (WriteMode), hClose, withFile) import System.Posix.Temp (mkdtemp, mkstemps) import System.Process (callProcess, readProcessWithExitCode) -run :: Text -> Text -> IO RR.RunResult -run moduleName text = do - TimedValue compResult compTime <- compileToBinary moduleName text outputFilePath +run :: Text -> IO RR.RunResult +run text = do + TimedValue compResult compTime <- compileToBinary text outputFilePath case compResult of Right () -> do @@ -50,7 +49,7 @@ run moduleName text = do } where outputFilePath :: FilePath - outputFilePath = "./" <> Txt.unpack moduleName + outputFilePath = "./program" runCompiledModule :: IO (TimedValue (Either (String, String, Int) String)) runCompiledModule = do @@ -64,15 +63,15 @@ run moduleName text = do return measuredResult -compileToBinary :: Text -> Text -> FilePath -> IO (TimedValue (Either Text ())) -compileToBinary moduleName text outputFilePath = measureTimedValue $ +compileToBinary :: Text -> FilePath -> IO (TimedValue (Either Text ())) +compileToBinary text outputFilePath = measureTimedValue $ sequenceA $ runExcept $ do - llvmIrText <- compileToLlvmIr' moduleName text + llvmIrText <- compileToLlvmIr' text return $ bracket (mkdtemp "build") removePathForcibly $ \buildDir -> withCurrentDirectory buildDir $ do - (llvm, llvmHandle) <- mkstemps (Txt.unpack moduleName) ".ll" + (llvm, llvmHandle) <- mkstemps "module" ".ll" Txt.hPutStrLn llvmHandle llvmIrText hClose llvmHandle @@ -83,18 +82,18 @@ compileToBinary moduleName text outputFilePath = measureTimedValue $ callProcess "clang" ["-Wno-override-module", "-O3", "-lm", llvm, runtime, "-o", "../" <> outputFilePath] -compileToLlvmIr :: Text -> Text -> FilePath -> IO (TimedValue (Either Text ())) -compileToLlvmIr moduleName text outputFilePath = measureTimedValue $ +compileToLlvmIr :: Text -> FilePath -> IO (TimedValue (Either Text ())) +compileToLlvmIr text outputFilePath = measureTimedValue $ sequenceA $ runExcept $ do - llvmIrText <- compileToLlvmIr' moduleName text + llvmIrText <- compileToLlvmIr' text return $ withFile outputFilePath WriteMode $ \handle -> do Txt.hPutStrLn handle llvmIrText -- * Internal -compileToLlvmIr' :: Text -> Text -> Except Text Text -compileToLlvmIr' moduleName text = do - irModule <- compileToModule moduleName text +compileToLlvmIr' :: Text -> Except Text Text +compileToLlvmIr' text = do + irModule <- compileToModule text return $ ppLlvmModule $ genLlvmIrModule irModule diff --git a/lib/CodeGen/Module.hs b/lib/CodeGen/Module.hs index 81455d8..50b4731 100644 --- a/lib/CodeGen/Module.hs +++ b/lib/CodeGen/Module.hs @@ -1,7 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} module CodeGen.Module - ( Module (Module, name, code), + ( Module (Module, code), compileToModule, ) where @@ -21,18 +21,15 @@ import Transformations.Simplifier.Simplifier (simplifyAst) import qualified TypeChecker.PrettyPrinter as TC import TypeChecker.TypeChecker (checkProgram) -data Module = Module - { name :: Text, - code :: Anf.Program - } +newtype Module = Module {code :: Anf.Program} deriving (Show, Eq) -compileToModule :: Text -> Text -> Except Text Module -compileToModule moduleName text = do +compileToModule :: Text -> Except Text Module +compileToModule text = do program <- parseAndVerify text let astToAnf = genAnf . llAst . ccAst . relabelAst . simplifyAst anf = astToAnf program - irMod = Module moduleName anf + irMod = Module anf in return irMod parseAndVerify :: Text -> Except Text Program diff --git a/miniml.cabal b/miniml.cabal index 38d61bc..4ed7fba 100644 --- a/miniml.cabal +++ b/miniml.cabal @@ -1,122 +1,120 @@ -cabal-version: 3.6 -name: mini-ml -version: 0.1.0.0 -synopsis: MiniML compiler -description: MiniML is a minimal dialect of ML (Meta Language). -homepage: https://github.com/AzimMuradov/miniml-compiler-haskell-spbu +cabal-version: 3.8 +name: mini-ml +version: 0.1.0.0 +synopsis: MiniML compiler +description: MiniML is a minimal dialect of ML (Meta Language). +homepage: https://github.com/AzimMuradov/miniml-compiler-haskell-spbu bug-reports: - https://github.com/AzimMuradov/miniml-compiler-haskell-spbu/issues + https://github.com/AzimMuradov/miniml-compiler-haskell-spbu/issues -license: MIT -license-file: LICENSE -author: Azim Muradov, Alexander Zadorozhnyy -maintainer: azim.muradov.dev@gmail.com, alexander.zadorozhnyy@yandex.ru -copyright: Copyright (c) 2023 Azim Muradov, Alexander Zadorozhnyy -category: Language +license: MIT +license-file: LICENSE +author: Azim Muradov, Alexander Zadorozhnyy +maintainer: azim.muradov.dev@gmail.com, alexander.zadorozhnyy@yandex.ru +copyright: Copyright (c) 2023 Azim Muradov, Alexander Zadorozhnyy +category: Language common shared-properties - default-language: Haskell2010 - build-depends: - , base >=4.14 - , bytestring >=0.11.2.0 - , extra >=1.7.12 - , text >=2.0.1 + default-language: Haskell2010 + build-depends: + , base >=4.7 && <5 + , bytestring >=0.11 && <0.12 + , extra >=1.7.12 + , text >=2.0.1 - ghc-options: - -Wall -Wcompat -Widentities -Wincomplete-uni-patterns - -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints + ghc-options: + -Wall -Wcompat -Widentities -Wincomplete-uni-patterns + -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints library - import: shared-properties - exposed-modules: - CodeGen.Llvm.LlvmIrGen - CodeGen.Llvm.Runner - CodeGen.Module - CodeGen.RunResult - CodeGen.TimedValue - MonadUtils - Parser.Ast - Parser.Lexer - Parser.Parser - Parser.Utils - StdLib - Transformations.Anf.Anf - Transformations.Anf.AnfGen - Transformations.Anf.PrettyPrinter - Transformations.Cc.Cc - Transformations.Ll.Lfr - Transformations.Ll.Ll - Transformations.Relabeler.Relabeler - Transformations.Simplifier.SimplifiedAst - Transformations.Simplifier.Simplifier - Trees.Common - TypeChecker.HindleyMilner - TypeChecker.PrettyPrinter - TypeChecker.TypeChecker + import: shared-properties + exposed-modules: + CodeGen.Llvm.LlvmIrGen + CodeGen.Llvm.Runner + CodeGen.Module + CodeGen.RunResult + CodeGen.TimedValue + MonadUtils + Parser.Ast + Parser.Lexer + Parser.Parser + Parser.Utils + StdLib + Transformations.Anf.Anf + Transformations.Anf.AnfGen + Transformations.Anf.PrettyPrinter + Transformations.Cc.Cc + Transformations.Ll.Lfr + Transformations.Ll.Ll + Transformations.Relabeler.Relabeler + Transformations.Simplifier.SimplifiedAst + Transformations.Simplifier.Simplifier + Trees.Common + TypeChecker.HindleyMilner + TypeChecker.PrettyPrinter + TypeChecker.TypeChecker - other-modules: - other-extensions: - build-depends: - , containers >=0.6.6 - , directory - , file-embed - , llvm-hs >=9.0.1 - , llvm-hs-pretty >=0.9.0.0 - , llvm-hs-pure >=9.0.0 - , megaparsec >=9.2 - , mtl >=2.2.2 - , parser-combinators >=1.3.0 - , process - , recursion-schemes - , string-conversions - , string-transform - , transformers >=0.5.6 - , unification-fd >=0.5.0 - , unix + other-modules: + other-extensions: + build-depends: + , containers >=0.6.6 + , directory + , file-embed + , llvm-codegen + , megaparsec >=9.2 + , mtl >=2.2.2 + , parser-combinators >=1.3.0 + , process + , recursion-schemes + , string-conversions + , string-transform + , transformers >=0.5.6 + , unification-fd >=0.5.0 + , unix - hs-source-dirs: lib + hs-source-dirs: lib executable miniml - import: shared-properties - main-is: Main.hs - other-modules: - Commands.Compile - Commands.Run - Configuration.AppConfiguration - Configuration.Commands.Compile - Configuration.Commands.MiniMl - Configuration.Commands.Run - Configuration.CommonParsers - Utils + import: shared-properties + main-is: Main.hs + other-modules: + Commands.Compile + Commands.Run + Configuration.AppConfiguration + Configuration.Commands.Compile + Configuration.Commands.MiniMl + Configuration.Commands.Run + Configuration.CommonParsers + Utils - other-extensions: - build-depends: - , filepath - , mini-ml - , optparse-applicative >=0.18 + other-extensions: + build-depends: + , filepath + , mini-ml + , optparse-applicative >=0.18 - hs-source-dirs: app + hs-source-dirs: app test-suite tests - import: shared-properties - type: exitcode-stdio-1.0 - main-is: Main.hs - other-modules: - Sample.AnfTest - Sample.FactorialTest - Sample.FibonacciTest - Sample.SimpleTest - Sample.Utils - Unit.Parser.ParserTest - Unit.StdLibTest - Unit.TypeInference.TypeInferenceTest - Utils + import: shared-properties + type: exitcode-stdio-1.0 + main-is: Main.hs + other-modules: + Sample.AnfTest + Sample.FactorialTest + Sample.FibonacciTest + Sample.SimpleTest + Sample.Utils + Unit.Parser.ParserTest + Unit.StdLibTest + Unit.TypeInference.TypeInferenceTest + Utils - build-depends: - , mini-ml - , pretty-simple >=4.1.2.0 - , tasty >=1.5 - , tasty-golden >=2.3.5 - , tasty-hunit >=0.10.1 + build-depends: + , mini-ml + , pretty-simple >=4.1.2.0 + , tasty >=1.5 + , tasty-golden >=2.3.5 + , tasty-hunit >=0.10.1 - hs-source-dirs: test + hs-source-dirs: test diff --git a/test/Sample/Utils.hs b/test/Sample/Utils.hs index 5b1101f..9075424 100644 --- a/test/Sample/Utils.hs +++ b/test/Sample/Utils.hs @@ -55,11 +55,11 @@ testLlvm testFileProvider = goldenVsString "LLVM" (testFileProvider "ll") - (LBSC8.pack . processTillLlvmIr "unnamed" <$> TxtIO.readFile (testFileProvider "ml")) + (LBSC8.pack . processTillLlvmIr <$> TxtIO.readFile (testFileProvider "ml")) testLlvmRun :: TestFileProvider -> TestTree testLlvmRun testFileProvider = goldenVsString "LLVM run" (testFileProvider "out") - (LBSC8.pack . processTillLlvmRunOutput "unnamed" <$> TxtIO.readFile (testFileProvider "ml")) + (LBSC8.pack . processTillLlvmRunOutput <$> TxtIO.readFile (testFileProvider "ml")) diff --git a/test/Utils.hs b/test/Utils.hs index d63b5b3..a9d1628 100644 --- a/test/Utils.hs +++ b/test/Utils.hs @@ -62,12 +62,12 @@ processTillLl = show . processTillLl' processTillAnfGen :: Text -> String processTillAnfGen = Anf.prettyPrint . processTillAnfGen' -processTillLlvmIr :: Text -> Text -> String -processTillLlvmIr name program = Txt.unpack $ ppLlvmModule $ genLlvmIrModule (Module name (processTillAnfGen' program)) +processTillLlvmIr :: Text -> String +processTillLlvmIr program = Txt.unpack $ ppLlvmModule $ genLlvmIrModule (Module (processTillAnfGen' program)) -processTillLlvmRunOutput :: Text -> Text -> String -processTillLlvmRunOutput name program = - let Success out _ _ = unsafePerformIO $ run name program +processTillLlvmRunOutput :: Text -> String +processTillLlvmRunOutput program = + let Success out _ _ = unsafePerformIO $ run program in Txt.unpack out -- Combinators From 57f3c7801a34663a241a0f679ca0e1a2045529b7 Mon Sep 17 00:00:00 2001 From: Azim Muradov Date: Fri, 21 Jun 2024 18:56:17 +0300 Subject: [PATCH 2/8] Apply hlint hints --- app/Configuration/Commands/Run.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Configuration/Commands/Run.hs b/app/Configuration/Commands/Run.hs index 9d58afc..c5580e1 100644 --- a/app/Configuration/Commands/Run.hs +++ b/app/Configuration/Commands/Run.hs @@ -11,7 +11,7 @@ runParserInfo :: ParserInfo Command runParserInfo = info runParser runInfoMod runParser :: Parser Command -runParser = CmdRun <$> (Run <$> inputParser) +runParser = CmdRun . Run <$> inputParser runInfoMod :: InfoMod a runInfoMod = From f2fe6335d03db6fa9b64676bad086a7bb84b9ffa Mon Sep 17 00:00:00 2001 From: Azim Muradov Date: Fri, 21 Jun 2024 18:56:45 +0300 Subject: [PATCH 3/8] Remove specific ormolu version --- .github/workflows/build.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bf47d23..20ac54d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,7 +44,6 @@ jobs: uses: haskell-actions/run-ormolu@v14 with: pattern: "**/*.hs" - version: 0.3.1.0 - name: Install LLVM run: sudo apt install -y llvm-17 llvm-17-dev - name: Build project From cbddc0685d994a7eeac9a39c79d88239f853f46b Mon Sep 17 00:00:00 2001 From: Azim Muradov Date: Fri, 21 Jun 2024 19:00:12 +0300 Subject: [PATCH 4/8] Fix test --- test/Sample/Factorial/FacRec.ll | 85 +++++++-------- test/Sample/Factorial/FacRecCps.ll | 129 +++++++++++------------ test/Sample/Factorial/FacRecLoop.ll | 105 +++++++++---------- test/Sample/Fibonacci/FibRec.ll | 93 +++++++---------- test/Sample/Fibonacci/FibRecCps.ll | 155 +++++++++++++--------------- test/Sample/Fibonacci/FibRecLoop.ll | 105 +++++++++---------- test/Sample/Simple/SimpleTest.ll | 66 +++++------- 7 files changed, 324 insertions(+), 414 deletions(-) diff --git a/test/Sample/Factorial/FacRec.ll b/test/Sample/Factorial/FacRec.ll index 7f968cd..120e740 100644 --- a/test/Sample/Factorial/FacRec.ll +++ b/test/Sample/Factorial/FacRec.ll @@ -1,61 +1,48 @@ -; ModuleID = 'unnamed' +declare external ccc i64 @not(i64) +declare external ccc i64 @print_bool(i64) - +declare external ccc i64 @print_int(i64) +declare external ccc i64 @miniml_div(i64, i64) -declare external ccc i64 @not(i64) +declare external ccc i64 @miniml_fun_to_paf(i64, i64) +declare external ccc i64 @miniml_apply(i64, i64) -declare external ccc i64 @print_bool(i64) - - -declare external ccc i64 @print_int(i64) - - -declare external ccc i64 @miniml_div(i64, i64) - - -declare external ccc i64 @miniml_fun_to_paf(i64, i64) - - -declare external ccc i64 @miniml_apply(i64, i64) - - -define external ccc i64 @factorial.1(i64 %n.2_0) { -;