Detect and remove __anon_exprs in repl
authorLuke Lau <luke_lau@icloud.com>
Sun, 2 Jun 2019 16:39:47 +0000 (17:39 +0100)
committerLuke Lau <luke_lau@icloud.com>
Sun, 2 Jun 2019 16:39:47 +0000 (17:39 +0100)
You might have noticed that when entering in top-level expressions you
end up getting duplicate __anon_expr.1, __anon_expr.2s etc. Since we
don't want these anonymous functions to stick around, in this commit
we're detecting them and then removing them once we're done.

We also only want to run the JIT whenever the user has entered a
top-level expression, so we've also sketched that out.

Main.hs
Utils.hs

diff --git a/Main.hs b/Main.hs
index ee8ee608da79855741c0fab9cc68a63b9b5c88f6..4dafa02b5f1acc3e2828c35a570993fba1abcfd0 100644 (file)
--- a/Main.hs
+++ b/Main.hs
@@ -2,6 +2,7 @@
 
 import AST as K -- K for Kaleidoscope
 import Utils
 
 import AST as K -- K for Kaleidoscope
 import Utils
+import Control.Monad
 import Control.Monad.Trans.Class
 import Control.Monad.Trans.Reader
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Class
 import Control.Monad.Trans.Reader
 import Control.Monad.IO.Class
@@ -40,21 +41,30 @@ repl = do
       case readMaybe l of
         Nothing ->  liftIO $ hPutStrLn stderr "Couldn't parse"
         Just ast -> do
       case readMaybe l of
         Nothing ->  liftIO $ hPutStrLn stderr "Couldn't parse"
         Just ast -> do
-          hoist $ buildAST ast
-          mostRecentDef >>= liftIO . Text.hPutStrLn stderr . ppll
+          anon <- isAnonExpr <$> hoist (buildAST ast)
+          def <- mostRecentDef
           
           ast <- moduleSoFar "main"
           ctx <- lift ask
           liftIO $ withModuleFromAST ctx ast $ \mdl -> do
           
           ast <- moduleSoFar "main"
           ctx <- lift ask
           liftIO $ withModuleFromAST ctx ast $ \mdl -> do
+            Text.hPutStrLn stderr $ ppll def
             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
             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
+            when anon (jit mdl >>= hPrint stderr)
+
+          when anon (removeDef def)
       repl
   where
     eofHandler e
       | isEOFError e = return Nothing
       | otherwise = ioError e
       repl
   where
     eofHandler e
       | isEOFError e = return Nothing
       | otherwise = ioError e
+    isAnonExpr (ConstantOperand (GlobalReference _ "__anon_expr")) = True
+    isAnonExpr _ = False
+
+jit :: Module -> IO Double
+jit _mdl = putStrLn "Working on it!" >> return 0
 
 type Binds = Map.Map String Operand
 
 
 type Binds = Map.Map String Operand
 
index 3bd3b37e01e54274cf4841b52e18d8d4b2cea97e..cd325a40b3c3c296549e0ea11ad9947b1c9d53a4 100644 (file)
--- a/Utils.hs
+++ b/Utils.hs
@@ -6,6 +6,7 @@ module Utils where
 import Control.Monad.Trans.State
 import Data.ByteString.Short (ShortByteString)
 import Data.Functor.Identity
 import Control.Monad.Trans.State
 import Data.ByteString.Short (ShortByteString)
 import Data.Functor.Identity
+import Data.List
 import LLVM.AST
 import LLVM.IRBuilder.Module
 import LLVM.IRBuilder.Internal.SnocList
 import LLVM.AST
 import LLVM.IRBuilder.Module
 import LLVM.IRBuilder.Internal.SnocList
@@ -16,6 +17,13 @@ moduleSoFar nm = do
   let ds = getSnocList (builderDefs s)
   return $ defaultModule { moduleName = nm, moduleDefinitions = ds }
 
   let ds = getSnocList (builderDefs s)
   return $ defaultModule { moduleName = nm, moduleDefinitions = ds }
 
+removeDef :: MonadModuleBuilder m => Definition -> m ()
+removeDef def = liftModuleState (modify update)
+  where
+    update (ModuleBuilderState defs typeDefs) =
+      let newDefs = SnocList (delete def (getSnocList defs))
+      in ModuleBuilderState newDefs typeDefs
+
 mostRecentDef :: Monad m => ModuleBuilderT m Definition
 mostRecentDef = last . getSnocList . builderDefs <$> liftModuleState get
 
 mostRecentDef :: Monad m => ModuleBuilderT m Definition
 mostRecentDef = last . getSnocList . builderDefs <$> liftModuleState get