Generate the module inside the repl
authorLuke Lau <luke_lau@icloud.com>
Sun, 2 Jun 2019 16:28:31 +0000 (17:28 +0100)
committerLuke Lau <luke_lau@icloud.com>
Sun, 2 Jun 2019 16:28:31 +0000 (17:28 +0100)
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

Main.hs
Utils.hs

diff --git a/Main.hs b/Main.hs
index bff1c08c965c037080cc6aba052a60c40f1dc999..ee8ee608da79855741c0fab9cc68a63b9b5c88f6 100644 (file)
--- a/Main.hs
+++ b/Main.hs
@@ -2,6 +2,7 @@
 
 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
@@ -25,15 +26,11 @@ import Text.Read (readMaybe)
 
 main :: IO ()
 main = do
-  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
@@ -45,6 +42,14 @@ repl = do
         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
       repl
   where
     eofHandler e
index 2a83c3591276ea116a969301fd4f24ae772af949..3bd3b37e01e54274cf4841b52e18d8d4b2cea97e 100644 (file)
--- a/Utils.hs
+++ b/Utils.hs
@@ -4,11 +4,18 @@ Shoving away gross stuff into this one module.
 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
 
+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