diff options
author | tomsmeding <tom.smeding@gmail.com> | 2017-08-26 18:54:41 +0200 |
---|---|---|
committer | tomsmeding <tom.smeding@gmail.com> | 2017-08-26 18:54:41 +0200 |
commit | b2c5ef755bc7a2c736c5f52c4753dde66c04c3aa (patch) | |
tree | 9bda1fbc34a5490494dadf690ae90a2279fade35 /BuildIR.hs | |
parent | 3fd304ea2272432a435e6c877ce002ff3d4c77df (diff) |
Add break statements
Diffstat (limited to 'BuildIR.hs')
-rw-r--r-- | BuildIR.hs | 14 |
1 files changed, 13 insertions, 1 deletions
@@ -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 |