{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DataKinds #-}
module Ivory.Opts.FP
( fpFold
) where
import Ivory.Opts.AssertFold
import qualified Ivory.Language.Syntax.AST as I
import qualified Ivory.Language.Syntax.Type as I
fpFold :: I.Proc -> I.Proc
fpFold = procFold "fp" (expFoldDefault fpAssert)
fpAssert :: I.Type -> I.Expr -> FolderStmt ()
fpAssert ty e = case ty of
I.TyFloat -> asst
I.TyDouble -> asst
_ -> return ()
where asst = insert (mkAssert ty e)
mkAssert :: I.Type -> I.Expr -> I.Stmt
mkAssert ty e = I.CompilerAssert $ I.ExpOp I.ExpAnd
[ I.ExpOp I.ExpNot [I.ExpOp (I.ExpIsNan ty) [e]]
, I.ExpOp I.ExpNot [I.ExpOp (I.ExpIsInf ty) [e]] ]