diff options
Diffstat (limited to 'BuildIR.hs')
-rw-r--r-- | BuildIR.hs | 49 |
1 files changed, 47 insertions, 2 deletions
@@ -23,6 +23,7 @@ data BuildState = BuildState scopeStack :: [Scope], loopStack :: [Id], currentBlock :: Id, + errorBlock :: Id, blockMap :: Map.Map Id BB } initBuildState :: BuildState @@ -31,6 +32,7 @@ initBuildState = BuildState scopeStack = [], loopStack = [], currentBlock = undefined, + errorBlock = undefined, blockMap = Map.empty } newtype BuildM a = BuildM {unBuildM :: StateT BuildState (Except String) a} @@ -56,6 +58,9 @@ newBlockNoSwitch = do modify $ \s -> s {blockMap = Map.insert i block (blockMap s)} return i +setErrorBlock :: Id -> BuildM () +setErrorBlock i = modify $ \s -> s {errorBlock = i} + addIns :: IRIns -> BuildM () addIns ins = modify $ \s -> s { @@ -121,6 +126,8 @@ buildIR (Program vars funcs) = clearBlockMap firstid <- newBlock lastid <- newBlockNoSwitch + makeErrorBlock >>= setErrorBlock + switchBlock firstid withScope $ do forM_ al $ \(at, an) -> scopeInsert an (Argument (sizeof at) an) at convertBlock bl lastid @@ -129,6 +136,13 @@ buildIR (Program vars funcs) = bblist <- getAllBlocks return $ IRFunc rt n al bblist firstid + makeErrorBlock :: BuildM Id + makeErrorBlock = do + bl <- newBlock + addIns $ ICall "_builtin_outofbounds" [] + setTerm IUnreachable + return bl + result :: BuildM IRProgram result = do withScope $ do @@ -196,6 +210,9 @@ convertStatement (SReturn (Just e)) _ = do setTerm $ IRetr ref convertStatement (SExpr e) nextnext = do void $ convertExpression e nextnext +convertStatement SDebugger nextnext = do + addIns IDebugger + setTerm $ IJmp nextnext convertExpression :: Expression -> Id -> BuildM Ref convertExpression (ELit (LInt n) _) nextnext = do @@ -282,6 +299,9 @@ convertExpression (EBin bo e1 e2 _) nextnext = do BOGeq -> addIns $ IAri AGeq ref ref1 ref2 BOLeq -> addIns $ IAri ALeq ref ref1 ref2 BOPow -> error $ "Pow operator not implemented" + BOBitAnd -> addIns $ IAri AAnd ref ref1 ref2 + BOBitOr -> addIns $ IAri AOr ref ref1 ref2 + BOBitXor -> addIns $ IAri AXor ref ref1 ref2 BOAnd -> undefined BOOr -> undefined setTerm $ IJmp nextnext @@ -301,6 +321,15 @@ convertExpression (ESubscript arr sub t) nextnext = do offref <- genTemp (refSize subref) off8ref <- genTemp (refSize subref) elemptr <- genTemp (refSize arrref) + arrsz <- genTemp (sizeof TInt) + + errbl <- gets errorBlock + + addIns $ ILoad arrsz arrref + bl4 <- newBlockNoSwitch + setTerm $ IJcc CUGeq subref arrsz errbl bl4 + + switchBlock bl4 addIns $ IAri AMul offref subref (Constant (refSize subref) (fromIntegral elemsz)) addIns $ IAri AAdd off8ref offref (Constant (refSize subref) (fromIntegral $ sizeof TInt)) addIns $ IAri AAdd elemptr arrref off8ref @@ -355,7 +384,15 @@ convertAsExpression (AESubscript ae2 expr mrt) valueref nextnext = do offref' <- genTemp (sizeof TInt) offref <- genTemp (sizeof TInt) elemptr <- genTemp (sizeof TInt) - -- TODO: do bounds checking + arrsz <- genTemp (sizeof TInt) + + errbl <- gets errorBlock + + addIns $ ILoad arrsz ae2ref + bl3 <- newBlockNoSwitch + setTerm $ IJcc CUGeq subref arrsz errbl bl3 + + switchBlock bl3 addIns $ IAri AMul offref' subref (Constant (sizeof TInt) (fromIntegral elemsz)) addIns $ IAri AAdd offref offref' (Constant (sizeof TInt) (fromIntegral $ sizeof TInt)) addIns $ IAri AAdd elemptr ae2ref offref @@ -381,7 +418,15 @@ convertAsExpression (AESubscript ae2 expr mrt) valueref nextnext = do offref' <- genTemp (sizeof TInt) offref <- genTemp (sizeof TInt) elemptr <- genTemp (sizeof TInt) - -- TODO: do bounds checking + arrsz <- genTemp (sizeof TInt) + + errbl <- gets errorBlock + + addIns $ ILoad arrsz ref + bl3 <- newBlockNoSwitch + setTerm $ IJcc CUGeq eref arrsz errbl bl3 + + switchBlock bl3 addIns $ IAri AMul offref' eref (Constant (sizeof TInt) (fromIntegral elemsz)) addIns $ IAri AAdd offref offref' (Constant (sizeof TInt) (fromIntegral $ sizeof TInt)) addIns $ IAri AAdd elemptr ref offref |