content: --------------------------------------------------------------------------------
  -- | Division by zero checks.
  --------------------------------------------------------------------------------
  
  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 "divZ" (expFoldDefault divAssert)
  
  --------------------------------------------------------------------------------
  
  -- Claim that the divisor expression cannnot equal zero.  If we don't have a
  -- division-causing expression, return Nothing.
  divAssert :: I.Type -> I.Expr -> FolderStmt ()
  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
        _                      -> return ()
    _               -> return ()
  
    where
    ma x = insert $ I.CompilerAssert $ 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.TyIndex _-> 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."
  
  --------------------------------------------------------------------------------
  