Add print functionality
parent
5325a845f2
commit
f7e64faed5
|
@ -1 +1 @@
|
||||||
6+8/3
|
(6+8/3)
|
|
@ -7,9 +7,13 @@ dependencies:
|
||||||
- parser-combinators
|
- parser-combinators
|
||||||
- text
|
- text
|
||||||
- process
|
- process
|
||||||
|
- mtl
|
||||||
|
- containers
|
||||||
- llvm-hs >= 15 && < 16
|
- llvm-hs >= 15 && < 16
|
||||||
- llvm-hs-pure >= 15 && < 16
|
- llvm-hs-pure >= 15 && < 16
|
||||||
- bytestring
|
- bytestring
|
||||||
|
- string-conversions
|
||||||
|
- transformers
|
||||||
tested-with: GHC == 9.2.8
|
tested-with: GHC == 9.2.8
|
||||||
category: Compilers/Interpreters
|
category: Compilers/Interpreters
|
||||||
|
|
||||||
|
|
|
@ -28,10 +28,14 @@ executable really-bad-compiler-in-haskell
|
||||||
build-depends:
|
build-depends:
|
||||||
base >=4.14.3 && <5
|
base >=4.14.3 && <5
|
||||||
, bytestring
|
, bytestring
|
||||||
|
, containers
|
||||||
, llvm-hs ==15.*
|
, llvm-hs ==15.*
|
||||||
, llvm-hs-pure ==15.*
|
, llvm-hs-pure ==15.*
|
||||||
, megaparsec >=9.0.1 && <10
|
, megaparsec >=9.0.1 && <10
|
||||||
|
, mtl
|
||||||
, parser-combinators
|
, parser-combinators
|
||||||
, process
|
, process
|
||||||
|
, string-conversions
|
||||||
, text
|
, text
|
||||||
|
, transformers
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE ImportQualifiedPost #-}
|
{-# LANGUAGE ImportQualifiedPost #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE RecursiveDo #-}
|
{-# LANGUAGE RecursiveDo #-}
|
||||||
|
|
||||||
-- see https://gh.sudoer.ch/danieljharvey/mimsa/blob/trunk/llvm-calc/src/Calc/Compile/ToLLVM.hs
|
-- see https://gh.sudoer.ch/danieljharvey/mimsa/blob/trunk/llvm-calc/src/Calc/Compile/ToLLVM.hs
|
||||||
|
-- see https://blog.josephmorag.com/posts/mcc3/
|
||||||
|
|
||||||
module Main.LLVMGen (llvmGen) where
|
module Main.LLVMGen (llvmGen) where
|
||||||
|
|
||||||
|
import Control.Monad.State
|
||||||
|
import Control.Monad.Trans.Class (lift)
|
||||||
import Data.ByteString (ByteString)
|
import Data.ByteString (ByteString)
|
||||||
|
import Data.Map qualified as M
|
||||||
|
import Data.String.Conversions
|
||||||
|
import Data.Text
|
||||||
import LLVM (moduleLLVMAssembly, withModuleFromAST)
|
import LLVM (moduleLLVMAssembly, withModuleFromAST)
|
||||||
import LLVM.AST hiding (function)
|
import LLVM.AST hiding (function)
|
||||||
import LLVM.AST.Type
|
import LLVM.AST.Type
|
||||||
|
@ -17,34 +24,71 @@ import LLVM.IRBuilder.Module
|
||||||
import LLVM.IRBuilder.Monad
|
import LLVM.IRBuilder.Monad
|
||||||
import Main.Types.Expr as Expr
|
import Main.Types.Expr as Expr
|
||||||
|
|
||||||
-- printf :: Operand
|
data Env = Env
|
||||||
-- printf = externVarArgs "printf" [ptr] i32
|
{ operands :: M.Map Text Operand,
|
||||||
|
strings :: M.Map Text Operand
|
||||||
|
}
|
||||||
|
deriving (Eq, Show)
|
||||||
|
|
||||||
|
registerOperand :: (MonadState Env m) => Text -> Operand -> m ()
|
||||||
|
registerOperand name op =
|
||||||
|
modify $ \env -> env {operands = M.insert name op (operands env)}
|
||||||
|
|
||||||
|
registerString :: (MonadState Env m) => Text -> Operand -> m ()
|
||||||
|
registerString name op =
|
||||||
|
modify $ \env -> env {strings = M.insert name op (operands env)}
|
||||||
|
|
||||||
|
getOperand :: (MonadState Env m, MonadModuleBuilder m, MonadIRBuilder m) => Text -> m Operand
|
||||||
|
getOperand name = do
|
||||||
|
env <- get
|
||||||
|
case M.lookup name (operands env) of
|
||||||
|
Just op -> return op
|
||||||
|
Nothing -> error $ "Unknown operand: " ++ show name
|
||||||
|
|
||||||
|
getString :: (MonadState Env m, MonadModuleBuilder m, MonadIRBuilder m) => Text -> m Operand
|
||||||
|
getString str = do
|
||||||
|
env <- get
|
||||||
|
case M.lookup str (strings env) of
|
||||||
|
Just s -> return s
|
||||||
|
Nothing -> do
|
||||||
|
s <- globalStringPtr (unpack str) (mkName "str")
|
||||||
|
let operand = ConstantOperand s
|
||||||
|
modify $ \env -> env {strings = M.insert str operand (strings env)}
|
||||||
|
return operand
|
||||||
|
|
||||||
getLLVM :: Expr -> Module
|
getLLVM :: Expr -> Module
|
||||||
getLLVM expr =
|
getLLVM expr =
|
||||||
buildModule "program" $ mdo
|
flip evalState (Env {operands = M.empty, strings = M.empty}) $
|
||||||
|
buildModuleT "program" $ mdo
|
||||||
-- TODO: better module name
|
-- TODO: better module name
|
||||||
printf <- externVarArgs "printf" [ptr] i32
|
printf <- externVarArgs "printf" [ptr] i32
|
||||||
|
lift $ registerOperand "printf" printf
|
||||||
function "main" [] i32 $ \_ -> mdo
|
function "main" [] i32 $ \_ -> mdo
|
||||||
numFormatStr <- globalStringPtr "%d\n" (mkName "str")
|
printNumStr <- globalStringPtr "%d\n" (mkName "str")
|
||||||
ourExpression <- exprToLLVM expr
|
lift $ registerString "%d\n" $ ConstantOperand printNumStr
|
||||||
_ <- call (FunctionType i32 [ptr] True) printf [(ConstantOperand numFormatStr, []), (ourExpression, [])]
|
_ <- exprToLLVM expr
|
||||||
ret $ int32 0
|
ret $ int32 0
|
||||||
|
|
||||||
-- getLLVM2 expr =
|
--
|
||||||
-- getLLVM $
|
-- ourExpression <- exprToLLVM expr
|
||||||
|
-- _ <- call (FunctionType i32 [ptr] True) printf [(ConstantOperand numFormatStr, []), (ourExpression, [])]
|
||||||
-- return (printf)
|
-- ret $ int32 0
|
||||||
|
|
||||||
exprToLLVM ::
|
exprToLLVM ::
|
||||||
( MonadIRBuilder m,
|
( MonadIRBuilder m,
|
||||||
MonadModuleBuilder m
|
MonadModuleBuilder m,
|
||||||
|
MonadState Env m
|
||||||
) =>
|
) =>
|
||||||
Expr ->
|
Expr ->
|
||||||
m Operand
|
m Operand
|
||||||
exprToLLVM (Lit prim) = pure $ primToLLVM prim
|
exprToLLVM (Lit prim) = pure $ primToLLVM prim
|
||||||
exprToLLVM (Paren e) = exprToLLVM e
|
exprToLLVM (Paren e) = exprToLLVM e
|
||||||
-- exprToLLVM (Print e) = mdo
|
exprToLLVM (Print e) = mdo
|
||||||
|
val <- exprToLLVM e
|
||||||
|
printf <- getOperand "printf"
|
||||||
|
formatStr <- getString "%d\n"
|
||||||
|
_ <- call (FunctionType i32 [ptr] True) printf [(formatStr, []), (val, [])]
|
||||||
|
pure val
|
||||||
exprToLLVM (Expr.Add a b) = mdo
|
exprToLLVM (Expr.Add a b) = mdo
|
||||||
lhs <- exprToLLVM a
|
lhs <- exprToLLVM a
|
||||||
rhs <- exprToLLVM b
|
rhs <- exprToLLVM b
|
||||||
|
|
Reference in New Issue