diff options
Diffstat (limited to 'BuildIR.hs')
-rw-r--r-- | BuildIR.hs | 27 |
1 files changed, 23 insertions, 4 deletions
@@ -24,7 +24,8 @@ data BuildState = BuildState loopStack :: [Id], currentBlock :: Id, errorBlock :: Id, - blockMap :: Map.Map Id BB } + blockMap :: Map.Map Id BB, + internedStrings :: [(Name, String)] } initBuildState :: BuildState initBuildState = BuildState @@ -33,7 +34,8 @@ initBuildState = BuildState loopStack = [], currentBlock = undefined, errorBlock = undefined, - blockMap = Map.empty } + blockMap = Map.empty, + internedStrings = [] } newtype BuildM a = BuildM {unBuildM :: StateT BuildState (Except String) a} deriving (Functor, Applicative, Monad, MonadState BuildState, MonadError String) @@ -116,6 +118,14 @@ findVar n = do return $ fmap (\idx -> (idx, fromJust (results !! idx))) $ findIndex isJust results +internString :: String -> BuildM Ref +internString str = do + i <- genId + let n = "__str_cnst_" ++ show i + ref <- genTemp (sizeof TInt) + addIns $ ILea ref n + state $ \s -> (ref, s {internedStrings = internedStrings s ++ [(n, str)]}) + buildIR :: Program -> Error IRProgram buildIR (Program vars funcs) = @@ -123,7 +133,7 @@ buildIR (Program vars funcs) = where goDFunc :: DFunc -> BuildM IRFunc goDFunc (DFunc rt n al bl) = do - clearBlockMap + clearBlockMap firstid <- newBlock lastid <- newBlockNoSwitch makeErrorBlock >>= setErrorBlock @@ -147,7 +157,12 @@ buildIR (Program vars funcs) = result = do withScope $ do mapM_ (\(DVar t n _) -> scopeInsert n (Global (sizeof t) n) t) vars - IRProgram vars <$> mapM goDFunc funcs + funcs' <- mapM goDFunc funcs + ns <- gets internedStrings + let strvars = flip map ns $ \(n, str) -> + let t = TArr TChar (Just $ fromIntegral $ length str) + in DVar t n (ELit (LStr str) (Just t)) + return $ IRProgram (vars ++ strvars) funcs' convertBlock :: Block -> Id -> BuildM () convertBlock (Block sts) nextnext = do @@ -250,6 +265,10 @@ convertExpression (ELit (LCall n al) mrt) nextnext = do return r setTerm $ IJmp nextnext return destref +convertExpression (ELit (LStr s) _) nextnext = do + ref <- internString s + setTerm $ IJmp nextnext + return ref convertExpression (EBin BOAnd e1 e2 _) nextnext = do destref <- genTemp (sizeof TInt) bl2 <- newBlockNoSwitch |