From 431c4b6e37e414b6959cdf14a50622c514ea0a85 Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Sun, 2 Jun 2019 17:39:47 +0100 Subject: [PATCH] Detect and remove __anon_exprs in repl 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 | 14 ++++++++++++-- Utils.hs | 8 ++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Main.hs b/Main.hs index ee8ee60..4dafa02 100644 --- a/Main.hs +++ b/Main.hs @@ -2,6 +2,7 @@ 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 @@ -40,21 +41,30 @@ repl = 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 + 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 + when anon (jit mdl >>= hPrint stderr) + + when anon (removeDef def) 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 diff --git a/Utils.hs b/Utils.hs index 3bd3b37..cd325a4 100644 --- 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 Data.List 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 } +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 -- 2.30.2