aboutsummaryrefslogtreecommitdiff
path: root/BuildIR.hs
diff options
context:
space:
mode:
Diffstat (limited to 'BuildIR.hs')
-rw-r--r--BuildIR.hs49
1 files changed, 39 insertions, 10 deletions
diff --git a/BuildIR.hs b/BuildIR.hs
index 9eb4d62..028c649 100644
--- a/BuildIR.hs
+++ b/BuildIR.hs
@@ -46,6 +46,9 @@ genId = state $ \s -> (nextId s, s {nextId = nextId s + 1})
genTemp :: Size -> BuildM Ref
genTemp sz = liftM (Temp sz) genId
+genStructTemp :: Size -> BuildM Ref
+genStructTemp sz = liftM (StructTemp sz) genId
+
newBlock :: BuildM Id
newBlock = do
i <- genId
@@ -128,7 +131,7 @@ internString str = do
buildIR :: Program -> Error IRProgram
-buildIR (Program vars funcs) =
+buildIR (Program [] vars funcs) =
runExcept $ evalStateT (unBuildM result) initBuildState
where
goDFunc :: DFunc -> BuildM IRFunc
@@ -163,6 +166,7 @@ buildIR (Program vars funcs) =
let t = TArr TChar (Just $ fromIntegral $ length str)
in DVar t n (ELit (LStr str) (Just t))
return $ IRProgram (vars ++ strvars) funcs'
+buildIR _ = undefined
convertBlock :: Block -> Id -> BuildM ()
convertBlock (Block sts) nextnext = do
@@ -269,6 +273,15 @@ convertExpression (ELit (LStr s) _) nextnext = do
ref <- internString s
setTerm $ IJmp nextnext
return ref
+convertExpression (ELit (LStruct ms) stype) nextnext = do
+ ref <- genStructTemp (sizeof $ fromJust stype)
+ forM_ ms $ \(n,e) -> do
+ bl <- newBlockNoSwitch
+ r <- convertExpression e bl
+ switchBlock bl
+ addIns $ ISet ref (offsetInStruct (fromJust stype) n) r
+ setTerm $ IJmp nextnext
+ return ref
convertExpression (EBin BOAnd e1 e2 _) nextnext = do
destref <- genTemp (sizeof TInt)
bl2 <- newBlockNoSwitch
@@ -356,19 +369,35 @@ convertExpression (ESubscript arr sub t) nextnext = do
addIns $ ILoad ref elemptr
setTerm $ IJmp nextnext
return ref
+convertExpression (EGet st n t) nextnext = do
+ let elemsz = sizeof $ fromJust t
+ bl2 <- newBlockNoSwitch
+ stref <- convertExpression st bl2
+ switchBlock bl2
+ let subtype = structMemberType (fromJust $ typeof st) n
+ eref <- case subtype of
+ TStruct _ -> genStructTemp elemsz
+ _ -> genTemp elemsz
+ addIns $ IGet eref stref (offsetInStruct (fromJust $ typeof st) n)
+ setTerm $ IJmp nextnext
+ return eref
convertExpression (ECast dt e) nextnext = do
let typ = case typeof e of
Nothing -> error $ "Cast subject " ++ show e ++ " has Nothing type"
Just t -> t
- when (not $ isIntegralType typ && isIntegralType dt) $
- error $ "convertExpression: unimplemented cast from " ++ pretty typ ++ " to " ++ pretty dt
- ref <- genTemp (sizeof dt)
- bl <- newBlockNoSwitch
- eref <- convertExpression e bl
- switchBlock bl
- addIns $ IResize ref eref
- setTerm $ IJmp nextnext
- return ref
+ if typ == dt
+ then convertExpression e nextnext
+ else do
+ when (not $ isIntegralType typ && isIntegralType dt) $
+ error $ "convertExpression: unimplemented cast from " ++ pretty typ ++
+ " to " ++ pretty dt
+ ref <- genTemp (sizeof dt)
+ bl <- newBlockNoSwitch
+ eref <- convertExpression e bl
+ switchBlock bl
+ addIns $ IResize ref eref
+ setTerm $ IJmp nextnext
+ return ref
convertExpression (ENew t sze) nextnext = do
when (not $ isBasicType t) $
throwError $ "Array element type in 'new' expression is not a basic type (" ++ pretty t ++ ")"