{-# LANGUAGE ConstraintKinds      #-}
{-# LANGUAGE FlexibleContexts     #-}
{-# LANGUAGE FlexibleInstances    #-}
{-# LANGUAGE TypeFamilies         #-}
{-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow]
                                      -- in module Language.Haskell.Syntax.Extension
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE TypeApplications #-}

{-# OPTIONS_GHC -Wno-orphans #-} -- Outputable, OutputableBndrId

{-
(c) The University of Glasgow 2006
(c) The GRASP/AQUA Project, Glasgow University, 1992-1998

-}

-- | Source-language literals
module GHC.Hs.Lit
  ( module Language.Haskell.Syntax.Lit
  , module GHC.Hs.Lit
  ) where

import GHC.Prelude

import {-# SOURCE #-} GHC.Hs.Expr( pprExpr )

import GHC.Data.FastString (unpackFS)
import GHC.Types.Basic (PprPrec(..), topPrec )
import GHC.Core.Ppr ( {- instance OutputableBndr TyVar -} )
import GHC.Types.SourceText
import GHC.Core.Type
import GHC.Utils.Misc (split)
import GHC.Utils.Outputable
import GHC.Utils.Panic (panic)
import GHC.Hs.Extension
import Language.Haskell.Syntax.Expr ( HsExpr )
import Language.Haskell.Syntax.Extension
import Language.Haskell.Syntax.Lit

{-
************************************************************************
*                                                                      *
\subsection[HsLit]{Literals}
*                                                                      *
************************************************************************
-}

type instance XHsChar       (GhcPass _) = SourceText
type instance XHsCharPrim   (GhcPass _) = SourceText
type instance XHsString     (GhcPass _) = SourceText
type instance XHsMultilineString (GhcPass _) = SourceText
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 XHsFloatPrim  (GhcPass _) = NoExtField
type instance XHsDoublePrim (GhcPass _) = NoExtField

type instance XXLit         GhcPs = DataConCantHappen
type instance XXLit         GhcRn = DataConCantHappen
type instance XXLit         GhcTc = HsLitTc

data HsLitTc
  = HsInteger SourceText Integer Type
      -- ^ Genuinely an integer; arises only
      -- from TRANSLATION (overloaded
      -- literals are done with HsOverLit)
  | HsRat FractionalLit Type
      -- ^ Genuinely a rational; arises only from
      -- TRANSLATION (overloaded literals are
      -- done with HsOverLit)
instance Eq HsLitTc where
  (HsInteger SourceText
_ Integer
x Type
_) == :: HsLitTc -> HsLitTc -> Bool
== (HsInteger SourceText
_ Integer
y Type
_) = Integer
xInteger -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
==Integer
y
  (HsRat FractionalLit
x Type
_)       == (HsRat FractionalLit
y Type
_)       = FractionalLit
xFractionalLit -> FractionalLit -> Bool
forall a. Eq a => a -> a -> Bool
==FractionalLit
y
  HsLitTc
_                 == HsLitTc
_                 = Bool
False

data OverLitRn
  = OverLitRn {
        OverLitRn -> Bool
ol_rebindable :: Bool,         -- Note [ol_rebindable]
        OverLitRn -> LIdP GhcRn
ol_from_fun   :: LIdP GhcRn    -- Note [Overloaded literal witnesses]
        }

data OverLitTc
  = OverLitTc {
        OverLitTc -> Bool
ol_rebindable :: Bool,         -- Note [ol_rebindable]
        OverLitTc -> HsExpr GhcTc
ol_witness    :: HsExpr GhcTc, -- Note [Overloaded literal witnesses]
        OverLitTc -> Type
ol_type :: Type }

{-
Note [Overloaded literal witnesses]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

During renaming, the coercion function needed for a given HsOverLit is
resolved according to the current scope and RebindableSyntax (see Note
[ol_rebindable]). The result of this resolution *before* type checking
is the coercion function such as 'fromInteger' or 'fromRational',
stored in the ol_from_fun field of OverLitRn.

*After* type checking, the ol_witness field of the OverLitTc contains
the witness of the literal as HsExpr, such as (fromInteger 3) or
lit_78. This witness should replace the literal. Reason: it allows
commoning up of the fromInteger calls, which wouldn't be possible if
the desugarer made the application.

The ol_type in OverLitTc records the type the overloaded literal is
found to have.
-}

type instance XOverLit GhcPs = NoExtField
type instance XOverLit GhcRn = OverLitRn
type instance XOverLit GhcTc = OverLitTc

pprXOverLit :: GhcPass p -> XOverLit (GhcPass p) -> SDoc
pprXOverLit :: forall (p :: Pass). GhcPass p -> XOverLit (GhcPass p) -> SDoc
pprXOverLit GhcPass p
GhcPs XOverLit (GhcPass p)
noExt = NoExtField -> SDoc
forall a. Outputable a => a -> SDoc
ppr XOverLit (GhcPass p)
NoExtField
noExt
pprXOverLit GhcPass p
GhcRn OverLitRn{ ol_from_fun :: OverLitRn -> LIdP GhcRn
ol_from_fun = LIdP GhcRn
from_fun } = GenLocated SrcSpanAnnN Name -> SDoc
forall a. Outputable a => a -> SDoc
ppr LIdP GhcRn
GenLocated SrcSpanAnnN Name
from_fun
pprXOverLit GhcPass p
GhcTc OverLitTc{ ol_witness :: OverLitTc -> HsExpr GhcTc
ol_witness = HsExpr GhcTc
witness } = HsExpr GhcTc -> SDoc
forall (p :: Pass).
OutputableBndrId p =>
HsExpr (GhcPass p) -> SDoc
pprExpr HsExpr GhcTc
witness

type instance XXOverLit (GhcPass _) = DataConCantHappen

overLitType :: HsOverLit GhcTc -> Type
overLitType :: HsOverLit GhcTc -> Type
overLitType (OverLit OverLitTc{ ol_type :: OverLitTc -> Type
ol_type = Type
ty } OverLitVal
_) = Type
ty

-- | @'hsOverLitNeedsParens' p ol@ returns 'True' if an overloaded literal
-- @ol@ needs to be parenthesized under precedence @p@.
hsOverLitNeedsParens :: PprPrec -> HsOverLit x -> Bool
hsOverLitNeedsParens :: forall x. PprPrec -> HsOverLit x -> Bool
hsOverLitNeedsParens PprPrec
p (OverLit { ol_val :: forall p. HsOverLit p -> OverLitVal
ol_val = OverLitVal
olv }) = OverLitVal -> Bool
go OverLitVal
olv
  where
    go :: OverLitVal -> Bool
    go :: OverLitVal -> Bool
go (HsIntegral IntegralLit
x)   = PprPrec
p PprPrec -> PprPrec -> Bool
forall a. Ord a => a -> a -> Bool
> PprPrec
topPrec Bool -> Bool -> Bool
&& IntegralLit -> Bool
il_neg IntegralLit
x
    go (HsFractional FractionalLit
x) = PprPrec
p PprPrec -> PprPrec -> Bool
forall a. Ord a => a -> a -> Bool
> PprPrec
topPrec Bool -> Bool -> Bool
&& FractionalLit -> Bool
fl_neg FractionalLit
x
    go (HsIsString {})  = Bool
False
hsOverLitNeedsParens PprPrec
_ (XOverLit { }) = Bool
False

-- | @'hsLitNeedsParens' p l@ returns 'True' if a literal @l@ needs
-- to be parenthesized under precedence @p@.
--
-- See Note [Printing of literals in Core] in GHC.Types.Literal
-- for the reasoning.
hsLitNeedsParens :: forall x. IsPass x => PprPrec -> HsLit (GhcPass x) -> Bool
hsLitNeedsParens :: forall (x :: Pass).
IsPass x =>
PprPrec -> HsLit (GhcPass x) -> Bool
hsLitNeedsParens PprPrec
p = HsLit (GhcPass x) -> Bool
go
  where
    go :: HsLit (GhcPass x) -> Bool
go (HsChar {})        = Bool
False
    go (HsCharPrim {})    = Bool
False
    go (HsString {})      = Bool
False
    go (HsMultilineString {}) = Bool
False
    go (HsStringPrim {})  = Bool
False
    go (HsInt XHsInt (GhcPass x)
_ IntegralLit
x)        = PprPrec
p PprPrec -> PprPrec -> Bool
forall a. Ord a => a -> a -> Bool
> PprPrec
topPrec Bool -> Bool -> Bool
&& IntegralLit -> Bool
il_neg IntegralLit
x
    go (HsFloatPrim {})   = Bool
False
    go (HsDoublePrim {})  = Bool
False
    go (HsIntPrim {})     = Bool
False
    go (HsInt8Prim {})    = Bool
False
    go (HsInt16Prim {})   = Bool
False
    go (HsInt32Prim {})   = Bool
False
    go (HsInt64Prim {})   = Bool
False
    go (HsWordPrim {})    = Bool
False
    go (HsWord8Prim {})   = Bool
False
    go (HsWord16Prim {})  = Bool
False
    go (HsWord64Prim {})  = Bool
False
    go (HsWord32Prim {})  = Bool
False
    go (XLit XXLit (GhcPass x)
x)           = case forall (p :: Pass). IsPass p => GhcPass p
ghcPass @x of
      GhcPass x
GhcTc -> case XXLit (GhcPass x)
x of
         (HsInteger SourceText
_ Integer
x Type
_) -> PprPrec
p PprPrec -> PprPrec -> Bool
forall a. Ord a => a -> a -> Bool
> PprPrec
topPrec Bool -> Bool -> Bool
&& Integer
x Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0
         (HsRat  FractionalLit
x Type
_)      -> PprPrec
p PprPrec -> PprPrec -> Bool
forall a. Ord a => a -> a -> Bool
> PprPrec
topPrec Bool -> Bool -> Bool
&& FractionalLit -> Bool
fl_neg FractionalLit
x


-- | Convert a literal from one index type to another.
-- The constraint XXLit (GhcPass p)~DataConCantHappen means that once the
-- XLit constructor is inhabited, we can no longer go back to the case where
-- its not. In practice it just means you can't just convertLit to go from
-- (HsLit GhcTc) -> (HsLit GhcPs/GhcRn), while all other conversions are fine.
convertLit :: XXLit (GhcPass p)~DataConCantHappen => HsLit (GhcPass p) -> HsLit (GhcPass p')
convertLit :: forall (p :: Pass) (p' :: Pass).
(XXLit (GhcPass p) ~ DataConCantHappen) =>
HsLit (GhcPass p) -> HsLit (GhcPass p')
convertLit (HsChar XHsChar (GhcPass p)
a Char
x)       = XHsChar (GhcPass p') -> Char -> HsLit (GhcPass p')
forall x. XHsChar x -> Char -> HsLit x
HsChar XHsChar (GhcPass p)
XHsChar (GhcPass p')
a Char
x
convertLit (HsCharPrim XHsCharPrim (GhcPass p)
a Char
x)   = XHsCharPrim (GhcPass p') -> Char -> HsLit (GhcPass p')
forall x. XHsCharPrim x -> Char -> HsLit x
HsCharPrim XHsCharPrim (GhcPass p)
XHsCharPrim (GhcPass p')
a Char
x
convertLit (HsString XHsString (GhcPass p)
a FastString
x)     = XHsString (GhcPass p') -> FastString -> HsLit (GhcPass p')
forall x. XHsString x -> FastString -> HsLit x
HsString XHsString (GhcPass p)
XHsString (GhcPass p')
a FastString
x
convertLit (HsMultilineString XHsMultilineString (GhcPass p)
a FastString
x) = XHsMultilineString (GhcPass p') -> FastString -> HsLit (GhcPass p')
forall x. XHsMultilineString x -> FastString -> HsLit x
HsMultilineString XHsMultilineString (GhcPass p)
XHsMultilineString (GhcPass p')
a FastString
x
convertLit (HsStringPrim XHsStringPrim (GhcPass p)
a ByteString
x) = XHsStringPrim (GhcPass p') -> ByteString -> HsLit (GhcPass p')
forall x. XHsStringPrim x -> ByteString -> HsLit x
HsStringPrim XHsStringPrim (GhcPass p)
XHsStringPrim (GhcPass p')
a ByteString
x
convertLit (HsInt XHsInt (GhcPass p)
a IntegralLit
x)        = XHsInt (GhcPass p') -> IntegralLit -> HsLit (GhcPass p')
forall x. XHsInt x -> IntegralLit -> HsLit x
HsInt XHsInt (GhcPass p)
XHsInt (GhcPass p')
a IntegralLit
x
convertLit (HsIntPrim XHsIntPrim (GhcPass p)
a Integer
x)    = XHsIntPrim (GhcPass p') -> Integer -> HsLit (GhcPass p')
forall x. XHsIntPrim x -> Integer -> HsLit x
HsIntPrim XHsIntPrim (GhcPass p)
XHsIntPrim (GhcPass p')
a Integer
x
convertLit (HsWordPrim XHsWordPrim (GhcPass p)
a Integer
x)   = XHsWordPrim (GhcPass p') -> Integer -> HsLit (GhcPass p')
forall x. XHsWordPrim x -> Integer -> HsLit x
HsWordPrim XHsWordPrim (GhcPass p)
XHsWordPrim (GhcPass p')
a Integer
x
convertLit (HsInt8Prim XHsInt8Prim (GhcPass p)
a Integer
x)   = XHsInt8Prim (GhcPass p') -> Integer -> HsLit (GhcPass p')
forall x. XHsInt8Prim x -> Integer -> HsLit x
HsInt8Prim XHsInt8Prim (GhcPass p)
XHsInt8Prim (GhcPass p')
a Integer
x
convertLit (HsInt16Prim XHsInt16Prim (GhcPass p)
a Integer
x)  = XHsInt16Prim (GhcPass p') -> Integer -> HsLit (GhcPass p')
forall x. XHsInt16Prim x -> Integer -> HsLit x
HsInt16Prim XHsInt16Prim (GhcPass p)
XHsInt16Prim (GhcPass p')
a Integer
x
convertLit (HsInt32Prim XHsInt32Prim (GhcPass p)
a Integer
x)  = XHsInt32Prim (GhcPass p') -> Integer -> HsLit (GhcPass p')
forall x. XHsInt32Prim x -> Integer -> HsLit x
HsInt32Prim XHsInt32Prim (GhcPass p)
XHsInt32Prim (GhcPass p')
a Integer
x
convertLit (HsInt64Prim XHsInt64Prim (GhcPass p)
a Integer
x)  = XHsInt64Prim (GhcPass p') -> Integer -> HsLit (GhcPass p')
forall x. XHsInt64Prim x -> Integer -> HsLit x
HsInt64Prim XHsInt64Prim (GhcPass p)
XHsInt64Prim (GhcPass p')
a Integer
x
convertLit (HsWord8Prim XHsWord8Prim (GhcPass p)
a Integer
x)  = XHsWord8Prim (GhcPass p') -> Integer -> HsLit (GhcPass p')
forall x. XHsWord8Prim x -> Integer -> HsLit x
HsWord8Prim XHsWord8Prim (GhcPass p)
XHsWord8Prim (GhcPass p')
a Integer
x
convertLit (HsWord16Prim XHsWord16Prim (GhcPass p)
a Integer
x) = XHsWord16Prim (GhcPass p') -> Integer -> HsLit (GhcPass p')
forall x. XHsWord16Prim x -> Integer -> HsLit x
HsWord16Prim XHsWord16Prim (GhcPass p)
XHsWord16Prim (GhcPass p')
a Integer
x
convertLit (HsWord32Prim XHsWord32Prim (GhcPass p)
a Integer
x) = XHsWord32Prim (GhcPass p') -> Integer -> HsLit (GhcPass p')
forall x. XHsWord32Prim x -> Integer -> HsLit x
HsWord32Prim XHsWord32Prim (GhcPass p)
XHsWord32Prim (GhcPass p')
a Integer
x
convertLit (HsWord64Prim XHsWord64Prim (GhcPass p)
a Integer
x) = XHsWord64Prim (GhcPass p') -> Integer -> HsLit (GhcPass p')
forall x. XHsWord64Prim x -> Integer -> HsLit x
HsWord64Prim XHsWord64Prim (GhcPass p)
XHsWord64Prim (GhcPass p')
a Integer
x
convertLit (HsFloatPrim XHsFloatPrim (GhcPass p)
a FractionalLit
x)  = XHsFloatPrim (GhcPass p') -> FractionalLit -> HsLit (GhcPass p')
forall x. XHsFloatPrim x -> FractionalLit -> HsLit x
HsFloatPrim XHsFloatPrim (GhcPass p)
XHsFloatPrim (GhcPass p')
a FractionalLit
x
convertLit (HsDoublePrim XHsDoublePrim (GhcPass p)
a FractionalLit
x) = XHsDoublePrim (GhcPass p') -> FractionalLit -> HsLit (GhcPass p')
forall x. XHsDoublePrim x -> FractionalLit -> HsLit x
HsDoublePrim XHsDoublePrim (GhcPass p)
XHsDoublePrim (GhcPass p')
a FractionalLit
x

{-
Note [ol_rebindable]
~~~~~~~~~~~~~~~~~~~~
The ol_rebindable field is True if this literal is actually
using rebindable syntax.  Specifically:

  False iff ol_from_fun / ol_witness is the standard one
  True  iff ol_from_fun / ol_witness is non-standard

Equivalently it's True if
  a) RebindableSyntax is on
  b) the witness for fromInteger/fromRational/fromString
     that happens to be in scope isn't the standard one
-}

-- Instance specific to GhcPs, need the SourceText
instance IsPass p => Outputable (HsLit (GhcPass p)) where
    ppr :: HsLit (GhcPass p) -> SDoc
ppr (HsChar XHsChar (GhcPass p)
st Char
c)       = SourceText -> SDoc -> SDoc
pprWithSourceText XHsChar (GhcPass p)
SourceText
st (Char -> SDoc
pprHsChar Char
c)
    ppr (HsCharPrim XHsCharPrim (GhcPass p)
st Char
c)   = SourceText -> SDoc -> SDoc
pprWithSourceText XHsCharPrim (GhcPass p)
SourceText
st (Char -> SDoc
pprPrimChar Char
c)
    ppr (HsString XHsString (GhcPass p)
st FastString
s)     = SourceText -> SDoc -> SDoc
pprWithSourceText XHsString (GhcPass p)
SourceText
st (FastString -> SDoc
pprHsString FastString
s)
    ppr (HsMultilineString XHsMultilineString (GhcPass p)
st FastString
s) =
      case XHsMultilineString (GhcPass p)
st of
        XHsMultilineString (GhcPass p)
SourceText
NoSourceText -> FastString -> SDoc
pprHsString FastString
s
        SourceText FastString
src -> [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (String -> SDoc) -> [String] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map String -> SDoc
forall doc. IsLine doc => String -> doc
text ([String] -> [SDoc]) -> [String] -> [SDoc]
forall a b. (a -> b) -> a -> b
$ Char -> String -> [String]
split Char
'\n' (FastString -> String
unpackFS FastString
src)
    ppr (HsStringPrim XHsStringPrim (GhcPass p)
st ByteString
s) = SourceText -> SDoc -> SDoc
pprWithSourceText XHsStringPrim (GhcPass p)
SourceText
st (ByteString -> SDoc
pprHsBytes ByteString
s)
    ppr (HsInt XHsInt (GhcPass p)
_ IntegralLit
i)
      = SourceText -> SDoc -> SDoc
pprWithSourceText (IntegralLit -> SourceText
il_text IntegralLit
i) (Integer -> SDoc
forall doc. IsLine doc => Integer -> doc
integer (IntegralLit -> Integer
il_value IntegralLit
i))
    ppr (HsFloatPrim XHsFloatPrim (GhcPass p)
_ FractionalLit
f)   = FractionalLit -> SDoc
forall a. Outputable a => a -> SDoc
ppr FractionalLit
f SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
primFloatSuffix
    ppr (HsDoublePrim XHsDoublePrim (GhcPass p)
_ FractionalLit
d)  = FractionalLit -> SDoc
forall a. Outputable a => a -> SDoc
ppr FractionalLit
d SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
primDoubleSuffix
    ppr (HsIntPrim XHsIntPrim (GhcPass p)
st Integer
i)    = SourceText -> SDoc -> SDoc
pprWithSourceText XHsIntPrim (GhcPass p)
SourceText
st (Integer -> SDoc
pprPrimInt Integer
i)
    ppr (HsInt8Prim XHsInt8Prim (GhcPass p)
st Integer
i)   = SourceText -> SDoc -> SDoc
pprWithSourceText XHsInt8Prim (GhcPass p)
SourceText
st (Integer -> SDoc
pprPrimInt8 Integer
i)
    ppr (HsInt16Prim XHsInt16Prim (GhcPass p)
st Integer
i)  = SourceText -> SDoc -> SDoc
pprWithSourceText XHsInt16Prim (GhcPass p)
SourceText
st (Integer -> SDoc
pprPrimInt16 Integer
i)
    ppr (HsInt32Prim XHsInt32Prim (GhcPass p)
st Integer
i)  = SourceText -> SDoc -> SDoc
pprWithSourceText XHsInt32Prim (GhcPass p)
SourceText
st (Integer -> SDoc
pprPrimInt32 Integer
i)
    ppr (HsInt64Prim XHsInt64Prim (GhcPass p)
st Integer
i)  = SourceText -> SDoc -> SDoc
pprWithSourceText XHsInt64Prim (GhcPass p)
SourceText
st (Integer -> SDoc
pprPrimInt64 Integer
i)
    ppr (HsWordPrim XHsWordPrim (GhcPass p)
st Integer
w)   = SourceText -> SDoc -> SDoc
pprWithSourceText XHsWordPrim (GhcPass p)
SourceText
st (Integer -> SDoc
pprPrimWord Integer
w)
    ppr (HsWord8Prim XHsWord8Prim (GhcPass p)
st Integer
w)  = SourceText -> SDoc -> SDoc
pprWithSourceText XHsWord8Prim (GhcPass p)
SourceText
st (Integer -> SDoc
pprPrimWord8 Integer
w)
    ppr (HsWord16Prim XHsWord16Prim (GhcPass p)
st Integer
w) = SourceText -> SDoc -> SDoc
pprWithSourceText XHsWord16Prim (GhcPass p)
SourceText
st (Integer -> SDoc
pprPrimWord16 Integer
w)
    ppr (HsWord32Prim XHsWord32Prim (GhcPass p)
st Integer
w) = SourceText -> SDoc -> SDoc
pprWithSourceText XHsWord32Prim (GhcPass p)
SourceText
st (Integer -> SDoc
pprPrimWord32 Integer
w)
    ppr (HsWord64Prim XHsWord64Prim (GhcPass p)
st Integer
w) = SourceText -> SDoc -> SDoc
pprWithSourceText XHsWord64Prim (GhcPass p)
SourceText
st (Integer -> SDoc
pprPrimWord64 Integer
w)
    ppr (XLit XXLit (GhcPass p)
x)            = case forall (p :: Pass). IsPass p => GhcPass p
ghcPass @p of
      GhcPass p
GhcTc -> case XXLit (GhcPass p)
x of
         (HsInteger SourceText
st Integer
i Type
_) -> SourceText -> SDoc -> SDoc
pprWithSourceText SourceText
st (Integer -> SDoc
forall doc. IsLine doc => Integer -> doc
integer Integer
i)
         (HsRat  FractionalLit
f Type
_)       -> FractionalLit -> SDoc
forall a. Outputable a => a -> SDoc
ppr FractionalLit
f

-- in debug mode, print the expression that it's resolved to, too
instance OutputableBndrId p
       => Outputable (HsOverLit (GhcPass p)) where
  ppr :: HsOverLit (GhcPass p) -> SDoc
ppr (OverLit {ol_val :: forall p. HsOverLit p -> OverLitVal
ol_val=OverLitVal
val, ol_ext :: forall p. HsOverLit p -> XOverLit p
ol_ext=XOverLit (GhcPass p)
ext})
        = OverLitVal -> SDoc
forall a. Outputable a => a -> SDoc
ppr OverLitVal
val SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> (SDoc -> SDoc
forall doc. IsOutput doc => doc -> doc
whenPprDebug (SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens (GhcPass p -> XOverLit (GhcPass p) -> SDoc
forall (p :: Pass). GhcPass p -> XOverLit (GhcPass p) -> SDoc
pprXOverLit (forall (p :: Pass). IsPass p => GhcPass p
ghcPass @p) XOverLit (GhcPass p)
ext)))

instance Outputable OverLitVal where
  ppr :: OverLitVal -> SDoc
ppr (HsIntegral IntegralLit
i)     = SourceText -> SDoc -> SDoc
pprWithSourceText (IntegralLit -> SourceText
il_text IntegralLit
i) (Integer -> SDoc
forall doc. IsLine doc => Integer -> doc
integer (IntegralLit -> Integer
il_value IntegralLit
i))
  ppr (HsFractional FractionalLit
f)   = FractionalLit -> SDoc
forall a. Outputable a => a -> SDoc
ppr FractionalLit
f
  ppr (HsIsString SourceText
st FastString
s)  = SourceText -> SDoc -> SDoc
pprWithSourceText SourceText
st (FastString -> SDoc
pprHsString FastString
s)

-- | pmPprHsLit pretty prints literals and is used when pretty printing pattern
-- match warnings. All are printed the same (i.e., without hashes if they are
-- primitive and not wrapped in constructors if they are boxed). This happens
-- mainly for too reasons:
--  * We do not want to expose their internal representation
--  * The warnings become too messy
pmPprHsLit :: forall p. IsPass p => HsLit (GhcPass p) -> SDoc
pmPprHsLit :: forall (p :: Pass). IsPass p => HsLit (GhcPass p) -> SDoc
pmPprHsLit (HsChar XHsChar (GhcPass p)
_ Char
c)       = Char -> SDoc
pprHsChar Char
c
pmPprHsLit (HsCharPrim XHsCharPrim (GhcPass p)
_ Char
c)   = Char -> SDoc
pprHsChar Char
c
pmPprHsLit (HsString XHsString (GhcPass p)
st FastString
s)    = SourceText -> SDoc -> SDoc
pprWithSourceText XHsString (GhcPass p)
SourceText
st (FastString -> SDoc
pprHsString FastString
s)
pmPprHsLit (HsMultilineString XHsMultilineString (GhcPass p)
st FastString
s) = SourceText -> SDoc -> SDoc
pprWithSourceText XHsMultilineString (GhcPass p)
SourceText
st (FastString -> SDoc
pprHsString FastString
s)
pmPprHsLit (HsStringPrim XHsStringPrim (GhcPass p)
_ ByteString
s) = ByteString -> SDoc
pprHsBytes ByteString
s
pmPprHsLit (HsInt XHsInt (GhcPass p)
_ IntegralLit
i)        = Integer -> SDoc
forall doc. IsLine doc => Integer -> doc
integer (IntegralLit -> Integer
il_value IntegralLit
i)
pmPprHsLit (HsIntPrim XHsIntPrim (GhcPass p)
_ Integer
i)    = Integer -> SDoc
forall doc. IsLine doc => Integer -> doc
integer Integer
i
pmPprHsLit (HsWordPrim XHsWordPrim (GhcPass p)
_ Integer
w)   = Integer -> SDoc
forall doc. IsLine doc => Integer -> doc
integer Integer
w
pmPprHsLit (HsInt8Prim XHsInt8Prim (GhcPass p)
_ Integer
i)   = Integer -> SDoc
forall doc. IsLine doc => Integer -> doc
integer Integer
i
pmPprHsLit (HsInt16Prim XHsInt16Prim (GhcPass p)
_ Integer
i)  = Integer -> SDoc
forall doc. IsLine doc => Integer -> doc
integer Integer
i
pmPprHsLit (HsInt32Prim XHsInt32Prim (GhcPass p)
_ Integer
i)  = Integer -> SDoc
forall doc. IsLine doc => Integer -> doc
integer Integer
i
pmPprHsLit (HsInt64Prim XHsInt64Prim (GhcPass p)
_ Integer
i)  = Integer -> SDoc
forall doc. IsLine doc => Integer -> doc
integer Integer
i
pmPprHsLit (HsWord8Prim XHsWord8Prim (GhcPass p)
_ Integer
w)  = Integer -> SDoc
forall doc. IsLine doc => Integer -> doc
integer Integer
w
pmPprHsLit (HsWord16Prim XHsWord16Prim (GhcPass p)
_ Integer
w) = Integer -> SDoc
forall doc. IsLine doc => Integer -> doc
integer Integer
w
pmPprHsLit (HsWord32Prim XHsWord32Prim (GhcPass p)
_ Integer
w) = Integer -> SDoc
forall doc. IsLine doc => Integer -> doc
integer Integer
w
pmPprHsLit (HsWord64Prim XHsWord64Prim (GhcPass p)
_ Integer
w) = Integer -> SDoc
forall doc. IsLine doc => Integer -> doc
integer Integer
w
pmPprHsLit (HsFloatPrim XHsFloatPrim (GhcPass p)
_ FractionalLit
f)  = FractionalLit -> SDoc
forall a. Outputable a => a -> SDoc
ppr FractionalLit
f
pmPprHsLit (HsDoublePrim XHsDoublePrim (GhcPass p)
_ FractionalLit
d) = FractionalLit -> SDoc
forall a. Outputable a => a -> SDoc
ppr FractionalLit
d
pmPprHsLit (XLit XXLit (GhcPass p)
x)           = case forall (p :: Pass). IsPass p => GhcPass p
ghcPass @p of
  GhcPass p
GhcTc -> case XXLit (GhcPass p)
x of
   (HsInteger SourceText
_ Integer
i Type
_)  -> Integer -> SDoc
forall doc. IsLine doc => Integer -> doc
integer Integer
i
   (HsRat FractionalLit
f Type
_)        -> FractionalLit -> SDoc
forall a. Outputable a => a -> SDoc
ppr FractionalLit
f

negateOverLitVal :: OverLitVal -> OverLitVal
negateOverLitVal :: OverLitVal -> OverLitVal
negateOverLitVal (HsIntegral IntegralLit
i) = IntegralLit -> OverLitVal
HsIntegral (IntegralLit -> IntegralLit
negateIntegralLit IntegralLit
i)
negateOverLitVal (HsFractional FractionalLit
f) = FractionalLit -> OverLitVal
HsFractional (FractionalLit -> FractionalLit
negateFractionalLit FractionalLit
f)
negateOverLitVal OverLitVal
_ = String -> OverLitVal
forall a. HasCallStack => String -> a
panic String
"negateOverLitVal: argument is not a number"

instance (Ord (XXOverLit p)) => Ord (HsOverLit p) where
  compare :: HsOverLit p -> HsOverLit p -> Ordering
compare (OverLit XOverLit p
_ OverLitVal
val1)  (OverLit XOverLit p
_ OverLitVal
val2) = OverLitVal
val1 OverLitVal -> OverLitVal -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` OverLitVal
val2
  compare (XOverLit  XXOverLit p
val1)  (XOverLit  XXOverLit p
val2) = XXOverLit p
val1 XXOverLit p -> XXOverLit p -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` XXOverLit p
val2
  compare HsOverLit p
_ HsOverLit p
_ = String -> Ordering
forall a. HasCallStack => String -> a
panic String
"Ord HsOverLit"

-- Comparison operations are needed when grouping literals
-- for compiling pattern-matching (module GHC.HsToCore.Match.Literal)
instance (Eq (XXOverLit p)) => Eq (HsOverLit p) where
  (OverLit XOverLit p
_ OverLitVal
val1) == :: HsOverLit p -> HsOverLit p -> Bool
== (OverLit XOverLit p
_ OverLitVal
val2) = OverLitVal
val1 OverLitVal -> OverLitVal -> Bool
forall a. Eq a => a -> a -> Bool
== OverLitVal
val2
  (XOverLit  XXOverLit p
val1) == (XOverLit  XXOverLit p
val2) = XXOverLit p
val1 XXOverLit p -> XXOverLit p -> Bool
forall a. Eq a => a -> a -> Bool
== XXOverLit p
val2
  HsOverLit p
_ == HsOverLit p
_ = String -> Bool
forall a. HasCallStack => String -> a
panic String
"Eq HsOverLit"