diff --git a/src/Expr.hs b/src/Expr.hs index 3d0023556d8344a9f1e71e7b409285fa3aa88f8d..a1ad5379ed2e57882c8ff0f9c777d3216fc73c08 100644 --- a/src/Expr.hs +++ b/src/Expr.hs @@ -231,8 +231,8 @@ genExpr' _width = sized gen [ binOp EAdd , binOp ESub , binOp EMul - , divOp EQuot - , divOp ERem + , quotOp + , remOp , ENegate <$> arbitrary ] @@ -267,7 +267,20 @@ genExpr' _width = sized gen ELit <$> chooseNumber (0, fromIntegral $ widthBits (knownWidth @width) - 1) subexpr2 = scale (`div` 2) genExpr binOp f = f <$> subexpr2 <*> subexpr2 - divOp f = f <$> arbitrary <*> subexpr2 <*> nonzero subexpr2 + quotOp = do + signedness <- arbitrary + num <- subexpr2 + let num' = interpret num + -- divisions where the result overflows the expression width + -- (e.g. (-128::W8) / (-1::W8)) are undefined. + -- See test-primops#1. + okay_denom denom + | Signed <- signedness = + num' /= maxBound || interpret denom /= maxBound + | otherwise = True + denom <- suchThat (nonzero subexpr2) okay_denom + return $ EQuot signedness num denom + remOp = ERem <$> arbitrary <*> subexpr2 <*> nonzero subexpr2 nonzero = flip suchThat $ \x -> interpret x /= 0 -- * SomeExpr diff --git a/src/Number.hs b/src/Number.hs index 0d58fe15fbbe6e1cbd7f5e0065aff3fa69668a8e..c236a967343a64c2fa306d85dacf4dd726f091be 100644 --- a/src/Number.hs +++ b/src/Number.hs @@ -143,6 +143,7 @@ instance (KnownWidth width) => Enum (Number width) where | n > maxBound = error "overflow" | otherwise = n +-- | Unsigned range. instance (KnownWidth width) => Bounded (Number width) where minBound = Number 0 maxBound = Number ((1 `shiftL` widthBits (knownWidth @width)) - 1)