, literalType, literalPrimRep
, hashLiteral
- , inIntRange, inWordRange, tARGET_MAX_INT
+ , inIntRange, inWordRange, tARGET_MAX_INT, inCharRange
, word2IntLit, int2WordLit, char2IntLit, int2CharLit
, float2IntLit, int2FloatLit, double2IntLit, int2DoubleLit
tARGET_MAX_INT = 2147483647
#endif
tARGET_MAX_WORD = (tARGET_MAX_INT * 2) + 1
+
+tARGET_MAX_CHAR :: Int
+tARGET_MAX_CHAR = 0x10ffff
\end{code}
inIntRange, inWordRange :: Integer -> Bool
inIntRange x = x >= tARGET_MIN_INT && x <= tARGET_MAX_INT
inWordRange x = x >= 0 && x <= tARGET_MAX_WORD
+
+inCharRange :: Int -> Bool
+inCharRange c = c >= 0 && c <= tARGET_MAX_CHAR
\end{code}
Coercions
import RnEnv
import RnHiFiles ( lookupFixityRn )
import CmdLineOpts ( DynFlag(..), opt_IgnoreAsserts )
-import Literal ( inIntRange )
+import Literal ( inIntRange, inCharRange )
import BasicTypes ( Fixity(..), FixityDirection(..), defaultFixity, negateFixity )
import PrelNames ( hasKey, assertIdKey, minusName, negateName, fromIntegerName,
eqClass_RDR, foldr_RDR, build_RDR, eqString_RDR,
are made available.
\begin{code}
-litFVs (HsChar c) = returnRn (unitFV charTyCon_name)
+litFVs (HsChar c)
+ = checkRn (inCharRange c) (bogusCharError c) `thenRn_`
+ returnRn (unitFV charTyCon_name)
+
litFVs (HsCharPrim c) = returnRn (unitFV (getName charPrimTyCon))
litFVs (HsString s) = returnRn (mkFVs [listTyCon_name, charTyCon_name])
litFVs (HsStringPrim s) = returnRn (unitFV (getName addrPrimTyCon))
doStmtListErr e
= sep [ptext SLIT("`do' statements must end in expression:"),
nest 4 (ppr e)]
+
+bogusCharError c
+ = ptext SLIT("character literal out of range: '\\") <> int c <> char '\''
\end{code}
import {-# SOURCE #-} Name( Name )
-import IO ( Handle, hPutChar, hPutStr, stderr, stdout )
import CmdLineOpts ( opt_PprStyle_Debug, opt_PprUserLength )
import FastString
import qualified Pretty
import Pretty ( Doc, Mode(..), TextDetails(..), fullRender )
import Panic
+
+import Word ( Word32 )
+import IO ( Handle, hPutChar, hPutStr, stderr, stdout )
import Char ( chr, ord, isDigit )
\end{code}
| c == ord '\r' = "\\r" ++ rest
| c == ord '\t' = "\\t" ++ rest
| c == ord '\v' = "\\v" ++ rest
- | otherwise = ('\\':) $ shows c $ case rest of
+ | otherwise = ('\\':) $ shows (fromIntegral c :: Word32) $ case rest of
d:_ | isDigit d -> "\\&" ++ rest
_ -> rest
-- of Char and String.
pprHsChar :: Int -> SDoc
-pprHsChar c = text (show (chr c))
+pprHsChar c | not (inCharRange c) = char '\\' <> show (fromIntegral c :: Word32)
+ | otherwise = text (show (chr c))
pprHsString :: FastString -> SDoc
pprHsString fs = text (show (unpackFS fs))