summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
b1b9003)
Now that we're generating functions, variables can now be bound. This
means we will have to somehow keep track of what variables are available
in scope (i.e. passed to us in 'funciton'), so we've wrapped our
IRBuilderT in a ReaderT (Map String Operand).
For now if the variable doesn't exist in scope, we just crash the
program. But later on we will introduce a mechanism for errors, and tidy
up the transformer stack.
import AST as K -- K for Kaleidoscope
import Utils
import AST as K -- K for Kaleidoscope
import Utils
+import Control.Monad.Trans.Reader
import Control.Monad.IO.Class
import Control.Monad.IO.Class
+import Data.String
+import qualified Data.Map as Map
import qualified Data.Text.Lazy.IO as Text
import LLVM.AST.Constant
import LLVM.AST.Float
import qualified Data.Text.Lazy.IO as Text
import LLVM.AST.Constant
import LLVM.AST.Float
+type Binds = Map.Map String Operand
+
buildAST :: AST -> ModuleBuilder Operand
buildAST :: AST -> ModuleBuilder Operand
+buildAST (Function (Prototype nameStr paramStrs) body) = do
+ let n = fromString nameStr
+ function n params Type.double $ \ops -> do
+ let binds = Map.fromList (zip paramStrs ops)
+ flip runReaderT binds $ buildExpr body >>= ret
+ where params = zip (repeat Type.double) (map fromString paramStrs)
+
buildAST (TopLevelExpr x) = function "__anon_expr" [] Type.double $
buildAST (TopLevelExpr x) = function "__anon_expr" [] Type.double $
- const $ buildExpr x >>= ret
+ const $ flip runReaderT mempty $ buildExpr x >>= ret
-buildExpr :: Expr -> IRBuilderT ModuleBuilder Operand
+buildExpr :: Expr -> ReaderT Binds (IRBuilderT ModuleBuilder) Operand
buildExpr (Num x) = pure $ ConstantOperand (Float (Double x))
buildExpr (Num x) = pure $ ConstantOperand (Float (Double x))
+buildExpr (Var n) = do
+ binds <- ask
+ case binds Map.!? n of
+ Just x -> pure x
+ Nothing -> error $ "'" <> n <> "' doesn't exist in scope"
+
buildExpr (BinOp op a b) = do
opA <- buildExpr a
opB <- buildExpr b
buildExpr (BinOp op a b) = do
opA <- buildExpr a
opB <- buildExpr b