aboutsummaryrefslogtreecommitdiff
path: root/BuildIR.hs
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2017-08-26 18:54:41 +0200
committertomsmeding <tom.smeding@gmail.com>2017-08-26 18:54:41 +0200
commitb2c5ef755bc7a2c736c5f52c4753dde66c04c3aa (patch)
tree9bda1fbc34a5490494dadf690ae90a2279fade35 /BuildIR.hs
parent3fd304ea2272432a435e6c877ce002ff3d4c77df (diff)
Add break statements
Diffstat (limited to 'BuildIR.hs')
-rw-r--r--BuildIR.hs14
1 files changed, 13 insertions, 1 deletions
diff --git a/BuildIR.hs b/BuildIR.hs
index 665dd33..a4be797 100644
--- a/BuildIR.hs
+++ b/BuildIR.hs
@@ -21,6 +21,7 @@ type Scope = Map.Map Name (Ref, Type)
data BuildState = BuildState
{ nextId :: Id,
scopeStack :: [Scope],
+ loopStack :: [Id],
currentBlock :: Id,
blockMap :: Map.Map Id BB }
@@ -28,6 +29,7 @@ initBuildState :: BuildState
initBuildState = BuildState
{ nextId = 0,
scopeStack = [],
+ loopStack = [],
currentBlock = undefined,
blockMap = Map.empty }
@@ -81,6 +83,13 @@ getAllBlocks = liftM Map.elems (gets blockMap)
switchBlock :: Id -> BuildM ()
switchBlock bid = modify $ \s -> s {currentBlock = bid}
+withLoop :: Id -> BuildM a -> BuildM a
+withLoop i act = do
+ modify $ \s -> s {loopStack = i : loopStack s}
+ res <- act
+ modify $ \s -> s {loopStack = tail (loopStack s)}
+ return res
+
withScope :: BuildM a -> BuildM a
withScope act = do
modify $ \s -> s {scopeStack = Map.empty : scopeStack s}
@@ -172,9 +181,12 @@ convertStatement (SWhile c b) nextnext = do
switchBlock cend
setTerm $ IJcc CNeq cref (Constant (refSize cref) 0) body nextnext
switchBlock body
- convertBlock b bodyend
+ withLoop nextnext $ convertBlock b bodyend
switchBlock bodyend
setTerm $ IJmp cond
+convertStatement (SBreak n) _ = do
+ ls <- gets loopStack
+ setTerm $ IJmp (ls !! n)
convertStatement (SReturn Nothing) _ = do
setTerm IRet
convertStatement (SReturn (Just e)) _ = do