The Kaleidoscope tutorial acts as a repl where each top-level expression
is evaluated when you enter it. Currently we were building up the
llvm-hs-pure AST inside our REPL, and then converting it to an actual
LLVM IR module in main when we called buildModuleT.
In order to do this line-by-line JITing, we'll need the actual LLVM
module when we enter the line. This will prepare us for the craziness
that will come in the following commits
import AST as K -- K for Kaleidoscope
import Utils
import AST as K -- K for Kaleidoscope
import Utils
+import Control.Monad.Trans.Class
import Control.Monad.Trans.Reader
import Control.Monad.IO.Class
import Data.String
import Control.Monad.Trans.Reader
import Control.Monad.IO.Class
import Data.String
- mdl' <- buildModuleT "main" repl
- withContext $ \ctx -> withHostTargetMachine $ \tm ->
- withModuleFromAST ctx mdl' $ \mdl -> do
- let spec = defaultCuratedPassSetSpec { optLevel = Just 3 }
- -- this returns true if the module was modified
- withPassManager spec $ flip runPassManager mdl
- Text.hPutStrLn stderr . ("\n" <>) . ppllvm =<< moduleAST mdl
+ withContext $ \ctx -> withHostTargetMachine $ \tm -> do
+ ast <- runReaderT (buildModuleT "main" repl) ctx
+ return ()
-repl :: ModuleBuilderT IO ()
+repl :: ModuleBuilderT (ReaderT Context IO) ()
repl = do
liftIO $ hPutStr stderr "ready> "
mline <- liftIO $ catchIOError (Just <$> getLine) eofHandler
repl = do
liftIO $ hPutStr stderr "ready> "
mline <- liftIO $ catchIOError (Just <$> getLine) eofHandler
Just ast -> do
hoist $ buildAST ast
mostRecentDef >>= liftIO . Text.hPutStrLn stderr . ppll
Just ast -> do
hoist $ buildAST ast
mostRecentDef >>= liftIO . Text.hPutStrLn stderr . ppll
+
+ ast <- moduleSoFar "main"
+ ctx <- lift ask
+ liftIO $ withModuleFromAST ctx ast $ \mdl -> do
+ let spec = defaultCuratedPassSetSpec { optLevel = Just 3 }
+ -- this returns true if the module was modified
+ withPassManager spec $ flip runPassManager mdl
+ Text.hPutStrLn stderr . ("\n" <>) . ppllvm =<< moduleAST mdl
module Utils where
import Control.Monad.Trans.State
module Utils where
import Control.Monad.Trans.State
+import Data.ByteString.Short (ShortByteString)
import Data.Functor.Identity
import LLVM.AST
import LLVM.IRBuilder.Module
import LLVM.IRBuilder.Internal.SnocList
import Data.Functor.Identity
import LLVM.AST
import LLVM.IRBuilder.Module
import LLVM.IRBuilder.Internal.SnocList
+moduleSoFar :: MonadModuleBuilder m => ShortByteString -> m Module
+moduleSoFar nm = do
+ s <- liftModuleState get
+ let ds = getSnocList (builderDefs s)
+ return $ defaultModule { moduleName = nm, moduleDefinitions = ds }
+
mostRecentDef :: Monad m => ModuleBuilderT m Definition
mostRecentDef = last . getSnocList . builderDefs <$> liftModuleState get
mostRecentDef :: Monad m => ModuleBuilderT m Definition
mostRecentDef = last . getSnocList . builderDefs <$> liftModuleState get