+{-# LANGUAGE OverloadedStrings #-}
+
import AST
+import Utils
+import Control.Monad.IO.Class
+import qualified Data.Text.Lazy.IO as Text
+import LLVM.AST.Constant
+import LLVM.AST.Float
+import LLVM.AST.Operand
+import LLVM.AST.Type as Type
+import LLVM.IRBuilder
+import LLVM.Pretty
import System.IO
-import Text.Read
-main = do
- hPutStr stderr "ready> "
- ast <- (readMaybe <$> getLine) :: IO (Maybe AST)
+import Text.Read (readMaybe)
+
+main = buildModuleT "main" repl
+
+repl :: ModuleBuilderT IO ()
+repl = do
+ liftIO $ hPutStr stderr "ready> "
+ ast <- liftIO $ readMaybe <$> getLine
case ast of
- Just x -> hPrint stderr x
- Nothing -> hPutStrLn stderr "Couldn't parse"
- main
+ Nothing -> liftIO $ hPutStrLn stderr "Couldn't parse"
+ Just x -> do
+ hoist $ buildAST x
+ mostRecentDef >>= liftIO . Text.hPutStrLn stderr . ppll
+ repl
+ where
+
+buildAST :: AST -> ModuleBuilder Operand
+buildAST (TopLevelExpr x) = function "__anon_expr" [] Type.double $
+ const $ buildExpr x >>= ret
+
+buildExpr :: Expr -> IRBuilderT ModuleBuilder Operand
+buildExpr (Num x) = pure $ ConstantOperand (Float (Double x))
--- /dev/null
+{-|
+Shoving away gross stuff into this one module.
+-}
+module Utils where
+
+import Control.Monad.Trans.State
+import Data.Functor.Identity
+import LLVM.AST
+import LLVM.IRBuilder.Module
+import LLVM.IRBuilder.Internal.SnocList
+
+mostRecentDef :: Monad m => ModuleBuilderT m Definition
+mostRecentDef = last . getSnocList . builderDefs <$> liftModuleState get
+
+hoist :: Monad m => ModuleBuilder a -> ModuleBuilderT m a
+hoist m = ModuleBuilderT $ StateT $
+ return . runIdentity . runStateT (unModuleBuilderT m)