Be a bit smarter about figuring out when conversions are precise

This commit is contained in:
Adam Sampson 2007-04-29 14:05:28 +00:00
parent 47ccd704e4
commit 5de146234f
3 changed files with 19 additions and 5 deletions

View File

@ -926,11 +926,13 @@ conversion
t <- dataType
(c, o) <- conversionMode
ot <- typeOfExpression o
let isImprecise = isRealType t || isRealType ot
when (isImprecise && c == A.DefaultConversion) $
fail "imprecise conversion must specify ROUND or TRUNC"
when (not isImprecise && c /= A.DefaultConversion) $
fail "precise conversion cannot specify ROUND or TRUNC"
case (isPreciseConversion ot t, c) of
(False, A.DefaultConversion) ->
fail "imprecise conversion must specify ROUND or TRUNC"
(False, _) -> return ()
(True, A.DefaultConversion) -> return ()
(True, _) ->
fail "precise conversion cannot specify ROUND or TRUNC"
return $ A.Conversion m c t o
<?> "conversion"

View File

@ -21,6 +21,8 @@ nothing to do with parsing.
Types needs cleaning up and Haddocking.
Many of the "lookup" lists should actually be Maps.
## Driver
Add an option for whether to compile out overflow/bounds checks.
@ -31,6 +33,9 @@ Record literals aren't implemented.
## Passes
Come up with an approach to combining simple passes to avoid multiple tree
walks (for example, giving passes a "next thing to try" parameter).
Expression simplification -- this should use generics, so that we can have a
default behaviour that simplifies expressions inside another one.

View File

@ -221,6 +221,13 @@ metaOfExpression e = head $ gmapQ (mkQ emptyMeta findMeta) e
findMeta :: Meta -> Meta
findMeta m = m
-- | Is a conversion between two types precise (i.e. do you need to specify
-- ROUND or TRUNC when doing it)?
isPreciseConversion :: A.Type -> A.Type -> Bool
isPreciseConversion A.Real32 A.Real64 = True
isPreciseConversion fromT toT
= fromT == toT || not (isRealType fromT || isRealType toT)
-- | Will a conversion between two types always succeed?
isSafeConversion :: A.Type -> A.Type -> Bool
isSafeConversion fromT toT = (fromP /= -1) && (toP /= -1) && (fromP <= toP)