diff options
Diffstat (limited to 'BuildIR.hs')
-rw-r--r-- | BuildIR.hs | 49 |
1 files changed, 39 insertions, 10 deletions
@@ -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 ++ ")" |