aboutsummaryrefslogtreecommitdiff
path: root/BuildIR.hs
diff options
context:
space:
mode:
Diffstat (limited to 'BuildIR.hs')
-rw-r--r--BuildIR.hs27
1 files changed, 23 insertions, 4 deletions
diff --git a/BuildIR.hs b/BuildIR.hs
index c64adb1..5b12dc2 100644
--- a/BuildIR.hs
+++ b/BuildIR.hs
@@ -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