module Ivory.Language.IIntegral where import Ivory.Language.Sint import Ivory.Language.Type import Ivory.Language.IBool import Ivory.Language.Uint import qualified Ivory.Language.Syntax.AST as I -------------------------------------------------------------------------------- -- | Integral, without the baggage from Haskell (i.e., supertypes of 'Real' and -- 'Enum'). Defines Euclidian division (rather than truncated division). See -- http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.74.8522. Notable -- properties, beyond the normal div/rem properties, are that -- -- The remainder is always non-negative. -- For d1 < 0, @d0 `iDiv` (-d1) == -(d0 `iDiv` d1)@. -- For d1 < 0, @d0 .% (-d1) == d0 .% d1@. -- -- N.B. `mod` and `rem` are equal if both args are positive, and C has no `mod` -- operator (only `rem`). In Haskell and C, both `mod` and `rem` may return -- negative values. Furthermore, before C99, the result of `rem` is -- implementation-defined. class (IvoryExpr a, IvoryOrd a , Num a) => IvoryIntegral a where -- | Euclidean division. iDiv :: a -> a -> a iDiv d0 d1 = (r ? 0) ? (q-1,q+1),q) where q = wrapExpr (I.ExpOp I.ExpDiv [unwrapExpr d0, unwrapExpr d1]) r = iRem d0 d1 -- | Euclidean remainder. (.%) :: a -> a -> a d0 .% d1 = (r ? 0) ? (r+d1,r-d1),r) where r = iRem d0 d1 (./) :: IvoryIntegral a => a -> a -> a (./) = iDiv -- XXX Dont' export iRem :: IvoryIntegral a => a -> a -> a iRem d0 d1 = wrapExpr (I.ExpOp I.ExpMod [unwrapExpr d0, unwrapExpr d1]) -------------------------------------------------------------------------------- instance IvoryIntegral Sint8 instance IvoryIntegral Sint16 instance IvoryIntegral Sint32 instance IvoryIntegral Sint64 instance IvoryIntegral Uint8 instance IvoryIntegral Uint16 instance IvoryIntegral Uint32 instance IvoryIntegral Uint64 --------------------------------------------------------------------------------