diff options
Diffstat (limited to 'BuildIR.hs')
-rw-r--r-- | BuildIR.hs | 82 |
1 files changed, 45 insertions, 37 deletions
@@ -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 |