aboutsummaryrefslogtreecommitdiff
path: root/BuildIR.hs
diff options
context:
space:
mode:
Diffstat (limited to 'BuildIR.hs')
-rw-r--r--BuildIR.hs82
1 files changed, 45 insertions, 37 deletions
diff --git a/BuildIR.hs b/BuildIR.hs
index f40e141..c70d538 100644
--- a/BuildIR.hs
+++ b/BuildIR.hs
@@ -14,6 +14,7 @@ import Defs
import Intermediate
import Pretty
import TypeRules
+import Utils
type Scope = Map.Map Name (Ref, Type)
@@ -49,6 +50,15 @@ genTemp sz = liftM (Temp sz) genId
genStructTemp :: Size -> BuildM Ref
genStructTemp sz = liftM (StructTemp sz) genId
+genTempForType :: Type -> BuildM Ref
+genTempForType t@(TStruct _) = genStructTemp (sizeof t)
+genTempForType t = genTemp (sizeof t)
+
+genTempLike :: Ref -> BuildM Ref
+genTempLike (Temp sz _) = genTemp sz
+genTempLike (StructTemp sz _) = genStructTemp sz
+genTempLike _ = undefined
+
newBlock :: BuildM Id
newBlock = do
i <- genId
@@ -125,7 +135,7 @@ internString :: String -> BuildM Ref
internString str = do
i <- genId
let n = "__str_cnst_" ++ show i
- ref <- genTemp (sizeof TInt)
+ ref <- genTempForType TInt
addIns $ ILea ref n
state $ \s -> (ref, s {internedStrings = internedStrings s ++ [(n, str)]})
@@ -180,7 +190,7 @@ convertStatement :: Statement -> Id -> BuildM ()
convertStatement (SDecl t n e) nextnext = do
endid <- newBlockNoSwitch
ref <- convertExpression e endid
- varref <- genTemp (sizeof t)
+ varref <- genTempForType t
scopeInsert n varref t
switchBlock endid
addIns $ IMov varref ref
@@ -235,12 +245,12 @@ convertStatement SDebugger nextnext = do
convertExpression :: Expression -> Id -> BuildM Ref
convertExpression (ELit (LInt n) _) nextnext = do
- ref <- genTemp (sizeof TInt)
+ ref <- genTempForType TInt
addIns $ IMov ref (Constant (sizeof TInt) (fromInteger n))
setTerm $ IJmp nextnext
return ref
convertExpression (ELit (LChar c) _) nextnext = do
- ref <- genTemp (sizeof TChar)
+ ref <- genTempForType TChar
addIns $ IMov ref (Constant (sizeof TChar) (fromIntegral $ ord c))
setTerm $ IJmp nextnext
return ref
@@ -248,7 +258,7 @@ convertExpression (ELit (LVar n) _) nextnext = do
mres <- findVar n
case mres of
Just (_, (r, t)) -> do
- ref <- genTemp (sizeof t)
+ ref <- genTempForType t
addIns $ IMov ref r
setTerm $ IJmp nextnext
return ref
@@ -264,7 +274,7 @@ convertExpression (ELit (LCall n al) mrt) nextnext = do
addIns $ ICall n refs
return $ Temp 0 (-1)
Just typ -> do
- r <- genTemp (sizeof typ)
+ r <- genTempForType typ
addIns $ ICallr r n refs
return r
setTerm $ IJmp nextnext
@@ -283,7 +293,7 @@ convertExpression (ELit (LStruct ms) stype) nextnext = do
setTerm $ IJmp nextnext
return ref
convertExpression (EBin BOAnd e1 e2 _) nextnext = do
- destref <- genTemp (sizeof TInt)
+ destref <- genTempForType TInt
bl2 <- newBlockNoSwitch
blTryR <- newBlockNoSwitch
bl3 <- newBlockNoSwitch
@@ -317,7 +327,7 @@ convertExpression (EBin bo e1 e2 _) nextnext = do
bl3 <- newBlockNoSwitch
ref2 <- convertExpression e2 bl3
switchBlock bl3
- ref <- genTemp (sizeof $ fromJust $ retTypeBO bo (fromJust $ typeof e1) (fromJust $ typeof e2))
+ ref <- genTempForType (fromJust $ retTypeBO bo (fromJust $ typeof e1) (fromJust $ typeof e2))
case bo of
BOAdd -> addIns $ IAri AAdd ref ref1 ref2
BOSub -> addIns $ IAri ASub ref ref1 ref2
@@ -343,7 +353,7 @@ convertExpression (EUn UONot e mt) nextnext =
convertExpression (EUn UONeg e mt) nextnext =
convertExpression (EBin BOSub (ELit (LInt 0) (typeof e)) e mt) nextnext
convertExpression (ESubscript arr sub t) nextnext = do
- let elemsz = sizeof $ fromJust t
+ let elemtype = fromJust t
bl2 <- newBlockNoSwitch
arrref <- convertExpression arr bl2
switchBlock bl2
@@ -352,8 +362,8 @@ convertExpression (ESubscript arr sub t) nextnext = do
switchBlock bl3
offref <- genTemp (refSize subref)
elemptr <- genTemp (refSize arrref)
- arrszptr <- genTemp (sizeof TInt)
- arrsz <- genTemp (sizeof TInt)
+ arrszptr <- genTempForType TInt
+ arrsz <- genTempForType TInt
errbl <- gets errorBlock
@@ -363,21 +373,19 @@ convertExpression (ESubscript arr sub t) nextnext = do
setTerm $ IJcc CUGeq subref arrsz errbl bl4
switchBlock bl4
- addIns $ IAri AMul offref subref (Constant (refSize subref) (fromIntegral elemsz))
+ addIns $ IAri AMul offref subref (Constant (refSize subref) (fromIntegral $ sizeof elemtype))
addIns $ IAri AAdd elemptr arrref offref
- ref <- genTemp elemsz
+ ref <- genTempForType elemtype
addIns $ ILoad ref elemptr
setTerm $ IJmp nextnext
return ref
convertExpression (EGet st n t) nextnext = do
- let elemsz = sizeof $ fromJust t
+ let elemtype = fromJust t
+ assertM $ structMemberType (fromJust $ typeof st) n == elemtype
bl2 <- newBlockNoSwitch
stref <- convertExpression st bl2
switchBlock bl2
- let subtype = structMemberType (fromJust $ typeof st) n
- eref <- case subtype of
- TStruct _ -> genStructTemp elemsz
- _ -> genTemp elemsz
+ eref <- genTempForType elemtype
addIns $ IGet eref stref (offsetInStruct (fromJust $ typeof st) n)
setTerm $ IJmp nextnext
return eref
@@ -391,7 +399,7 @@ convertExpression (ECast dt e) nextnext = do
when (not $ isIntegralType typ && isIntegralType dt) $
error $ "convertExpression: unimplemented cast from " ++ pretty typ ++
" to " ++ pretty dt
- ref <- genTemp (sizeof dt)
+ ref <- genTempForType dt
bl <- newBlockNoSwitch
eref <- convertExpression e bl
switchBlock bl
@@ -404,10 +412,10 @@ convertExpression (ENew t sze) nextnext = do
bl2 <- newBlockNoSwitch
szref <- convertExpression sze bl2
switchBlock bl2
- ref' <- genTemp (sizeof $ TArr t Nothing)
- ref <- genTemp (sizeof $ TArr t Nothing)
- argref' <- genTemp (sizeof TInt)
- argref <- genTemp (sizeof TInt)
+ ref' <- genTempForType (TArr t Nothing)
+ ref <- genTempForType (TArr t Nothing)
+ argref' <- genTempForType TInt
+ argref <- genTempForType TInt
addIns $ IAri AMul argref' szref (Constant (sizeof TInt) (fromIntegral $ sizeof t))
addIns $ IAri AAdd argref argref' (Constant (sizeof TInt) (fromIntegral $ sizeof TInt))
addIns $ ICallr ref' "_builtin_malloc" [argref]
@@ -433,7 +441,7 @@ convertAsExpression topae@(AEGet _ _ _) valueref nextnext = do
addIns $ ISet vref offset valueref
aesubscript@(AESubscript _ _ _) -> do
elemptr <- getAESubscriptStoreRef aesubscript
- fieldptr <- genTemp (refSize elemptr)
+ fieldptr <- genTempLike elemptr
addIns $ IAri AAdd fieldptr elemptr (Constant (refSize elemptr) (fromIntegral offset))
addIns $ IStore fieldptr valueref
AEGet _ _ _ -> undefined
@@ -461,10 +469,10 @@ getAESubscriptStoreRef (AESubscript ae2 expr mrt) = do
bl2 <- newBlockNoSwitch
subref <- convertExpression expr bl2
switchBlock bl2
- offref <- genTemp (sizeof TInt)
- elemptr <- genTemp (sizeof TInt)
- arrszptr <- genTemp (sizeof TInt)
- arrsz <- genTemp (sizeof TInt)
+ offref <- genTempForType TInt
+ elemptr <- genTempForType TInt
+ arrszptr <- genTempForType TInt
+ arrsz <- genTempForType TInt
errbl <- gets errorBlock
@@ -486,19 +494,19 @@ getAESubscriptStoreRef (AESubscript ae2 expr mrt) = do
Just (_, (r, t)) -> return (r, t)
Nothing -> throwError $ "Undefined variable '" ++ n ++ "'" ++
" used in assignment expression"
- ref <- genTemp (sizeof t)
+ ref <- genTempForType t
addIns $ IMov ref vref
return ref
goLoad (AESubscript ae expr' _) = do
- let elemsz = sizeof $ fromJust $ typeof ae
+ let elemtype = fromJust $ typeof ae
ref <- goLoad ae
bl2 <- newBlockNoSwitch
eref <- convertExpression expr' bl2
switchBlock bl2
- offref <- genTemp (sizeof TInt)
- elemptr <- genTemp (sizeof TInt)
- arrszptr <- genTemp (sizeof TInt)
- arrsz <- genTemp (sizeof TInt)
+ offref <- genTempForType TInt
+ elemptr <- genTempForType TInt
+ arrszptr <- genTempForType TInt
+ arrsz <- genTempForType TInt
errbl <- gets errorBlock
@@ -508,15 +516,15 @@ getAESubscriptStoreRef (AESubscript ae2 expr mrt) = do
setTerm $ IJcc CUGeq eref arrsz errbl bl3
switchBlock bl3
- addIns $ IAri AMul offref eref (Constant (sizeof TInt) (fromIntegral elemsz))
+ addIns $ IAri AMul offref eref (Constant (sizeof TInt) (fromIntegral $ sizeof elemtype))
addIns $ IAri AAdd elemptr ref offref
- dstref <- genTemp elemsz
+ dstref <- genTempForType elemtype
addIns $ ILoad dstref elemptr
return dstref
goLoad topae@(AEGet topup _ _) = do
let (core, _, offset) = collectAESets topae
coreref <- goLoad core
- ref <- genTemp (sizeof $ fromJust $ typeof topup)
+ ref <- genTempForType (fromJust $ typeof topup)
addIns $ IGet ref coreref offset
return ref
getAESubscriptStoreRef _ = undefined