From 931c8d82f28fb98a7e0ad0a837eff05c08021cbe Mon Sep 17 00:00:00 2001 From: Ben Orchard Date: Tue, 24 May 2022 14:18:45 +0100 Subject: Add sized primitive literal syntax Adds a new LANGUAGE pragma ExtendedLiterals, which enables defining unboxed numeric literals such as `0xFF#Word8 :: Word8#`. Implements GHC proposal 0451: https://github.com/ghc-proposals/ghc-proposals/blob/b384a538b34f79d18a0201455b7b3c473bc8c936/proposals/0451-sized-literals.rst Fixes #21422. Bumps haddock submodule. Co-authored-by: Krzysztof Gogolewski --- compiler/GHC/Driver/Session.hs | 1 + compiler/GHC/Hs/Lit.hs | 40 +++- compiler/GHC/Hs/Syn/Type.hs | 6 + compiler/GHC/HsToCore/Match/Literal.hs | 27 ++- compiler/GHC/Parser.y | 112 ++++++--- compiler/GHC/Parser/Lexer.x | 195 +++++++++++++--- compiler/Language/Haskell/Syntax/Extension.hs | 6 + compiler/Language/Haskell/Syntax/Lit.hs | 13 +- docs/users_guide/9.8.1-notes.rst | 4 + docs/users_guide/exts/extended_literals.rst | 47 ++++ docs/users_guide/exts/literals.rst | 1 + docs/users_guide/exts/primitives.rst | 3 + docs/users_guide/exts/stolen_syntax.rst | 3 + .../ghc-boot-th/GHC/LanguageExtensions/Type.hs | 1 + testsuite/tests/driver/T4437.hs | 3 +- testsuite/tests/extendedliterals/all.T | 3 + .../tests/extendedliterals/extendedliterals01.hs | 41 ++++ .../tests/extendedliterals/extendedliterals02.hs | 15 ++ .../tests/extendedliterals/extendedliterals03.hs | 260 +++++++++++++++++++++ .../extendedliterals/extendedliterals03.stdout | 16 ++ testsuite/tests/ghci/should_run/SizedLiterals.hs | 117 ---------- testsuite/tests/ghci/should_run/SizedLiteralsA.hs | 139 ----------- testsuite/tests/ghci/should_run/all.T | 1 - testsuite/tests/printer/Ppr038.hs | 12 +- utils/check-exact/ExactPrint.hs | 6 + utils/haddock | 2 +- 26 files changed, 739 insertions(+), 335 deletions(-) create mode 100644 docs/users_guide/exts/extended_literals.rst create mode 100644 testsuite/tests/extendedliterals/all.T create mode 100644 testsuite/tests/extendedliterals/extendedliterals01.hs create mode 100644 testsuite/tests/extendedliterals/extendedliterals02.hs create mode 100644 testsuite/tests/extendedliterals/extendedliterals03.hs create mode 100644 testsuite/tests/extendedliterals/extendedliterals03.stdout delete mode 100644 testsuite/tests/ghci/should_run/SizedLiterals.hs delete mode 100644 testsuite/tests/ghci/should_run/SizedLiteralsA.hs diff --git a/compiler/GHC/Driver/Session.hs b/compiler/GHC/Driver/Session.hs index d6dd214c75..da5cf29506 100644 --- a/compiler/GHC/Driver/Session.hs +++ b/compiler/GHC/Driver/Session.hs @@ -3758,6 +3758,7 @@ xFlagsDeps = [ flagSpec "ExplicitForAll" LangExt.ExplicitForAll, flagSpec "ExplicitNamespaces" LangExt.ExplicitNamespaces, flagSpec "ExtendedDefaultRules" LangExt.ExtendedDefaultRules, + flagSpec "ExtendedLiterals" LangExt.ExtendedLiterals, flagSpec "FlexibleContexts" LangExt.FlexibleContexts, flagSpec "FlexibleInstances" LangExt.FlexibleInstances, flagSpec "ForeignFunctionInterface" LangExt.ForeignFunctionInterface, diff --git a/compiler/GHC/Hs/Lit.hs b/compiler/GHC/Hs/Lit.hs index 7d2df811ee..d6c59cc927 100644 --- a/compiler/GHC/Hs/Lit.hs +++ b/compiler/GHC/Hs/Lit.hs @@ -50,7 +50,13 @@ type instance XHsStringPrim (GhcPass _) = SourceText type instance XHsInt (GhcPass _) = NoExtField type instance XHsIntPrim (GhcPass _) = SourceText type instance XHsWordPrim (GhcPass _) = SourceText +type instance XHsInt8Prim (GhcPass _) = SourceText +type instance XHsInt16Prim (GhcPass _) = SourceText +type instance XHsInt32Prim (GhcPass _) = SourceText type instance XHsInt64Prim (GhcPass _) = SourceText +type instance XHsWord8Prim (GhcPass _) = SourceText +type instance XHsWord16Prim (GhcPass _) = SourceText +type instance XHsWord32Prim (GhcPass _) = SourceText type instance XHsWord64Prim (GhcPass _) = SourceText type instance XHsInteger (GhcPass _) = SourceText type instance XHsRat (GhcPass _) = NoExtField @@ -128,14 +134,20 @@ hsLitNeedsParens p = go go (HsString {}) = False go (HsStringPrim {}) = False go (HsInt _ x) = p > topPrec && il_neg x - go (HsIntPrim {}) = False - go (HsWordPrim {}) = False - go (HsInt64Prim {}) = False - go (HsWord64Prim {}) = False go (HsInteger _ x _) = p > topPrec && x < 0 go (HsRat _ x _) = p > topPrec && fl_neg x go (HsFloatPrim {}) = False go (HsDoublePrim {}) = False + go (HsIntPrim {}) = False + go (HsInt8Prim {}) = False + go (HsInt16Prim {}) = False + go (HsInt32Prim {}) = False + go (HsInt64Prim {}) = False + go (HsWordPrim {}) = False + go (HsWord8Prim {}) = False + go (HsWord16Prim {}) = False + go (HsWord64Prim {}) = False + go (HsWord32Prim {}) = False go (XLit _) = False -- | Convert a literal from one index type to another @@ -147,7 +159,13 @@ convertLit (HsStringPrim a x) = HsStringPrim a x convertLit (HsInt a x) = HsInt a x convertLit (HsIntPrim a x) = HsIntPrim a x convertLit (HsWordPrim a x) = HsWordPrim a x +convertLit (HsInt8Prim a x) = HsInt8Prim a x +convertLit (HsInt16Prim a x) = HsInt16Prim a x +convertLit (HsInt32Prim a x) = HsInt32Prim a x convertLit (HsInt64Prim a x) = HsInt64Prim a x +convertLit (HsWord8Prim a x) = HsWord8Prim a x +convertLit (HsWord16Prim a x) = HsWord16Prim a x +convertLit (HsWord32Prim a x) = HsWord32Prim a x convertLit (HsWord64Prim a x) = HsWord64Prim a x convertLit (HsInteger a x b) = HsInteger a x b convertLit (HsRat a x b) = HsRat a x b @@ -182,8 +200,14 @@ instance Outputable (HsLit (GhcPass p)) where ppr (HsFloatPrim _ f) = ppr f <> primFloatSuffix ppr (HsDoublePrim _ d) = ppr d <> primDoubleSuffix ppr (HsIntPrim st i) = pprWithSourceText st (pprPrimInt i) - ppr (HsWordPrim st w) = pprWithSourceText st (pprPrimWord w) + ppr (HsInt8Prim st i) = pprWithSourceText st (pprPrimInt8 i) + ppr (HsInt16Prim st i) = pprWithSourceText st (pprPrimInt16 i) + ppr (HsInt32Prim st i) = pprWithSourceText st (pprPrimInt32 i) ppr (HsInt64Prim st i) = pprWithSourceText st (pprPrimInt64 i) + ppr (HsWordPrim st w) = pprWithSourceText st (pprPrimWord w) + ppr (HsWord8Prim st w) = pprWithSourceText st (pprPrimWord8 w) + ppr (HsWord16Prim st w) = pprWithSourceText st (pprPrimWord16 w) + ppr (HsWord32Prim st w) = pprWithSourceText st (pprPrimWord32 w) ppr (HsWord64Prim st w) = pprWithSourceText st (pprPrimWord64 w) -- in debug mode, print the expression that it's resolved to, too @@ -211,7 +235,13 @@ pmPprHsLit (HsStringPrim _ s) = pprHsBytes s pmPprHsLit (HsInt _ i) = integer (il_value i) pmPprHsLit (HsIntPrim _ i) = integer i pmPprHsLit (HsWordPrim _ w) = integer w +pmPprHsLit (HsInt8Prim _ i) = integer i +pmPprHsLit (HsInt16Prim _ i) = integer i +pmPprHsLit (HsInt32Prim _ i) = integer i pmPprHsLit (HsInt64Prim _ i) = integer i +pmPprHsLit (HsWord8Prim _ w) = integer w +pmPprHsLit (HsWord16Prim _ w) = integer w +pmPprHsLit (HsWord32Prim _ w) = integer w pmPprHsLit (HsWord64Prim _ w) = integer w pmPprHsLit (HsInteger _ i _) = integer i pmPprHsLit (HsRat _ f _) = ppr f diff --git a/compiler/GHC/Hs/Syn/Type.hs b/compiler/GHC/Hs/Syn/Type.hs index a7e21d2458..edcdc39ea0 100644 --- a/compiler/GHC/Hs/Syn/Type.hs +++ b/compiler/GHC/Hs/Syn/Type.hs @@ -77,7 +77,13 @@ hsLitType (HsStringPrim _ _) = addrPrimTy hsLitType (HsInt _ _) = intTy hsLitType (HsIntPrim _ _) = intPrimTy hsLitType (HsWordPrim _ _) = wordPrimTy +hsLitType (HsInt8Prim _ _) = int8PrimTy +hsLitType (HsInt16Prim _ _) = int16PrimTy +hsLitType (HsInt32Prim _ _) = int32PrimTy hsLitType (HsInt64Prim _ _) = int64PrimTy +hsLitType (HsWord8Prim _ _) = word8PrimTy +hsLitType (HsWord16Prim _ _) = word16PrimTy +hsLitType (HsWord32Prim _ _) = word32PrimTy hsLitType (HsWord64Prim _ _) = word64PrimTy hsLitType (HsInteger _ _ ty) = ty hsLitType (HsRat _ _ ty) = ty diff --git a/compiler/GHC/HsToCore/Match/Literal.hs b/compiler/GHC/HsToCore/Match/Literal.hs index 1c21f2a5e6..b44f325b60 100644 --- a/compiler/GHC/HsToCore/Match/Literal.hs +++ b/compiler/GHC/HsToCore/Match/Literal.hs @@ -106,7 +106,13 @@ dsLit l = do HsCharPrim _ c -> return (Lit (LitChar c)) HsIntPrim _ i -> return (Lit (mkLitIntWrap platform i)) HsWordPrim _ w -> return (Lit (mkLitWordWrap platform w)) + HsInt8Prim _ i -> return (Lit (mkLitInt8Wrap i)) + HsInt16Prim _ i -> return (Lit (mkLitInt16Wrap i)) + HsInt32Prim _ i -> return (Lit (mkLitInt32Wrap i)) HsInt64Prim _ i -> return (Lit (mkLitInt64Wrap i)) + HsWord8Prim _ w -> return (Lit (mkLitWord8Wrap w)) + HsWord16Prim _ w -> return (Lit (mkLitWord16Wrap w)) + HsWord32Prim _ w -> return (Lit (mkLitWord32Wrap w)) HsWord64Prim _ w -> return (Lit (mkLitWord64Wrap w)) -- This can be slow for very large literals. See Note [FractionalLit representation] @@ -455,10 +461,23 @@ getSimpleIntegralLit :: HsLit GhcTc -> Maybe (Integer, Type) getSimpleIntegralLit (HsInt _ IL{ il_value = i }) = Just (i, intTy) getSimpleIntegralLit (HsIntPrim _ i) = Just (i, intPrimTy) getSimpleIntegralLit (HsWordPrim _ i) = Just (i, wordPrimTy) +getSimpleIntegralLit (HsInt8Prim _ i) = Just (i, int8PrimTy) +getSimpleIntegralLit (HsInt16Prim _ i) = Just (i, int16PrimTy) +getSimpleIntegralLit (HsInt32Prim _ i) = Just (i, int32PrimTy) getSimpleIntegralLit (HsInt64Prim _ i) = Just (i, int64PrimTy) +getSimpleIntegralLit (HsWord8Prim _ i) = Just (i, word8PrimTy) +getSimpleIntegralLit (HsWord16Prim _ i) = Just (i, word16PrimTy) +getSimpleIntegralLit (HsWord32Prim _ i) = Just (i, word32PrimTy) getSimpleIntegralLit (HsWord64Prim _ i) = Just (i, word64PrimTy) getSimpleIntegralLit (HsInteger _ i ty) = Just (i, ty) -getSimpleIntegralLit _ = Nothing + +getSimpleIntegralLit HsChar{} = Nothing +getSimpleIntegralLit HsCharPrim{} = Nothing +getSimpleIntegralLit HsString{} = Nothing +getSimpleIntegralLit HsStringPrim{} = Nothing +getSimpleIntegralLit HsRat{} = Nothing +getSimpleIntegralLit HsFloatPrim{} = Nothing +getSimpleIntegralLit HsDoublePrim{} = Nothing -- | Extract the Char if the expression is a Char literal. getLHsCharLit :: LHsExpr GhcTc -> Maybe Char @@ -638,7 +657,13 @@ hsLitKey :: Platform -> HsLit GhcTc -> Literal -- HsLit does not. hsLitKey platform (HsIntPrim _ i) = mkLitIntWrap platform i hsLitKey platform (HsWordPrim _ w) = mkLitWordWrap platform w +hsLitKey _ (HsInt8Prim _ i) = mkLitInt8Wrap i +hsLitKey _ (HsInt16Prim _ i) = mkLitInt16Wrap i +hsLitKey _ (HsInt32Prim _ i) = mkLitInt32Wrap i hsLitKey _ (HsInt64Prim _ i) = mkLitInt64Wrap i +hsLitKey _ (HsWord8Prim _ w) = mkLitWord8Wrap w +hsLitKey _ (HsWord16Prim _ w) = mkLitWord16Wrap w +hsLitKey _ (HsWord32Prim _ w) = mkLitWord32Wrap w hsLitKey _ (HsWord64Prim _ w) = mkLitWord64Wrap w hsLitKey _ (HsCharPrim _ c) = mkLitChar c -- This following two can be slow. See Note [FractionalLit representation] diff --git a/compiler/GHC/Parser.y b/compiler/GHC/Parser.y index d95d9d1512..a61a133574 100644 --- a/compiler/GHC/Parser.y +++ b/compiler/GHC/Parser.y @@ -718,6 +718,14 @@ are the most common patterns, rewritten as regular expressions for clarity: PRIMSTRING { L _ (ITprimstring _ _) } PRIMINTEGER { L _ (ITprimint _ _) } PRIMWORD { L _ (ITprimword _ _) } + PRIMINTEGER8 { L _ (ITprimint8 _ _) } + PRIMINTEGER16 { L _ (ITprimint16 _ _) } + PRIMINTEGER32 { L _ (ITprimint32 _ _) } + PRIMINTEGER64 { L _ (ITprimint64 _ _) } + PRIMWORD8 { L _ (ITprimword8 _ _) } + PRIMWORD16 { L _ (ITprimword16 _ _) } + PRIMWORD32 { L _ (ITprimword32 _ _) } + PRIMWORD64 { L _ (ITprimword64 _ _) } PRIMFLOAT { L _ (ITprimfloat _) } PRIMDOUBLE { L _ (ITprimdouble _) } @@ -3873,6 +3881,22 @@ literal :: { Located (HsLit GhcPs) } $ getPRIMINTEGER $1 } | PRIMWORD { sL1 $1 $ HsWordPrim (getPRIMWORDs $1) $ getPRIMWORD $1 } + | PRIMINTEGER8 { sL1 $1 $ HsInt8Prim (getPRIMINTEGER8s $1) + $ getPRIMINTEGER8 $1 } + | PRIMINTEGER16 { sL1 $1 $ HsInt16Prim (getPRIMINTEGER16s $1) + $ getPRIMINTEGER16 $1 } + | PRIMINTEGER32 { sL1 $1 $ HsInt32Prim (getPRIMINTEGER32s $1) + $ getPRIMINTEGER32 $1 } + | PRIMINTEGER64 { sL1 $1 $ HsInt64Prim (getPRIMINTEGER64s $1) + $ getPRIMINTEGER64 $1 } + | PRIMWORD8 { sL1 $1 $ HsWord8Prim (getPRIMWORD8s $1) + $ getPRIMWORD8 $1 } + | PRIMWORD16 { sL1 $1 $ HsWord16Prim (getPRIMWORD16s $1) + $ getPRIMWORD16 $1 } + | PRIMWORD32 { sL1 $1 $ HsWord32Prim (getPRIMWORD32s $1) + $ getPRIMWORD32 $1 } + | PRIMWORD64 { sL1 $1 $ HsWord64Prim (getPRIMWORD64s $1) + $ getPRIMWORD64 $1 } | PRIMCHAR { sL1 $1 $ HsCharPrim (getPRIMCHARs $1) $ getPRIMCHAR $1 } | PRIMSTRING { sL1 $1 $ HsStringPrim (getPRIMSTRINGs $1) @@ -3913,43 +3937,59 @@ bars :: { ([SrcSpan],Int) } -- One or more bars happyError :: P a happyError = srcParseFail -getVARID (L _ (ITvarid x)) = x -getCONID (L _ (ITconid x)) = x -getVARSYM (L _ (ITvarsym x)) = x -getCONSYM (L _ (ITconsym x)) = x -getDO (L _ (ITdo x)) = x -getMDO (L _ (ITmdo x)) = x -getQVARID (L _ (ITqvarid x)) = x -getQCONID (L _ (ITqconid x)) = x -getQVARSYM (L _ (ITqvarsym x)) = x -getQCONSYM (L _ (ITqconsym x)) = x -getIPDUPVARID (L _ (ITdupipvarid x)) = x -getLABELVARID (L _ (ITlabelvarid _ x)) = x -getCHAR (L _ (ITchar _ x)) = x -getSTRING (L _ (ITstring _ x)) = x -getINTEGER (L _ (ITinteger x)) = x -getRATIONAL (L _ (ITrational x)) = x -getPRIMCHAR (L _ (ITprimchar _ x)) = x -getPRIMSTRING (L _ (ITprimstring _ x)) = x -getPRIMINTEGER (L _ (ITprimint _ x)) = x -getPRIMWORD (L _ (ITprimword _ x)) = x -getPRIMFLOAT (L _ (ITprimfloat x)) = x -getPRIMDOUBLE (L _ (ITprimdouble x)) = x -getINLINE (L _ (ITinline_prag _ inl conl)) = (inl,conl) -getSPEC_INLINE (L _ (ITspec_inline_prag src True)) = (Inline src,FunLike) -getSPEC_INLINE (L _ (ITspec_inline_prag src False)) = (NoInline src,FunLike) +getVARID (L _ (ITvarid x)) = x +getCONID (L _ (ITconid x)) = x +getVARSYM (L _ (ITvarsym x)) = x +getCONSYM (L _ (ITconsym x)) = x +getDO (L _ (ITdo x)) = x +getMDO (L _ (ITmdo x)) = x +getQVARID (L _ (ITqvarid x)) = x +getQCONID (L _ (ITqconid x)) = x +getQVARSYM (L _ (ITqvarsym x)) = x +getQCONSYM (L _ (ITqconsym x)) = x +getIPDUPVARID (L _ (ITdupipvarid x)) = x +getLABELVARID (L _ (ITlabelvarid _ x)) = x +getCHAR (L _ (ITchar _ x)) = x +getSTRING (L _ (ITstring _ x)) = x +getINTEGER (L _ (ITinteger x)) = x +getRATIONAL (L _ (ITrational x)) = x +getPRIMCHAR (L _ (ITprimchar _ x)) = x +getPRIMSTRING (L _ (ITprimstring _ x)) = x +getPRIMINTEGER (L _ (ITprimint _ x)) = x +getPRIMWORD (L _ (ITprimword _ x)) = x +getPRIMINTEGER8 (L _ (ITprimint8 _ x)) = x +getPRIMINTEGER16 (L _ (ITprimint16 _ x)) = x +getPRIMINTEGER32 (L _ (ITprimint32 _ x)) = x +getPRIMINTEGER64 (L _ (ITprimint64 _ x)) = x +getPRIMWORD8 (L _ (ITprimword8 _ x)) = x +getPRIMWORD16 (L _ (ITprimword16 _ x)) = x +getPRIMWORD32 (L _ (ITprimword32 _ x)) = x +getPRIMWORD64 (L _ (ITprimword64 _ x)) = x +getPRIMFLOAT (L _ (ITprimfloat x)) = x +getPRIMDOUBLE (L _ (ITprimdouble x)) = x +getINLINE (L _ (ITinline_prag _ inl conl)) = (inl,conl) +getSPEC_INLINE (L _ (ITspec_inline_prag src True)) = (Inline src,FunLike) +getSPEC_INLINE (L _ (ITspec_inline_prag src False)) = (NoInline src,FunLike) getCOMPLETE_PRAGs (L _ (ITcomplete_prag x)) = x -getVOCURLY (L (RealSrcSpan l _) ITvocurly) = srcSpanStartCol l - -getINTEGERs (L _ (ITinteger (IL src _ _))) = src -getCHARs (L _ (ITchar src _)) = src -getSTRINGs (L _ (ITstring src _)) = src -getPRIMCHARs (L _ (ITprimchar src _)) = src -getPRIMSTRINGs (L _ (ITprimstring src _)) = src -getPRIMINTEGERs (L _ (ITprimint src _)) = src -getPRIMWORDs (L _ (ITprimword src _)) = src - -getLABELVARIDs (L _ (ITlabelvarid src _)) = src +getVOCURLY (L (RealSrcSpan l _) ITvocurly) = srcSpanStartCol l + +getINTEGERs (L _ (ITinteger (IL src _ _))) = src +getCHARs (L _ (ITchar src _)) = src +getSTRINGs (L _ (ITstring src _)) = src +getPRIMCHARs (L _ (ITprimchar src _)) = src +getPRIMSTRINGs (L _ (ITprimstring src _)) = src +getPRIMINTEGERs (L _ (ITprimint src _)) = src +getPRIMWORDs (L _ (ITprimword src _)) = src +getPRIMINTEGER8s (L _ (ITprimint8 src _)) = src +getPRIMINTEGER16s (L _ (ITprimint16 src _)) = src +getPRIMINTEGER32s (L _ (ITprimint32 src _)) = src +getPRIMINTEGER64s (L _ (ITprimint64 src _)) = src +getPRIMWORD8s (L _ (ITprimword8 src _)) = src +getPRIMWORD16s (L _ (ITprimword16 src _)) = src +getPRIMWORD32s (L _ (ITprimword32 src _)) = src +getPRIMWORD64s (L _ (ITprimword64 src _)) = src + +getLABELVARIDs (L _ (ITlabelvarid src _)) = src -- See Note [Pragma source text] in "GHC.Types.SourceText" for the following getINLINE_PRAGs (L _ (ITinline_prag _ inl _)) = inlineSpecSource inl diff --git a/compiler/GHC/Parser/Lexer.x b/compiler/GHC/Parser/Lexer.x index 380a30ca78..48a1a367c2 100644 --- a/compiler/GHC/Parser/Lexer.x +++ b/compiler/GHC/Parser/Lexer.x @@ -194,6 +194,10 @@ $docsym = [\| \^ \* \$] @exponent = @numspc [eE] [\-\+]? @decimal @bin_exponent = @numspc [pP] [\-\+]? @decimal +@binarylit = 0[bB] @numspc @binary +@octallit = 0[oO] @numspc @octal +@hexadecimallit = 0[xX] @numspc @hexadecimal + @qual = (@conid \.)+ @qvarid = @qual @varid @qconid = @qual @conid @@ -517,15 +521,15 @@ $unigraphic / { isSmartQuote } { smart_quote_error } -- <0> { -- Normal integral literals (:: Num a => a, from Integer) - @decimal { tok_num positive 0 0 decimal } - 0[bB] @numspc @binary / { ifExtension BinaryLiteralsBit } { tok_num positive 2 2 binary } - 0[oO] @numspc @octal { tok_num positive 2 2 octal } - 0[xX] @numspc @hexadecimal { tok_num positive 2 2 hexadecimal } - @negative @decimal / { negLitPred } { tok_num negative 1 1 decimal } - @negative 0[bB] @numspc @binary / { negLitPred `alexAndPred` - ifExtension BinaryLiteralsBit } { tok_num negative 3 3 binary } - @negative 0[oO] @numspc @octal / { negLitPred } { tok_num negative 3 3 octal } - @negative 0[xX] @numspc @hexadecimal / { negLitPred } { tok_num negative 3 3 hexadecimal } + @decimal { tok_num positive 0 0 decimal } + @binarylit / { ifExtension BinaryLiteralsBit } { tok_num positive 2 2 binary } + @octallit { tok_num positive 2 2 octal } + @hexadecimallit { tok_num positive 2 2 hexadecimal } + @negative @decimal / { negLitPred } { tok_num negative 1 1 decimal } + @negative @binarylit / { negLitPred `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_num negative 3 3 binary } + @negative @octallit / { negLitPred } { tok_num negative 3 3 octal } + @negative @hexadecimallit / { negLitPred } { tok_num negative 3 3 hexadecimal } -- Normal rational literals (:: Fractional a => a, from Rational) @floating_point { tok_frac 0 tok_float } @@ -540,31 +544,116 @@ $unigraphic / { isSmartQuote } { smart_quote_error } -- Unboxed ints (:: Int#) and words (:: Word#) -- It's simpler (and faster?) to give separate cases to the negatives, -- especially considering octal/hexadecimal prefixes. - @decimal \# / { ifExtension MagicHashBit } { tok_primint positive 0 1 decimal } - 0[bB] @numspc @binary \# / { ifExtension MagicHashBit `alexAndPred` - ifExtension BinaryLiteralsBit } { tok_primint positive 2 3 binary } - 0[oO] @numspc @octal \# / { ifExtension MagicHashBit } { tok_primint positive 2 3 octal } - 0[xX] @numspc @hexadecimal \# / { ifExtension MagicHashBit } { tok_primint positive 2 3 hexadecimal } - @negative @decimal \# / { negHashLitPred } { tok_primint negative 1 2 decimal } - @negative 0[bB] @numspc @binary \# / { negHashLitPred `alexAndPred` - ifExtension BinaryLiteralsBit } { tok_primint negative 3 4 binary } - @negative 0[oO] @numspc @octal \# / { negHashLitPred } { tok_primint negative 3 4 octal } - @negative 0[xX] @numspc @hexadecimal \# - / { negHashLitPred } { tok_primint negative 3 4 hexadecimal } - - @decimal \# \# / { ifExtension MagicHashBit } { tok_primword 0 2 decimal } - 0[bB] @numspc @binary \# \# / { ifExtension MagicHashBit `alexAndPred` - ifExtension BinaryLiteralsBit } { tok_primword 2 4 binary } - 0[oO] @numspc @octal \# \# / { ifExtension MagicHashBit } { tok_primword 2 4 octal } - 0[xX] @numspc @hexadecimal \# \# / { ifExtension MagicHashBit } { tok_primword 2 4 hexadecimal } + @decimal \# / { ifExtension MagicHashBit } { tok_primint positive 0 1 decimal } + @binarylit \# / { ifExtension MagicHashBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint positive 2 3 binary } + @octallit \# / { ifExtension MagicHashBit } { tok_primint positive 2 3 octal } + @hexadecimallit \# / { ifExtension MagicHashBit } { tok_primint positive 2 3 hexadecimal } + @negative @decimal \# / { negHashLitPred MagicHashBit } { tok_primint negative 1 2 decimal } + @negative @binarylit \# / { negHashLitPred MagicHashBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint negative 3 4 binary } + @negative @octallit \# / { negHashLitPred MagicHashBit } { tok_primint negative 3 4 octal } + @negative @hexadecimallit \# / { negHashLitPred MagicHashBit } { tok_primint negative 3 4 hexadecimal } + + @decimal \# \# / { ifExtension MagicHashBit } { tok_primword 0 2 decimal } + @binarylit \# \# / { ifExtension MagicHashBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primword 2 4 binary } + @octallit \# \# / { ifExtension MagicHashBit } { tok_primword 2 4 octal } + @hexadecimallit \# \# / { ifExtension MagicHashBit } { tok_primword 2 4 hexadecimal } -- Unboxed floats and doubles (:: Float#, :: Double#) -- prim_{float,double} work with signed literals @floating_point \# / { ifExtension MagicHashBit } { tok_frac 1 tok_primfloat } @floating_point \# \# / { ifExtension MagicHashBit } { tok_frac 2 tok_primdouble } - @negative @floating_point \# / { negHashLitPred } { tok_frac 1 tok_primfloat } - @negative @floating_point \# \# / { negHashLitPred } { tok_frac 2 tok_primdouble } + @negative @floating_point \# / { negHashLitPred MagicHashBit } { tok_frac 1 tok_primfloat } + @negative @floating_point \# \# / { negHashLitPred MagicHashBit } { tok_frac 2 tok_primdouble } + + @decimal \#"Int8" / { ifExtension ExtendedLiteralsBit } { tok_primint8 positive 0 decimal } + @binarylit \#"Int8" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint8 positive 2 binary } + @octallit \#"Int8" / { ifExtension ExtendedLiteralsBit } { tok_primint8 positive 2 octal } + @hexadecimallit \#"Int8" / { ifExtension ExtendedLiteralsBit } { tok_primint8 positive 2 hexadecimal } + @negative @decimal \#"Int8" / { negHashLitPred ExtendedLiteralsBit } { tok_primint8 negative 1 decimal } + @negative @binarylit \#"Int8" / { negHashLitPred ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint8 negative 3 binary } + @negative @octallit \#"Int8" / { negHashLitPred ExtendedLiteralsBit } { tok_primint8 negative 3 octal } + @negative @hexadecimallit \#"Int8" / { negHashLitPred ExtendedLiteralsBit } { tok_primint8 negative 3 hexadecimal } + + @decimal \#"Int16" / { ifExtension ExtendedLiteralsBit } { tok_primint16 positive 0 decimal } + @binarylit \#"Int16" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint16 positive 2 binary } + @octallit \#"Int16" / { ifExtension ExtendedLiteralsBit } { tok_primint16 positive 2 octal } + @hexadecimallit \#"Int16" / { ifExtension ExtendedLiteralsBit } { tok_primint16 positive 2 hexadecimal } + @negative @decimal \#"Int16" / { negHashLitPred ExtendedLiteralsBit} { tok_primint16 negative 1 decimal } + @negative @binarylit \#"Int16" / { negHashLitPred ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint16 negative 3 binary } + @negative @octallit \#"Int16" / { negHashLitPred ExtendedLiteralsBit} { tok_primint16 negative 3 octal } + @negative @hexadecimallit \#"Int16" / { negHashLitPred ExtendedLiteralsBit} { tok_primint16 negative 3 hexadecimal } + + @decimal \#"Int32" / { ifExtension ExtendedLiteralsBit } { tok_primint32 positive 0 decimal } + @binarylit \#"Int32" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint32 positive 2 binary } + @octallit \#"Int32" / { ifExtension ExtendedLiteralsBit } { tok_primint32 positive 2 octal } + @hexadecimallit \#"Int32" / { ifExtension ExtendedLiteralsBit } { tok_primint32 positive 2 hexadecimal } + @negative @decimal \#"Int32" / { negHashLitPred ExtendedLiteralsBit } { tok_primint32 negative 1 decimal } + @negative @binarylit \#"Int32" / { negHashLitPred ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint32 negative 3 binary } + @negative @octallit \#"Int32" / { negHashLitPred ExtendedLiteralsBit} { tok_primint32 negative 3 octal } + @negative @hexadecimallit \#"Int32" / { negHashLitPred ExtendedLiteralsBit} { tok_primint32 negative 3 hexadecimal } + + @decimal \#"Int64" / { ifExtension ExtendedLiteralsBit } { tok_primint64 positive 0 decimal } + @binarylit \#"Int64" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint64 positive 2 binary } + @octallit \#"Int64" / { ifExtension ExtendedLiteralsBit } { tok_primint64 positive 2 octal } + @hexadecimallit \#"Int64" / { ifExtension ExtendedLiteralsBit } { tok_primint64 positive 2 hexadecimal } + @negative @decimal \#"Int64" / { negHashLitPred ExtendedLiteralsBit } { tok_primint64 negative 1 decimal } + @negative @binarylit \#"Int64" / { negHashLitPred ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint64 negative 3 binary } + @negative @octallit \#"Int64" / { negHashLitPred ExtendedLiteralsBit } { tok_primint64 negative 3 octal } + @negative @hexadecimallit \#"Int64" / { negHashLitPred ExtendedLiteralsBit } { tok_primint64 negative 3 hexadecimal } + + @decimal \#"Int" / { ifExtension ExtendedLiteralsBit } { tok_primint positive 0 4 decimal } + @binarylit \#"Int" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint positive 2 6 binary } + @octallit \#"Int" / { ifExtension ExtendedLiteralsBit } { tok_primint positive 2 6 octal } + @hexadecimallit \#"Int" / { ifExtension ExtendedLiteralsBit } { tok_primint positive 2 6 hexadecimal } + @negative @decimal \#"Int" / { negHashLitPred ExtendedLiteralsBit } { tok_primint negative 1 5 decimal } + @negative @binarylit \#"Int" / { negHashLitPred ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint negative 3 7 binary } + @negative @octallit \#"Int" / { negHashLitPred ExtendedLiteralsBit } { tok_primint negative 3 7 octal } + @negative @hexadecimallit \#"Int" / { negHashLitPred ExtendedLiteralsBit } { tok_primint negative 3 7 hexadecimal } + + @decimal \#"Word8" / { ifExtension ExtendedLiteralsBit } { tok_primword8 0 decimal } + @binarylit \#"Word8" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primword8 2 binary } + @octallit \#"Word8" / { ifExtension ExtendedLiteralsBit } { tok_primword8 2 octal } + @hexadecimallit \#"Word8" / { ifExtension ExtendedLiteralsBit } { tok_primword8 2 hexadecimal } + + @decimal \#"Word16" / { ifExtension ExtendedLiteralsBit } { tok_primword16 0 decimal } + @binarylit \#"Word16" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primword16 2 binary } + @octallit \#"Word16" / { ifExtension ExtendedLiteralsBit } { tok_primword16 2 octal } + @hexadecimallit \#"Word16" / { ifExtension ExtendedLiteralsBit } { tok_primword16 2 hexadecimal } + + @decimal \#"Word32" / { ifExtension ExtendedLiteralsBit } { tok_primword32 0 decimal } + @binarylit \#"Word32" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primword32 2 binary } + @octallit \#"Word32" / { ifExtension ExtendedLiteralsBit } { tok_primword32 2 octal } + @hexadecimallit \#"Word32" / { ifExtension ExtendedLiteralsBit } { tok_primword32 2 hexadecimal } + + @decimal \#"Word64" / { ifExtension ExtendedLiteralsBit } { tok_primword64 0 decimal } + @binarylit \#"Word64" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primword64 2 binary } + @octallit \#"Word64" / { ifExtension ExtendedLiteralsBit } { tok_primword64 2 octal } + @hexadecimallit \#"Word64" / { ifExtension ExtendedLiteralsBit } { tok_primword64 2 hexadecimal } + + @decimal \#"Word" / { ifExtension ExtendedLiteralsBit } { tok_primword 0 5 decimal } + @binarylit \#"Word" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primword 2 7 binary } + @octallit \#"Word" / { ifExtension ExtendedLiteralsBit } { tok_primword 2 7 octal } + @hexadecimallit \#"Word" / { ifExtension ExtendedLiteralsBit } { tok_primword 2 7 hexadecimal } + } -- Strings and chars are lexed by hand-written code. The reason is @@ -866,6 +955,14 @@ data Token | ITprimstring SourceText ByteString -- Note [Literal source text] in "GHC.Types.SourceText" | ITprimint SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" | ITprimword SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimint8 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimint16 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimint32 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimint64 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimword8 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimword16 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimword32 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimword64 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" | ITprimfloat FractionalLit | ITprimdouble FractionalLit @@ -1281,10 +1378,10 @@ negLitPred = alexNotPred precededByClosingToken -- Check if we should parse an unboxed negative literal (e.g. -123#) as a single token. -negHashLitPred :: AlexAccPred ExtsBitmap -negHashLitPred = prefix_minus `alexAndPred` magic_hash +negHashLitPred :: ExtBits -> AlexAccPred ExtsBitmap +negHashLitPred ext = prefix_minus `alexAndPred` magic_hash where - magic_hash = ifExtension MagicHashBit + magic_hash = ifExtension ext -- Either MagicHashBit or ExtendedLiteralsBit prefix_minus = -- Note [prefix_minus in negLitPred and negHashLitPred] alexNotPred precededByClosingToken @@ -1829,6 +1926,40 @@ binary = (2,octDecDigit) octal = (8,octDecDigit) hexadecimal = (16,hexDigit) +-- | Helper for defining @IntX@ primitive literal parsers (specifically for +-- the ExtendedLiterals extension, such as @123#Int8@). +tok_primintX :: (SourceText -> Integer -> Token) + -> Int + -> (Integer -> Integer) + -> Int + -> (Integer, (Char->Int)) -> Action +tok_primintX itint addlen transint transbuf = + tok_integral itint transint transbuf (transbuf+addlen) + +tok_primint8, tok_primint16, tok_primint32, tok_primint64 + :: (Integer -> Integer) + -> Int -> (Integer, (Char->Int)) -> Action +tok_primint8 = tok_primintX ITprimint8 5 +tok_primint16 = tok_primintX ITprimint16 6 +tok_primint32 = tok_primintX ITprimint32 6 +tok_primint64 = tok_primintX ITprimint64 6 + +-- | Helper for defining @WordX@ primitive literal parsers (specifically for +-- the ExtendedLiterals extension, such as @234#Word8@). +tok_primwordX :: (SourceText -> Integer -> Token) + -> Int + -> Int + -> (Integer, (Char->Int)) -> Action +tok_primwordX itint addlen transbuf = + tok_integral itint positive transbuf (transbuf+addlen) + +tok_primword8, tok_primword16, tok_primword32, tok_primword64 + :: Int -> (Integer, (Char->Int)) -> Action +tok_primword8 = tok_primwordX ITprimword8 6 +tok_primword16 = tok_primwordX ITprimword16 7 +tok_primword32 = tok_primwordX ITprimword32 7 +tok_primword64 = tok_primwordX ITprimword64 7 + -- readSignificandExponentPair can understand negative rationals, exponents, everything. tok_frac :: Int -> (String -> Token) -> Action tok_frac drop f span buf len _buf2 = do @@ -2903,6 +3034,7 @@ data ExtBits | NoLexicalNegationBit -- See Note [Why not LexicalNegationBit] | OverloadedRecordDotBit | OverloadedRecordUpdateBit + | ExtendedLiteralsBit -- Flags that are updated once parsing starts | InRulePragBit @@ -2982,6 +3114,7 @@ mkParserOpts extensionFlags diag_opts supported .|. NoLexicalNegationBit `xoptNotBit` LangExt.LexicalNegation -- See Note [Why not LexicalNegationBit] .|. OverloadedRecordDotBit `xoptBit` LangExt.OverloadedRecordDot .|. OverloadedRecordUpdateBit `xoptBit` LangExt.OverloadedRecordUpdate -- Enable testing via 'getBit OverloadedRecordUpdateBit' in the parser (RecordDotSyntax parsing uses that information). + .|. ExtendedLiteralsBit `xoptBit` LangExt.ExtendedLiterals optBits = HaddockBit `setBitIf` isHaddock .|. RawTokenStreamBit `setBitIf` rawTokStream diff --git a/compiler/Language/Haskell/Syntax/Extension.hs b/compiler/Language/Haskell/Syntax/Extension.hs index b184f1f46b..0072e60ab6 100644 --- a/compiler/Language/Haskell/Syntax/Extension.hs +++ b/compiler/Language/Haskell/Syntax/Extension.hs @@ -568,7 +568,13 @@ type family XHsStringPrim x type family XHsInt x type family XHsIntPrim x type family XHsWordPrim x +type family XHsInt8Prim x +type family XHsInt16Prim x +type family XHsInt32Prim x type family XHsInt64Prim x +type family XHsWord8Prim x +type family XHsWord16Prim x +type family XHsWord32Prim x type family XHsWord64Prim x type family XHsInteger x type family XHsRat x diff --git a/compiler/Language/Haskell/Syntax/Lit.hs b/compiler/Language/Haskell/Syntax/Lit.hs index 564d5660dd..f0b9d72fad 100644 --- a/compiler/Language/Haskell/Syntax/Lit.hs +++ b/compiler/Language/Haskell/Syntax/Lit.hs @@ -63,8 +63,20 @@ data HsLit x -- ^ literal @Int#@ | HsWordPrim (XHsWordPrim x) {- SourceText -} Integer -- ^ literal @Word#@ + | HsInt8Prim (XHsInt8Prim x) {- SourceText -} Integer + -- ^ literal @Int8#@ + | HsInt16Prim (XHsInt16Prim x) {- SourceText -} Integer + -- ^ literal @Int16#@ + | HsInt32Prim (XHsInt32Prim x) {- SourceText -} Integer + -- ^ literal @Int32#@ | HsInt64Prim (XHsInt64Prim x) {- SourceText -} Integer -- ^ literal @Int64#@ + | HsWord8Prim (XHsWord8Prim x) {- SourceText -} Integer + -- ^ literal @Word8#@ + | HsWord16Prim (XHsWord16Prim x) {- SourceText -} Integer + -- ^ literal @Word16#@ + | HsWord32Prim (XHsWord32Prim x) {- SourceText -} Integer + -- ^ literal @Word32#@ | HsWord64Prim (XHsWord64Prim x) {- SourceText -} Integer -- ^ literal @Word64#@ | HsInteger (XHsInteger x) {- SourceText -} Integer Type @@ -149,4 +161,3 @@ instance Ord OverLitVal where compare (HsIsString _ s1) (HsIsString _ s2) = s1 `lexicalCompareFS` s2 compare (HsIsString _ _) (HsIntegral _) = GT compare (HsIsString _ _) (HsFractional _) = GT - diff --git a/docs/users_guide/9.8.1-notes.rst b/docs/users_guide/9.8.1-notes.rst index 9f2d51d329..e7e9acdf75 100644 --- a/docs/users_guide/9.8.1-notes.rst +++ b/docs/users_guide/9.8.1-notes.rst @@ -6,6 +6,10 @@ Version 9.8.1 Language ~~~~~~~~ +- There is a new extension :extension:`ExtendedLiterals`, which enables + sized primitive literals, e.g. ``123#Int8`` is a literal of type ``Int8#``. + See the GHC proposal `#451 `_. + Compiler ~~~~~~~~ diff --git a/docs/users_guide/exts/extended_literals.rst b/docs/users_guide/exts/extended_literals.rst new file mode 100644 index 0000000000..ac61f2d410 --- /dev/null +++ b/docs/users_guide/exts/extended_literals.rst @@ -0,0 +1,47 @@ +.. _extended-literals: + +Sized primitive literal syntax +------------------------------ + +.. extension:: ExtendedLiterals + :shortdesc: Enable numeric literal postfix syntax for unboxed integers. + + :since: 9.8.1 + + Allows defining unboxed numeric primitive values through ``#Type`` suffixes + on numeric literals e.g. ``0xFF#Word8 :: Word8#``. + +The :extension:`MagicHash` extension enables some new literals, including ``3# +:: Int#``, ``3## :: Word#``. This does not extend to all unboxed values. For +example, there is no literal syntax for ``Word8#``: you must write something +such as ``wordToWord8 (3## :: Word#) :: Word8#``. + +:extension:`ExtendedLiterals` enables further syntax for defining primitive +numeric literals. Suffix any Haskell integer lexeme with a hash sign ``#`` +followed by a primitive numeric type (without its hash suffix) to obtain a value +of that type. For example, ``0xFF#Word8 :: Word8#``. There must be no spaces +between the parts of the literal. + +The primitive numeric types allowed are: + +- ``Int8#`` +- ``Int16#`` +- ``Int32#`` +- ``Int64#`` +- ``Int#`` +- ``Word8#`` +- ``Word16#`` +- ``Word32#`` +- ``Word64#`` +- ``Word#`` + +All types permit any nonnegative Haskell integer lexeme, e.g. ``70``, ``0x2A``, +``0o1276``, ``0b1010`` (with :extension:`BinaryLiterals`). The signed ``Int`` +types also permit negative integer lexemes. Defining a literal with a value that +can't fit in its requested type will emit an overflow warning by default, the +same as boxed numeric literals. + +As with :extension:`MagicHash`, this extension does not bring anything into +scope, nor change any semantics. The syntax only applies to numeric literals. +You may want to import ``GHC.Exts`` (see :ref:`primitives`) to refer to the +types of the literals you define. diff --git a/docs/users_guide/exts/literals.rst b/docs/users_guide/exts/literals.rst index fbb613333f..6061bdfec7 100644 --- a/docs/users_guide/exts/literals.rst +++ b/docs/users_guide/exts/literals.rst @@ -10,6 +10,7 @@ Literals binary_literals hex_float_literals num_decimals + extended_literals numeric_underscores overloaded_strings overloaded_labels diff --git a/docs/users_guide/exts/primitives.rst b/docs/users_guide/exts/primitives.rst index 9caab6b146..ef8cb32523 100644 --- a/docs/users_guide/exts/primitives.rst +++ b/docs/users_guide/exts/primitives.rst @@ -19,6 +19,9 @@ your program, you must first import ``GHC.Exts`` to bring them into scope. Many of them have names ending in ``#``, and to mention such names you need the :extension:`MagicHash` extension. +To enable defining literals for other primitive data types, see the +:extension:`ExtendedLiterals` extension. + The primops make extensive use of `unboxed types <#glasgow-unboxed>`__ and `unboxed tuples <#unboxed-tuples>`__, which we briefly summarise here. diff --git a/docs/users_guide/exts/stolen_syntax.rst b/docs/users_guide/exts/stolen_syntax.rst index 746daebd7c..39747bc745 100644 --- a/docs/users_guide/exts/stolen_syntax.rst +++ b/docs/users_guide/exts/stolen_syntax.rst @@ -80,6 +80,9 @@ The following syntax is stolen: ⟨varid⟩, ``#``\ ⟨char⟩, ``#``, ⟨string⟩, ``#``, ⟨integer⟩, ``#``, ⟨float⟩, ``#``, ⟨float⟩, ``##`` Stolen by: :extension:`MagicHash` +⟨integer⟩, ``#(Int|Word)(8|16|32|64)?`` + Stolen by: :extension:`ExtendedLiterals` + ``(#``, ``#)`` Stolen by: :extension:`UnboxedTuples` diff --git a/libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs b/libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs index 532c290ba8..e3bd35cbbb 100644 --- a/libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs +++ b/libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs @@ -152,6 +152,7 @@ data Extension | OverloadedRecordDot | OverloadedRecordUpdate | TypeAbstractions + | ExtendedLiterals deriving (Eq, Enum, Show, Generic, Bounded) -- 'Ord' and 'Bounded' are provided for GHC API users (see discussions -- in https://gitlab.haskell.org/ghc/ghc/merge_requests/2707 and diff --git a/testsuite/tests/driver/T4437.hs b/testsuite/tests/driver/T4437.hs index 3c07aa5679..142c348fca 100644 --- a/testsuite/tests/driver/T4437.hs +++ b/testsuite/tests/driver/T4437.hs @@ -37,7 +37,8 @@ check title expected got -- See Note [Adding a language extension] in compiler/GHC/Driver/Session.hs. expectedGhcOnlyExtensions :: [String] expectedGhcOnlyExtensions = - [ "TypeAbstractions" + [ "TypeAbstractions", + "ExtendedLiterals" ] expectedCabalOnlyExtensions :: [String] diff --git a/testsuite/tests/extendedliterals/all.T b/testsuite/tests/extendedliterals/all.T new file mode 100644 index 0000000000..a1a922adc5 --- /dev/null +++ b/testsuite/tests/extendedliterals/all.T @@ -0,0 +1,3 @@ +test('extendedliterals01', normal, compile, ['']) +test('extendedliterals02', normal, compile, ['']) +test('extendedliterals03', [extra_ways(['ghci']), js_skip], compile_and_run, ['']) diff --git a/testsuite/tests/extendedliterals/extendedliterals01.hs b/testsuite/tests/extendedliterals/extendedliterals01.hs new file mode 100644 index 0000000000..d464f9822b --- /dev/null +++ b/testsuite/tests/extendedliterals/extendedliterals01.hs @@ -0,0 +1,41 @@ +{-# LANGUAGE MagicHash, ExtendedLiterals #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE UnboxedSums, UnboxedTuples #-} + +-- needed on 32bit +{-# OPTIONS_GHC -fno-warn-overflowed-literals #-} + +module Ex where + +import GHC.Exts +import GHC.Word +import GHC.Int + +-- Precise 'Int8#'/'Int8' range tests +exI8g1, exI8g2, exI8g3 :: Int8 +exI8g1 = I8# 0x00#Int8 +exI8g2 = I8# 0x7F#Int8 +exI8g3 = I8# -0x80#Int8 + +-- Showcase various syntax for equivalent 'Int' terms +exIg1, exIg2, exIg3 :: Int +exIg1 = 0x7FFFFFFFFFFFFFFF +exIg2 = I# 0x7FFFFFFFFFFFFFFF# +exIg3 = I# 0x7FFFFFFFFFFFFFFF#Int + +-- Motivating example: unboxed 'Word8#' parsing +data CEnum = Cons00 | Cons01 | ConsFF deriving Show +parseCEnum :: Word8# -> (# (##) | CEnum #) +parseCEnum = \case 0x00#Word8 -> (# | Cons00 #) + 0x01#Word8 -> (# | Cons01 #) + 0xFF#Word8 -> (# | ConsFF #) + _ -> (# (##) | #) + +w8ToBool# :: Word8# -> Int# +w8ToBool# = \case 0#Word8 -> 0# + _ -> 1# + +i8IsPole# :: Int8# -> Int# +i8IsPole# = \case 0x7F#Int8 -> 1# + -0x80#Int8 -> 1# + _ -> 0# diff --git a/testsuite/tests/extendedliterals/extendedliterals02.hs b/testsuite/tests/extendedliterals/extendedliterals02.hs new file mode 100644 index 0000000000..0b5a9391af --- /dev/null +++ b/testsuite/tests/extendedliterals/extendedliterals02.hs @@ -0,0 +1,15 @@ +{-# LANGUAGE MagicHash, ExtendedLiterals #-} +{-# OPTIONS_GHC -fno-warn-overflowed-literals #-} + +module Ex where + +--import GHC.Exts +import GHC.Int + +-- Overflowed 'Int8#' literals +exI8b1, exI8b2, exI8b3, exI8b4, exI8b5 :: Int8 +exI8b1 = I8# 0x80#Int8 +exI8b2 = I8# -0x81#Int8 +exI8b3 = I8# 0xFF#Int8 +exI8b4 = I8# -0xFF#Int8 +exI8b5 = I8# 0xFFFFFFFFFFFFFFFF#Int8 diff --git a/testsuite/tests/extendedliterals/extendedliterals03.hs b/testsuite/tests/extendedliterals/extendedliterals03.hs new file mode 100644 index 0000000000..a3a4b0b8f5 --- /dev/null +++ b/testsuite/tests/extendedliterals/extendedliterals03.hs @@ -0,0 +1,260 @@ +{-# LANGUAGE MagicHash, ExtendedLiterals #-} +import GHC.Word +import GHC.Int +import GHC.Exts + +main = do + print (W8# (fibw8 6#Word8), + W16# (fibw16 6#Word16), + W32# (fibw32 6#Word32), + W64# (fibw64 6#Word64)) + print (I8# (fibi8 6#Int8), + I16# (fibi16 6#Int16), + I32# (fibi32 6#Int32), + I64# (fibi64 6#Int64)) + + print (W64# 0xFFFFFFFFFFFFFFFF#Word64) + print (I64# 0x7FFFFFFFFFFFFFFF#Int64) + print (I64# -0x8000000000000000#Int64) + print (W64# (x () `timesWord64#` y ())) + print (case x () `timesWord64#` y () of + 276447232#Word64 -> False + 276447233#Word64 -> False + 276447234#Word64 -> False + 276047234#Word64 -> False + 5000000004#Word64 -> False + 100000000000000#Word64 -> True + _ -> False) + print (case x () `timesWord64#` y () of + 276447232#Word64 -> True + _ -> False) + + print [ W8# (branchi8 0#Int8) + , W8# (branchi8 1#Int8) + , W8# (branchi8 -1#Int8) + , W8# (branchi8 126#Int8) + , W8# (branchi8 127#Int8) + , W8# (branchi8 -127#Int8) + , W8# (branchi8 -128#Int8) + , W8# (branchi8 2#Int8) + ] + + print [ W16# (branchi16 0#Int16) + , W16# (branchi16 1#Int16) + , W16# (branchi16 (-1#Int16)) + , W16# (branchi16 32767#Int16) + , W16# (branchi16 32766#Int16) + , W16# (branchi16 (-32768#Int16)) + , W16# (branchi16 (-32767#Int16)) + , W16# (branchi16 2#Int16) + ] + + print [ W32# (branchi32 0#Int32) + , W32# (branchi32 1#Int32) + , W32# (branchi32 (-1#Int32)) + , W32# (branchi32 2147483646#Int32) + , W32# (branchi32 2147483647#Int32) + , W32# (branchi32 (-2147483648#Int32)) + , W32# (branchi32 (-2147483647#Int32)) + , W32# (branchi32 2#Int32) + ] + + print [ W64# (branchi64 0#Int64) + , W64# (branchi64 1#Int64) + , W64# (branchi64 (-1#Int64)) + , W64# (branchi64 2147483647#Int64) + , W64# (branchi64 2147483648#Int64) + , W64# (branchi64 4294967297#Int64) + , W64# (branchi64 (-2147483648#Int64)) + , W64# (branchi64 (-2147483649#Int64)) + , W64# (branchi64 (-4294967295#Int64)) + , W64# (branchi64 9223372036854775807#Int64) + , W64# (branchi64 9223372036854775806#Int64) + , W64# (branchi64 (-9223372036854775808#Int64)) + , W64# (branchi64 (-9223372036854775807#Int64)) + , W64# (branchi64 2#Int64) + ] + + print [ I8# (branchw8 0#Word8) + , I8# (branchw8 1#Word8) + , I8# (branchw8 254#Word8) + , I8# (branchw8 255#Word8) + , I8# (branchw8 2#Word8) + ] + + print [ I16# (branchw16 0#Word16) + , I16# (branchw16 1#Word16) + , I16# (branchw16 255#Word16) + , I16# (branchw16 256#Word16) + , I16# (branchw16 65534#Word16) + , I16# (branchw16 65535#Word16) + , I16# (branchw16 2#Word16) + ] + + print [ I32# (branchw32 0#Word32) + , I32# (branchw32 1#Word32) + , I32# (branchw32 65534#Word32) + , I32# (branchw32 65535#Word32) + , I32# (branchw32 65536#Word32) + , I32# (branchw32 4294967295#Word32) + , I32# (branchw32 4294967294#Word32) + , I32# (branchw32 4294967293#Word32) + , I32# (branchw32 2#Word32) + ] + + print [ I64# (branchw64 0#Word64) + , I64# (branchw64 1#Word64) + , I64# (branchw64 65536#Word64) + , I64# (branchw64 4294967295#Word64) + , I64# (branchw64 4294967296#Word64) + , I64# (branchw64 4294967297#Word64) + , I64# (branchw64 18446744073709551615#Word64) + , I64# (branchw64 18446744073709551614#Word64) + , I64# (branchw64 18446744073709551613#Word64) + , I64# (branchw64 2#Word64) + ] + +fibw8 :: Word8# -> Word8# +fibw8 0#Word8 = 0#Word8 +fibw8 1#Word8 = 1#Word8 +fibw8 n = fibw8 (n `subWord8#` 1#Word8) `plusWord8#` fibw8 (n `subWord8#` 2#Word8) + +fibw16 :: Word16# -> Word16# +fibw16 0#Word16 = 0#Word16 +fibw16 1#Word16 = 1#Word16 +fibw16 n = fibw16 (n `subWord16#` 1#Word16) `plusWord16#` fibw16 (n `subWord16#` 2#Word16) + +fibw32 :: Word32# -> Word32# +fibw32 0#Word32 = 0#Word32 +fibw32 1#Word32 = 1#Word32 +fibw32 n = fibw32 (n `subWord32#` 1#Word32) `plusWord32#` fibw32 (n `subWord32#` 2#Word32) + +fibw64 :: Word64# -> Word64# +fibw64 0#Word64 = 0#Word64 +fibw64 1#Word64 = 1#Word64 +fibw64 n = fibw64 (n `subWord64#` 1#Word64) `plusWord64#` fibw64 (n `subWord64#` 2#Word64) + +-- + +fibi8 :: Int8# -> Int8# +fibi8 0#Int8 = 0#Int8 +fibi8 1#Int8 = 1#Int8 +fibi8 n = fibi8 (n `subInt8#` 1#Int8) `plusInt8#` fibi8 (n `subInt8#` 2#Int8) + +fibi16 :: Int16# -> Int16# +fibi16 0#Int16 = 0#Int16 +fibi16 1#Int16 = 1#Int16 +fibi16 n = fibi16 (n `subInt16#` 1#Int16) `plusInt16#` fibi16 (n `subInt16#` 2#Int16) + +fibi32 :: Int32# -> Int32# +fibi32 0#Int32 = 0#Int32 +fibi32 1#Int32 = 1#Int32 +fibi32 n = fibi32 (n `subInt32#` 1#Int32) `plusInt32#` fibi32 (n `subInt32#` 2#Int32) + +fibi64 :: Int64# -> Int64# +fibi64 0#Int64 = 0#Int64 +fibi64 1#Int64 = 1#Int64 +fibi64 n = fibi64 (n `subInt64#` 1#Int64) `plusInt64#` fibi64 (n `subInt64#` 2#Int64) + +-- + +branchi8 :: Int8# -> Word8# +branchi8 0#Int8 = 1#Word8 +branchi8 1#Int8 = 2#Word8 +branchi8 (-1#Int8) = 3#Word8 +branchi8 126#Int8 = 4#Word8 +branchi8 127#Int8 = 5#Word8 +branchi8 (-127#Int8) = 6#Word8 +branchi8 (-128#Int8) = 7#Word8 +branchi8 _ = 0#Word8 +{-# NOINLINE branchi8 #-} + +branchi16 :: Int16# -> Word16# +branchi16 0#Int16 = 1#Word16 +branchi16 1#Int16 = 2#Word16 +branchi16 (-1#Int16) = 3#Word16 +branchi16 32767#Int16 = 255#Word16 +branchi16 32766#Int16 = 256#Word16 +branchi16 (-32768#Int16) = 65534#Word16 +branchi16 (-32767#Int16) = 65535#Word16 +branchi16 _ = 0#Word16 +{-# NOINLINE branchi16 #-} + +branchi32 :: Int32# -> Word32# +branchi32 0#Int32 = 1#Word32 +branchi32 1#Int32 = 2#Word32 +branchi32 (-1#Int32) = 3#Word32 +branchi32 2147483646#Int32 = 65535#Word32 +branchi32 2147483647#Int32 = 65536#Word32 +branchi32 (-2147483648#Int32) = 4294967294#Word32 +branchi32 (-2147483647#Int32) = 4294967295#Word32 +branchi32 _ = 0#Word32 +{-# NOINLINE branchi32 #-} + +branchi64 :: Int64# -> Word64# +branchi64 0#Int64 = 18446744073709551615#Word64 +branchi64 1#Int64 = 2147483648#Word64 +branchi64 (-1#Int64) = 4294967296#Word64 +branchi64 2147483647#Int64 = 4294967297#Word64 +branchi64 2147483648#Int64 = 9#Word64 +branchi64 4294967297#Int64 = 1#Word64 +branchi64 (-2147483648#Int64) = 18446744073709551614#Word64 +branchi64 (-2147483649#Int64) = 3#Word64 +branchi64 (-4294967295#Int64) = 4#Word64 +branchi64 9223372036854775807#Int64 = 5#Word64 +branchi64 9223372036854775806#Int64 = 6#Word64 +branchi64 (-9223372036854775808#Int64) = 7#Word64 +branchi64 (-9223372036854775807#Int64) = 8#Word64 +branchi64 _ = 0#Word64 +{-# NOINLINE branchi64 #-} + +branchw8 :: Word8# -> Int8# +branchw8 0#Word8 = 1#Int8 +branchw8 1#Word8 = (-1#Int8) +branchw8 254#Word8 = 2#Int8 +branchw8 255#Word8 = (-2#Int8) +branchw8 _ = 0#Int8 +{-# NOINLINE branchw8 #-} + +branchw16 :: Word16# -> Int16# +branchw16 0#Word16 = 256#Int16 +branchw16 1#Word16 = (-256#Int16) +branchw16 255#Word16 = 32767#Int16 +branchw16 256#Word16 = (-32768#Int16) +branchw16 65534#Word16 = (-1#Int16) +branchw16 65535#Word16 = 1#Int16 +branchw16 _ = 0#Int16 +{-# NOINLINE branchw16 #-} + +branchw32 :: Word32# -> Int32# +branchw32 0#Word32 = 2147483647#Int32 +branchw32 1#Word32 = (-2147483648#Int32) +branchw32 65534#Word32 = 65535#Int32 +branchw32 65535#Word32 = 65536#Int32 +branchw32 65536#Word32 = (-1#Int32) +branchw32 4294967295#Word32 = (-65536#Int32) +branchw32 4294967294#Word32 = (-65537#Int32) +branchw32 4294967293#Word32 = 1#Int32 +branchw32 _ = 0#Int32 +{-# NOINLINE branchw32 #-} + +branchw64 :: Word64# -> Int64# +branchw64 0#Word64 = 9223372036854775807#Int64 +branchw64 1#Word64 = 2147483648#Int64 +branchw64 65536#Word64 = 4294967296#Int64 +branchw64 4294967295#Word64 = 4294967297#Int64 +branchw64 4294967296#Word64 = (-1#Int64) +branchw64 4294967297#Word64 = 9223372036854775806#Int64 +branchw64 18446744073709551615#Word64 = (-9223372036854775808#Int64) +branchw64 18446744073709551614#Word64 = (-9223372036854775807#Int64) +branchw64 18446744073709551613#Word64 = 1#Int64 +branchw64 _ = 0#Int64 +{-# NOINLINE branchw64 #-} + +x :: () -> Word64# +x () = 2000000000#Word64 +{-# NOINLINE x #-} + +y :: () -> Word64# +y () = 50000#Word64 +{-# NOINLINE y #-} diff --git a/testsuite/tests/extendedliterals/extendedliterals03.stdout b/testsuite/tests/extendedliterals/extendedliterals03.stdout new file mode 100644 index 0000000000..eba8001d49 --- /dev/null +++ b/testsuite/tests/extendedliterals/extendedliterals03.stdout @@ -0,0 +1,16 @@ +(8,8,8,8) +(8,8,8,8) +18446744073709551615 +9223372036854775807 +-9223372036854775808 +100000000000000 +True +False +[1,2,3,4,5,6,7,0] +[1,2,3,255,256,65534,65535,0] +[1,2,3,65535,65536,4294967294,4294967295,0] +[18446744073709551615,2147483648,4294967296,4294967297,9,1,18446744073709551614,3,4,5,6,7,8,0] +[1,-1,2,-2,0] +[256,-256,32767,-32768,-1,1,0] +[2147483647,-2147483648,65535,65536,-1,-65536,-65537,1,0] +[9223372036854775807,2147483648,4294967296,4294967297,-1,9223372036854775806,-9223372036854775808,-9223372036854775807,1,0] diff --git a/testsuite/tests/ghci/should_run/SizedLiterals.hs b/testsuite/tests/ghci/should_run/SizedLiterals.hs deleted file mode 100644 index e02683d27c..0000000000 --- a/testsuite/tests/ghci/should_run/SizedLiterals.hs +++ /dev/null @@ -1,117 +0,0 @@ -{-# LANGUAGE TemplateHaskell #-} - -import SizedLiteralsA -import Language.Haskell.TH - -{- - - This file is compiled with the GHC flags: - - -O -fbyte-code-and-object-code -fprefer-byte-code - - This makes sure that the Template Haskell runs in the bytecode - interpreter with optimized bytecode, allowing us to test the - sized unboxed literals. - - Running the test in GHCi directly would disable optimization. - - -} - -main :: IO () -main = do - print $(pure $ ListE [ ie (fibw8 5) - , ie (fibw16 5) - , ie (fibw32 5) - , ie (fibw64 5) - ]) - - print $(pure $ ListE [ ie (fibi8 5) - , ie (fibi16 5) - , ie (fibi32 5) - , ie (fibi64 5) - ]) - - print $(pure $ ListE [ ie (branchi8 0) - , ie (branchi8 1) - , ie (branchi8 (-1)) - , ie (branchi8 126) - , ie (branchi8 127) - , ie (branchi8 (-127)) - , ie (branchi8 (-128)) - , ie (branchi8 2) - ]) - - print $(pure $ ListE [ ie (branchi16 0) - , ie (branchi16 1) - , ie (branchi16 (-1)) - , ie (branchi16 32767) - , ie (branchi16 32766) - , ie (branchi16 (-32768)) - , ie (branchi16 (-32767)) - , ie (branchi16 2) - ]) - - print $(pure $ ListE [ ie (branchi32 0) - , ie (branchi32 1) - , ie (branchi32 (-1)) - , ie (branchi32 2147483646) - , ie (branchi32 2147483647) - , ie (branchi32 (-2147483648)) - , ie (branchi32 (-2147483647)) - , ie (branchi32 2) - ]) - - print $(pure $ ListE [ ie (branchi64 0) - , ie (branchi64 1) - , ie (branchi64 (-1)) - , ie (branchi64 2147483647) - , ie (branchi64 2147483648) - , ie (branchi64 4294967297) - , ie (branchi64 (-2147483648)) - , ie (branchi64 (-2147483649)) - , ie (branchi64 (-4294967295)) - , ie (branchi64 9223372036854775807) - , ie (branchi64 9223372036854775806) - , ie (branchi64 (-9223372036854775808)) - , ie (branchi64 (-9223372036854775807)) - , ie (branchi64 2) - ]) - - print $(pure $ ListE [ ie (branchw8 0) - , ie (branchw8 1) - , ie (branchw8 254) - , ie (branchw8 255) - , ie (branchw8 2) - ]) - - print $(pure $ ListE [ ie (branchw16 0) - , ie (branchw16 1) - , ie (branchw16 255) - , ie (branchw16 256) - , ie (branchw16 65534) - , ie (branchw16 65535) - , ie (branchw16 2) - ]) - - print $(pure $ ListE [ ie (branchw32 0) - , ie (branchw32 1) - , ie (branchw32 65534) - , ie (branchw32 65535) - , ie (branchw32 65536) - , ie (branchw32 4294967295) - , ie (branchw32 4294967294) - , ie (branchw32 4294967293) - , ie (branchw32 2) - ]) - - print $(pure $ ListE [ ie (branchw64 0) - , ie (branchw64 1) - , ie (branchw64 65536) - , ie (branchw64 4294967295) - , ie (branchw64 4294967296) - , ie (branchw64 4294967297) - , ie (branchw64 18446744073709551615) - , ie (branchw64 18446744073709551614) - , ie (branchw64 18446744073709551613) - , ie (branchw64 2) - ]) \ No newline at end of file diff --git a/testsuite/tests/ghci/should_run/SizedLiteralsA.hs b/testsuite/tests/ghci/should_run/SizedLiteralsA.hs deleted file mode 100644 index 3cfec65071..0000000000 --- a/testsuite/tests/ghci/should_run/SizedLiteralsA.hs +++ /dev/null @@ -1,139 +0,0 @@ -module SizedLiteralsA where - -import GHC.Word -import GHC.Int -import Language.Haskell.TH.Syntax - -fibw8 :: Word8 -> Word8 -fibw8 0 = 0 -fibw8 1 = 1 -fibw8 n = fibw8 (n-1) + fibw8 (n-2) - -fibw16 :: Word16 -> Word16 -fibw16 0 = 0 -fibw16 1 = 1 -fibw16 n = fibw16 (n-1) + fibw16 (n-2) - -fibw32 :: Word32 -> Word32 -fibw32 0 = 0 -fibw32 1 = 1 -fibw32 n = fibw32 (n-1) + fibw32 (n-2) - -fibw64 :: Word64 -> Word64 -fibw64 0 = 0 -fibw64 1 = 1 -fibw64 n = fibw64 (n-1) + fibw64 (n-2) - --- - -fibi8 :: Int8 -> Int8 -fibi8 0 = 0 -fibi8 1 = 1 -fibi8 n = fibi8 (n-1) + fibi8 (n-2) - -fibi16 :: Int16 -> Int16 -fibi16 0 = 0 -fibi16 1 = 1 -fibi16 n = fibi16 (n-1) + fibi16 (n-2) - -fibi32 :: Int32 -> Int32 -fibi32 0 = 0 -fibi32 1 = 1 -fibi32 n = fibi32 (n-1) + fibi32 (n-2) - -fibi64 :: Int64 -> Int64 -fibi64 0 = 0 -fibi64 1 = 1 -fibi64 n = fibi64 (n-1) + fibi64 (n-2) - --- - -branchi8 :: Int8 -> Word8 -branchi8 0 = 1 -branchi8 1 = 2 -branchi8 (-1) = 3 -branchi8 126 = 4 -branchi8 127 = 5 -branchi8 (-127) = 6 -branchi8 (-128) = 7 -branchi8 _ = 0 - -branchi16 :: Int16 -> Word16 -branchi16 0 = 1 -branchi16 1 = 2 -branchi16 (-1) = 3 -branchi16 32767 = 255 -branchi16 32766 = 256 -branchi16 (-32768) = 65534 -branchi16 (-32767) = 65535 -branchi16 _ = 0 - -branchi32 :: Int32 -> Word32 -branchi32 0 = 1 -branchi32 1 = 2 -branchi32 (-1) = 3 -branchi32 2147483646 = 65535 -branchi32 2147483647 = 65536 -branchi32 (-2147483648) = 4294967294 -branchi32 (-2147483647) = 4294967295 -branchi32 _ = 0 - -branchi64 :: Int64 -> Word64 -branchi64 0 = 18446744073709551615 -branchi64 1 = 2147483648 -branchi64 (-1) = 4294967296 -branchi64 2147483647 = 4294967297 -branchi64 2147483648 = 9 -branchi64 4294967297 = 1 -branchi64 (-2147483648) = 18446744073709551614 -branchi64 (-2147483649) = 3 -branchi64 (-4294967295) = 4 -branchi64 9223372036854775807 = 5 -branchi64 9223372036854775806 = 6 -branchi64 (-9223372036854775808) = 7 -branchi64 (-9223372036854775807) = 8 -branchi64 _ = 0 - -branchw8 :: Word8 -> Int8 -branchw8 0 = 1 -branchw8 1 = (-1) -branchw8 254 = 2 -branchw8 255 = (-2) -branchw8 _ = 0 - -branchw16 :: Word16 -> Int16 -branchw16 0 = 256 -branchw16 1 = (-256) -branchw16 255 = 32767 -branchw16 256 = (-32768) -branchw16 65534 = (-1) -branchw16 65535 = 1 -branchw16 _ = 0 - -branchw32 :: Word32 -> Int32 -branchw32 0 = 2147483647 -branchw32 1 = (-2147483648) -branchw32 65534 = 65535 -branchw32 65535 = 65536 -branchw32 65536 = (-1) -branchw32 4294967295 = (-65536) -branchw32 4294967294 = (-65537) -branchw32 4294967293 = 1 -branchw32 _ = 0 - -branchw64 :: Word64 -> Int64 -branchw64 0 = 9223372036854775807 -branchw64 1 = 2147483648 -branchw64 65536 = 4294967296 -branchw64 4294967295 = 4294967297 -branchw64 4294967296 = (-1) -branchw64 4294967297 = 9223372036854775806 -branchw64 18446744073709551615 = (-9223372036854775808) -branchw64 18446744073709551614 = (-9223372036854775807) -branchw64 18446744073709551613 = 1 -branchw64 _ = 0 - --- - -ie :: Integral a => a -> Exp -ie x = LitE (IntegerL (toInteger x)) diff --git a/testsuite/tests/ghci/should_run/all.T b/testsuite/tests/ghci/should_run/all.T index 15df5e417c..aaa8dfe856 100644 --- a/testsuite/tests/ghci/should_run/all.T +++ b/testsuite/tests/ghci/should_run/all.T @@ -85,7 +85,6 @@ test('T19628', [extra_files(['T19628a.hs']), only_ways(['ghci']) ], compile_and_ test('T21052', just_ghci, ghci_script, ['T21052.script']) test('T21300', just_ghci, ghci_script, ['T21300.script']) test('UnliftedDataType2', just_ghci, compile_and_run, ['']) -test('SizedLiterals', [req_interp, extra_files(["SizedLiteralsA.hs"]),extra_hc_opts("-O -fbyte-code-and-object-code -fprefer-byte-code")], compile_and_run, ['']) test('T22829', just_ghci + [extra_hc_opts("-Wmissing-import-lists -Werror")], compile_and_run, ['']) test('T23229', just_ghci + [extra_hc_opts("-this-unit-id my-package -Wno-missing-methods T23229")], ghci_script, ['T23229.script']) diff --git a/testsuite/tests/printer/Ppr038.hs b/testsuite/tests/printer/Ppr038.hs index 43fafaf01c..17b42802fb 100644 --- a/testsuite/tests/printer/Ppr038.hs +++ b/testsuite/tests/printer/Ppr038.hs @@ -21,6 +21,14 @@ blah = x wordH = 005## floatH = 3.20# doubleH = 04.16## - -- int64H = 00456L# - -- word64H = 00456L## + intNH = 1000#Int + int8H = 1008#Int8 + int16H = 1016#Int8 + int32H = 1032#Int32 + int64H = 1064#Int64 + wordNH = 2000#Word + word8H = 2008#Word8 + word16H = 2016#Word16 + word32H = 2032#Word32 + word64H = 2064#Word64 x = 1 diff --git a/utils/check-exact/ExactPrint.hs b/utils/check-exact/ExactPrint.hs index 5db255f765..f4d4defb5b 100644 --- a/utils/check-exact/ExactPrint.hs +++ b/utils/check-exact/ExactPrint.hs @@ -4695,7 +4695,13 @@ hsLit2String lit = HsInt _ (IL src _ v) -> toSourceTextWithSuffix src v "" HsIntPrim src v -> toSourceTextWithSuffix src v "" HsWordPrim src v -> toSourceTextWithSuffix src v "" + HsInt8Prim src v -> toSourceTextWithSuffix src v "" + HsInt16Prim src v -> toSourceTextWithSuffix src v "" + HsInt32Prim src v -> toSourceTextWithSuffix src v "" HsInt64Prim src v -> toSourceTextWithSuffix src v "" + HsWord8Prim src v -> toSourceTextWithSuffix src v "" + HsWord16Prim src v -> toSourceTextWithSuffix src v "" + HsWord32Prim src v -> toSourceTextWithSuffix src v "" HsWord64Prim src v -> toSourceTextWithSuffix src v "" HsInteger src v _ -> toSourceTextWithSuffix src v "" HsRat _ fl@(FL{fl_text = src }) _ -> toSourceTextWithSuffix src fl "" diff --git a/utils/haddock b/utils/haddock index 03ba53ca76..e16e20d592 160000 --- a/utils/haddock +++ b/utils/haddock @@ -1 +1 @@ -Subproject commit 03ba53ca764f56a13d12607c110f923f129e809a +Subproject commit e16e20d592a6f5d9ed1af17b77fafd6495242345 -- cgit v1.2.1