{-# LANGUAGE FlexibleContexts #-}
module Codegen.ExprGen.Variable where
import qualified Ast.Types as AT
import qualified Codegen.Errors as CC
import qualified Codegen.ExprGen.Cast as EC
import qualified Codegen.ExprGen.DataValue as ED
import {-# SOURCE #-} qualified Codegen.ExprGen.ExprGen as EG
import qualified Codegen.ExprGen.Types as ET
import qualified Codegen.State as CS
import qualified Control.Monad.Except as E
import qualified Data.List as L
import qualified Data.Maybe as M
import qualified LLVM.AST as AST
import qualified LLVM.AST.AddrSpace as AS
import qualified LLVM.AST.Constant as C
import qualified LLVM.AST.Float as FF
import qualified LLVM.AST.Global as G
import qualified LLVM.AST.Linkage as LK
import qualified LLVM.AST.Type as T
import qualified LLVM.AST.Typed as TD
import qualified LLVM.AST.Visibility as V
import qualified LLVM.IRBuilder.Constant as IC
import qualified LLVM.IRBuilder.Instruction as I
import qualified LLVM.IRBuilder.Module as M
import qualified Shared.Utils as SU
generateDeclaration :: (CS.MonadCodegen m, EG.ExprGen AT.Expr) => AT.Expr -> m AST.Operand
generateDeclaration :: forall (m :: * -> *).
(MonadCodegen m, ExprGen Expr) =>
Expr -> m Operand
generateDeclaration (AT.Declaration SrcLoc
loc String
name Type
typ Maybe Expr
mInitExpr) = do
Maybe Operand
maybeVar <- String -> m (Maybe Operand)
forall (m :: * -> *). VarBinding m => String -> m (Maybe Operand)
CS.getVar String
name
case Maybe Operand
maybeVar of
Just Operand
ptr -> do
case Maybe Expr
mInitExpr of
Just Expr
initExpr -> do
Operand
initValue <- Expr -> m Operand
forall a (m :: * -> *).
(ExprGen a, MonadCodegen m) =>
a -> m Operand
forall (m :: * -> *). MonadCodegen m => Expr -> m Operand
EG.generateExpr Expr
initExpr
Operand
initValue' <- SrcLoc -> Operand -> Type -> m Operand
forall (m :: * -> *).
MonadCodegen m =>
SrcLoc -> Operand -> Type -> m Operand
EC.ensureMatchingType SrcLoc
loc Operand
initValue (Type -> Type
forall a. ToLLVM a => a -> Type
ET.toLLVM Type
typ)
Operand -> Word32 -> Operand -> m ()
forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Word32 -> Operand -> m ()
I.store Operand
ptr Word32
0 Operand
initValue'
Operand -> Word32 -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Word32 -> m Operand
I.load Operand
ptr Word32
0
Maybe Expr
Nothing -> Operand -> Word32 -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Word32 -> m Operand
I.load Operand
ptr Word32
0
Maybe Operand
Nothing -> CodegenError -> m Operand
forall a. CodegenError -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
E.throwError (CodegenError -> m Operand) -> CodegenError -> m Operand
forall a b. (a -> b) -> a -> b
$ SrcLoc -> CodegenErrorType -> CodegenError
CC.CodegenError SrcLoc
loc (CodegenErrorType -> CodegenError)
-> CodegenErrorType -> CodegenError
forall a b. (a -> b) -> a -> b
$ String -> CodegenErrorType
CC.VariableNotFound String
name
generateDeclaration Expr
expr =
CodegenError -> m Operand
forall a. CodegenError -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
E.throwError (CodegenError -> m Operand) -> CodegenError -> m Operand
forall a b. (a -> b) -> a -> b
$ SrcLoc -> CodegenErrorType -> CodegenError
CC.CodegenError (Expr -> SrcLoc
SU.getLoc Expr
expr) (CodegenErrorType -> CodegenError)
-> CodegenErrorType -> CodegenError
forall a b. (a -> b) -> a -> b
$ Expr -> CodegenErrorType
CC.UnsupportedDefinition Expr
expr
generateLiteral :: (CS.MonadCodegen m, EG.ExprGen AT.Expr) => AT.Expr -> m AST.Operand
generateLiteral :: forall (m :: * -> *).
(MonadCodegen m, ExprGen Expr) =>
Expr -> m Operand
generateLiteral (AT.Lit SrcLoc
loc Literal
lit) = do
Constant
constant <- Literal -> SrcLoc -> m Constant
forall (m :: * -> *).
(MonadCodegen m, ExprGen Expr) =>
Literal -> SrcLoc -> m Constant
generateConstant Literal
lit SrcLoc
loc
Operand -> m Operand
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Operand -> m Operand) -> Operand -> m Operand
forall a b. (a -> b) -> a -> b
$ Constant -> Operand
AST.ConstantOperand Constant
constant
generateLiteral Expr
expr =
CodegenError -> m Operand
forall a. CodegenError -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
E.throwError (CodegenError -> m Operand) -> CodegenError -> m Operand
forall a b. (a -> b) -> a -> b
$ SrcLoc -> CodegenErrorType -> CodegenError
CC.CodegenError (Expr -> SrcLoc
SU.getLoc Expr
expr) (CodegenErrorType -> CodegenError)
-> CodegenErrorType -> CodegenError
forall a b. (a -> b) -> a -> b
$ Expr -> CodegenErrorType
CC.UnsupportedDefinition Expr
expr
generateConstant :: (CS.MonadCodegen m, EG.ExprGen AT.Expr) => AT.Literal -> AT.SrcLoc -> m C.Constant
generateConstant :: forall (m :: * -> *).
(MonadCodegen m, ExprGen Expr) =>
Literal -> SrcLoc -> m Constant
generateConstant Literal
lit SrcLoc
loc = case Literal
lit of
AT.LInt Integer
n -> Constant -> m Constant
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Constant -> m Constant) -> Constant -> m Constant
forall a b. (a -> b) -> a -> b
$ Word32 -> Integer -> Constant
C.Int Word32
32 (Integer -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
n)
AT.LChar Char
c -> Constant -> m Constant
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Constant -> m Constant) -> Constant -> m Constant
forall a b. (a -> b) -> a -> b
$ Word32 -> Integer -> Constant
C.Int Word32
8 (Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Integer) -> Int -> Integer
forall a b. (a -> b) -> a -> b
$ Char -> Int
forall a. Enum a => a -> Int
fromEnum Char
c)
AT.LBool Bool
b -> Constant -> m Constant
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Constant -> m Constant) -> Constant -> m Constant
forall a b. (a -> b) -> a -> b
$ Word32 -> Integer -> Constant
C.Int Word32
1 (if Bool
b then Integer
1 else Integer
0)
Literal
AT.LNull -> Constant -> m Constant
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Constant -> m Constant) -> Constant -> m Constant
forall a b. (a -> b) -> a -> b
$ Type -> Constant
C.Null Type
T.i8
AT.LFloat Double
f -> Constant -> m Constant
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Constant -> m Constant) -> Constant -> m Constant
forall a b. (a -> b) -> a -> b
$ SomeFloat -> Constant
C.Float (Float -> SomeFloat
FF.Single (Double -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
f))
AT.LDouble Double
f -> Constant -> m Constant
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Constant -> m Constant) -> Constant -> m Constant
forall a b. (a -> b) -> a -> b
$ SomeFloat -> Constant
C.Float (Double -> SomeFloat
FF.Double (Double -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
f))
AT.LArray [Literal]
elems -> do
let (Literal
headElem, [Literal]
_) = Maybe (Literal, [Literal]) -> (Literal, [Literal])
forall a. HasCallStack => Maybe a -> a
M.fromJust (Maybe (Literal, [Literal]) -> (Literal, [Literal]))
-> Maybe (Literal, [Literal]) -> (Literal, [Literal])
forall a b. (a -> b) -> a -> b
$ [Literal] -> Maybe (Literal, [Literal])
forall a. [a] -> Maybe (a, [a])
L.uncons [Literal]
elems
case Literal
headElem of
AT.LChar Char
_ -> do
Operand
strPtr <- String -> m Operand
forall (m :: * -> *).
(MonadCodegen m, ExprGen Expr) =>
String -> m Operand
createGlobalString [Char
c | AT.LChar Char
c <- [Literal]
elems]
case Operand
strPtr of
AST.ConstantOperand Constant
c -> Constant -> m Constant
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Constant
c
Operand
_ -> CodegenError -> m Constant
forall a. CodegenError -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
E.throwError (CodegenError -> m Constant) -> CodegenError -> m Constant
forall a b. (a -> b) -> a -> b
$ SrcLoc -> CodegenErrorType -> CodegenError
CC.CodegenError SrcLoc
loc (CodegenErrorType -> CodegenError)
-> CodegenErrorType -> CodegenError
forall a b. (a -> b) -> a -> b
$ Literal -> CodegenErrorType
CC.UnsupportedLiteral Literal
lit
Literal
_ -> do
[Constant]
constants <- (Literal -> m Constant) -> [Literal] -> m [Constant]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Literal -> SrcLoc -> m Constant
forall (m :: * -> *).
(MonadCodegen m, ExprGen Expr) =>
Literal -> SrcLoc -> m Constant
`generateConstant` SrcLoc
loc) [Literal]
elems
Constant -> m Constant
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Constant -> m Constant) -> Constant -> m Constant
forall a b. (a -> b) -> a -> b
$ Type -> [Constant] -> Constant
C.Array (Constant -> Type
forall a. Typed a => a -> Type
TD.typeOf (Constant -> Type) -> Constant -> Type
forall a b. (a -> b) -> a -> b
$ [Constant] -> Constant
forall a. HasCallStack => [a] -> a
head [Constant]
constants) [Constant]
constants
AT.LStruct [(String, Literal)]
fields -> do
let ([String]
_, [Literal]
values) = [(String, Literal)] -> ([String], [Literal])
forall a b. [(a, b)] -> ([a], [b])
unzip [(String, Literal)]
fields
[Constant]
constants <- (Literal -> m Constant) -> [Literal] -> m [Constant]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Literal -> SrcLoc -> m Constant
forall (m :: * -> *).
(MonadCodegen m, ExprGen Expr) =>
Literal -> SrcLoc -> m Constant
`generateConstant` SrcLoc
loc) [Literal]
values
Constant -> m Constant
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Constant -> m Constant) -> Constant -> m Constant
forall a b. (a -> b) -> a -> b
$ Maybe Name -> Bool -> [Constant] -> Constant
C.Struct Maybe Name
forall a. Maybe a
Nothing Bool
False [Constant]
constants
createGlobalString :: (CS.MonadCodegen m, EG.ExprGen AT.Expr) => String -> m AST.Operand
createGlobalString :: forall (m :: * -> *).
(MonadCodegen m, ExprGen Expr) =>
String -> m Operand
createGlobalString String
str = do
let strConst :: Constant
strConst =
Type -> [Constant] -> Constant
C.Array
(Word32 -> Type
T.IntegerType Word32
8)
((Char -> Constant) -> String -> [Constant]
forall a b. (a -> b) -> [a] -> [b]
map (Word32 -> Integer -> Constant
C.Int Word32
8 (Integer -> Constant) -> (Char -> Integer) -> Char -> Constant
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Integer) -> (Char -> Int) -> Char -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Int
forall a. Enum a => a -> Int
fromEnum) (String
str String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\0"))
let strType :: Type
strType = Word64 -> Type -> Type
T.ArrayType (Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word64) -> Int -> Word64
forall a b. (a -> b) -> a -> b
$ String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
str Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Word32 -> Type
T.IntegerType Word32
8)
Name
name <- m Name
forall (m :: * -> *). MonadState CodegenState m => m Name
CS.fresh
let global :: Global
global =
AST.GlobalVariable
{ name :: Name
G.name = Name
name,
linkage :: Linkage
G.linkage = Linkage
LK.Private,
visibility :: Visibility
G.visibility = Visibility
V.Default,
dllStorageClass :: Maybe StorageClass
G.dllStorageClass = Maybe StorageClass
forall a. Maybe a
Nothing,
threadLocalMode :: Maybe Model
G.threadLocalMode = Maybe Model
forall a. Maybe a
Nothing,
unnamedAddr :: Maybe UnnamedAddr
G.unnamedAddr = UnnamedAddr -> Maybe UnnamedAddr
forall a. a -> Maybe a
Just UnnamedAddr
AST.GlobalAddr,
isConstant :: Bool
G.isConstant = Bool
True,
type' :: Type
G.type' = Type
strType,
addrSpace :: AddrSpace
G.addrSpace = Word32 -> AddrSpace
AS.AddrSpace Word32
0,
initializer :: Maybe Constant
G.initializer = Constant -> Maybe Constant
forall a. a -> Maybe a
Just Constant
strConst,
section :: Maybe ShortByteString
G.section = Maybe ShortByteString
forall a. Maybe a
Nothing,
comdat :: Maybe ShortByteString
G.comdat = Maybe ShortByteString
forall a. Maybe a
Nothing,
alignment :: Word32
G.alignment = Word32
1,
metadata :: [(ShortByteString, MDRef MDNode)]
G.metadata = []
}
Definition -> m ()
forall (m :: * -> *). MonadModuleBuilder m => Definition -> m ()
M.emitDefn (Definition -> m ()) -> Definition -> m ()
forall a b. (a -> b) -> a -> b
$ Global -> Definition
AST.GlobalDefinition Global
global
Operand -> m Operand
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Operand -> m Operand) -> Operand -> m Operand
forall a b. (a -> b) -> a -> b
$
Constant -> Operand
AST.ConstantOperand (Constant -> Operand) -> Constant -> Operand
forall a b. (a -> b) -> a -> b
$
Bool -> Constant -> [Constant] -> Constant
C.GetElementPtr
Bool
True
(Type -> Name -> Constant
C.GlobalReference (Type -> Type
T.ptr Type
strType) Name
name)
[Word32 -> Integer -> Constant
C.Int Word32
64 Integer
0, Word32 -> Integer -> Constant
C.Int Word32
64 Integer
0]
generateVar :: (CS.MonadCodegen m, EG.ExprGen AT.Expr) => AT.Expr -> m AST.Operand
generateVar :: forall (m :: * -> *).
(MonadCodegen m, ExprGen Expr) =>
Expr -> m Operand
generateVar (AT.Var SrcLoc
loc String
name Type
type') = do
Maybe Operand
maybeVar <- String -> m (Maybe Operand)
forall (m :: * -> *). VarBinding m => String -> m (Maybe Operand)
CS.getVar String
name
case Maybe Operand
maybeVar of
Maybe Operand
Nothing ->
CodegenError -> m Operand
forall a. CodegenError -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
E.throwError (CodegenError -> m Operand) -> CodegenError -> m Operand
forall a b. (a -> b) -> a -> b
$ SrcLoc -> CodegenErrorType -> CodegenError
CC.CodegenError SrcLoc
loc (CodegenErrorType -> CodegenError)
-> CodegenErrorType -> CodegenError
forall a b. (a -> b) -> a -> b
$ String -> CodegenErrorType
CC.VariableNotFound String
name
Just Operand
ptr -> do
let varTy :: Type
varTy = Operand -> Type
forall a. Typed a => a -> Type
TD.typeOf Operand
ptr
expectedType :: Type
expectedType = Type -> Type
forall a. ToLLVM a => a -> Type
ET.toLLVM Type
type'
if Type
varTy Type -> Type -> Bool
forall a. Eq a => a -> a -> Bool
== Type
expectedType
then Operand -> m Operand
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Operand
ptr
else case Type
varTy of
T.PointerType (T.FunctionType {}) AddrSpace
_ -> Operand -> m Operand
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Operand
ptr
T.PointerType Type
_ AddrSpace
_ -> Operand -> Word32 -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Word32 -> m Operand
I.load Operand
ptr Word32
0
Type
_ -> Operand -> m Operand
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Operand
ptr
generateVar Expr
expr =
CodegenError -> m Operand
forall a. CodegenError -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
E.throwError (CodegenError -> m Operand) -> CodegenError -> m Operand
forall a b. (a -> b) -> a -> b
$ SrcLoc -> CodegenErrorType -> CodegenError
CC.CodegenError (Expr -> SrcLoc
SU.getLoc Expr
expr) (CodegenErrorType -> CodegenError)
-> CodegenErrorType -> CodegenError
forall a b. (a -> b) -> a -> b
$ Expr -> CodegenErrorType
CC.UnsupportedDefinition Expr
expr
generateAssignment :: (CS.MonadCodegen m, EG.ExprGen AT.Expr) => AT.Expr -> m AST.Operand
generateAssignment :: forall (m :: * -> *).
(MonadCodegen m, ExprGen Expr) =>
Expr -> m Operand
generateAssignment (AT.Assignment SrcLoc
_ Expr
expr Expr
valueExpr) = do
Operand
value <- Expr -> m Operand
forall a (m :: * -> *).
(ExprGen a, MonadCodegen m) =>
a -> m Operand
forall (m :: * -> *). MonadCodegen m => Expr -> m Operand
EG.generateExpr Expr
valueExpr
case Expr
expr of
AT.Var SrcLoc
_ String
name Type
_ -> do
Maybe Operand
maybeVar <- String -> m (Maybe Operand)
forall (m :: * -> *). VarBinding m => String -> m (Maybe Operand)
CS.getVar String
name
case Maybe Operand
maybeVar of
Just Operand
ptr -> do
Operand -> Word32 -> Operand -> m ()
forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Word32 -> Operand -> m ()
I.store Operand
ptr Word32
0 Operand
value
Operand -> m Operand
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Operand
value
Maybe Operand
Nothing -> CodegenError -> m Operand
forall a. CodegenError -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
E.throwError (CodegenError -> m Operand) -> CodegenError -> m Operand
forall a b. (a -> b) -> a -> b
$ SrcLoc -> CodegenErrorType -> CodegenError
CC.CodegenError (Expr -> SrcLoc
SU.getLoc Expr
expr) (CodegenErrorType -> CodegenError)
-> CodegenErrorType -> CodegenError
forall a b. (a -> b) -> a -> b
$ String -> CodegenErrorType
CC.VariableNotFound String
name
AT.ArrayAccess SrcLoc
_ (AT.Var SrcLoc
_ String
name Type
_) Expr
indexExpr -> do
Maybe Operand
maybeVar <- String -> m (Maybe Operand)
forall (m :: * -> *). VarBinding m => String -> m (Maybe Operand)
CS.getVar String
name
Operand
ptr <- case Maybe Operand
maybeVar of
Just Operand
arrayPtr -> Operand -> m Operand
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Operand
arrayPtr
Maybe Operand
Nothing -> CodegenError -> m Operand
forall a. CodegenError -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
E.throwError (CodegenError -> m Operand) -> CodegenError -> m Operand
forall a b. (a -> b) -> a -> b
$ SrcLoc -> CodegenErrorType -> CodegenError
CC.CodegenError (Expr -> SrcLoc
SU.getLoc Expr
expr) (CodegenErrorType -> CodegenError)
-> CodegenErrorType -> CodegenError
forall a b. (a -> b) -> a -> b
$ String -> CodegenErrorType
CC.VariableNotFound String
name
Operand
index <- Expr -> m Operand
forall a (m :: * -> *).
(ExprGen a, MonadCodegen m) =>
a -> m Operand
forall (m :: * -> *). MonadCodegen m => Expr -> m Operand
EG.generateExpr Expr
indexExpr
Operand
elementPtr <- Operand -> [Operand] -> m Operand
forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> [Operand] -> m Operand
I.gep Operand
ptr [Integer -> Operand
IC.int32 Integer
0, Operand
index]
Operand -> Word32 -> Operand -> m ()
forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Word32 -> Operand -> m ()
I.store Operand
elementPtr Word32
0 Operand
value
Operand -> m Operand
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Operand
value
AT.UnaryOp SrcLoc
_ UnaryOperation
AT.Deref (AT.Var SrcLoc
_ String
name Type
_) -> do
Maybe Operand
maybeVar <- String -> m (Maybe Operand)
forall (m :: * -> *). VarBinding m => String -> m (Maybe Operand)
CS.getVar String
name
case Maybe Operand
maybeVar of
Just Operand
ptr -> do
Operand
actualPtr <- Operand -> Word32 -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Word32 -> m Operand
I.load Operand
ptr Word32
0
Operand -> Word32 -> Operand -> m ()
forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Word32 -> Operand -> m ()
I.store Operand
actualPtr Word32
0 Operand
value
Operand -> m Operand
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Operand
value
Maybe Operand
Nothing -> CodegenError -> m Operand
forall a. CodegenError -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
E.throwError (CodegenError -> m Operand) -> CodegenError -> m Operand
forall a b. (a -> b) -> a -> b
$ SrcLoc -> CodegenErrorType -> CodegenError
CC.CodegenError (Expr -> SrcLoc
SU.getLoc Expr
expr) (CodegenErrorType -> CodegenError)
-> CodegenErrorType -> CodegenError
forall a b. (a -> b) -> a -> b
$ String -> CodegenErrorType
CC.VariableNotFound String
name
AT.StructAccess {} -> do
(Operand
fieldPtr, Type
_) <- Expr -> m (Operand, Type)
forall (m :: * -> *).
(MonadCodegen m, ExprGen Expr) =>
Expr -> m (Operand, Type)
ED.getStructFieldPointer Expr
expr
Operand -> Word32 -> Operand -> m ()
forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Word32 -> Operand -> m ()
I.store Operand
fieldPtr Word32
0 Operand
value
Operand -> m Operand
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Operand
value
Expr
_ -> CodegenError -> m Operand
forall a. CodegenError -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
E.throwError (CodegenError -> m Operand) -> CodegenError -> m Operand
forall a b. (a -> b) -> a -> b
$ SrcLoc -> CodegenErrorType -> CodegenError
CC.CodegenError (Expr -> SrcLoc
SU.getLoc Expr
expr) (CodegenErrorType -> CodegenError)
-> CodegenErrorType -> CodegenError
forall a b. (a -> b) -> a -> b
$ Expr -> CodegenErrorType
CC.UnsupportedDefinition Expr
expr
generateAssignment Expr
expr =
CodegenError -> m Operand
forall a. CodegenError -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
E.throwError (CodegenError -> m Operand) -> CodegenError -> m Operand
forall a b. (a -> b) -> a -> b
$ SrcLoc -> CodegenErrorType -> CodegenError
CC.CodegenError (Expr -> SrcLoc
SU.getLoc Expr
expr) (CodegenErrorType -> CodegenError)
-> CodegenErrorType -> CodegenError
forall a b. (a -> b) -> a -> b
$ Expr -> CodegenErrorType
CC.UnsupportedDefinition Expr
expr