module Ivory.Opts.DivZero
( divZeroFold
) where
import Ivory.Opts.AssertFold
import qualified Ivory.Language.Syntax.AST as I
import qualified Ivory.Language.Syntax.Type as I
divZeroFold :: I.Proc -> I.Proc
divZeroFold = procFold (expFoldDefault divAssert)
divAssert :: I.Type -> I.Expr -> [I.Expr]
divAssert ty e0 = case e0 of
I.ExpOp op args ->
case (op,args) of
(I.ExpDiv,[_,r]) -> ma r
(I.ExpMod,[_,r]) -> ma r
(I.ExpRecip,[e]) -> ma e
(I.ExpFLog,[e]) -> ma e
(I.ExpFLogBase,[_,r]) -> ma r
_ -> []
_ -> []
where
ma x = [I.ExpOp (I.ExpNeq ty) [x,zeroExp]]
zeroExp = case ty of
I.TyInt _ -> I.ExpLit (I.LitInteger 0)
I.TyWord _ -> I.ExpLit (I.LitInteger 0)
I.TyFloat -> I.ExpLit (I.LitFloat 0)
I.TyDouble -> I.ExpLit (I.LitDouble 0)
_ -> error $
"ivory opts: unrecognized expression in Div by zero checking."