-- Copyright 2019 Google LLC
--
-- Use of this source code is governed by a BSD-style
-- license that can be found in the LICENSE file or at
-- https://developers.google.com/open-source/licenses/bsd

-- | This module provides combinators for constructing Haskell literals,
-- which may be used in either patterns or expressions.
{-# LANGUAGE CPP #-}
module GHC.SourceGen.Lit
    ( HsLit'
    , HsOverLit'
    , HasLit(..)
    , char
    , string
    , int
    , frac
    ) where

#if MIN_VERSION_ghc(9,2,0)
import GHC.Types.SourceText (mkTHFractionalLit, mkIntegralLit)
import GHC.Data.FastString (fsLit)
#elif MIN_VERSION_ghc(9,0,0)
import GHC.Types.Basic (mkFractionalLit, mkIntegralLit)
import GHC.Data.FastString (fsLit)
#else
import BasicTypes (mkFractionalLit, mkIntegralLit)
import FastString (fsLit)
#endif
import GHC.Hs.Lit
import GHC.Hs.Expr (noExpr, noSyntaxExpr, HsExpr(..))
import GHC.Hs.Pat (Pat(..))

import GHC.SourceGen.Lit.Internal
import GHC.SourceGen.Syntax.Internal

class HasLit e where
    lit :: HsLit' -> e
    overLit :: HsOverLit' -> e

instance HasLit HsExpr' where
    lit :: HsLit' -> HsExpr'
lit = forall ann a. (EpAnn ann -> a) -> a
withEpAnnNotUsed forall p. XLitE p -> HsLit p -> HsExpr p
HsLit
    overLit :: HsOverLit' -> HsExpr'
overLit = forall ann a. (EpAnn ann -> a) -> a
withEpAnnNotUsed forall p. XOverLitE p -> HsOverLit p -> HsExpr p
HsOverLit

instance HasLit Pat' where
    lit :: HsLit' -> Pat'
lit = forall a. (NoExtField -> a) -> a
noExt forall p. XLitPat p -> HsLit p -> Pat p
LitPat
    overLit :: HsOverLit' -> Pat'
overLit HsOverLit'
l = forall a. a -> a
withPlaceHolder
#if MIN_VERSION_ghc(9,4,0)
                    $ withEpAnnNotUsed NPat (mkLocated l) Nothing noSyntaxExpr
#else
                    forall a b. (a -> b) -> a -> b
$ forall ann a. (EpAnn ann -> a) -> a
withEpAnnNotUsed forall p.
XNPat p
-> XRec p (HsOverLit p)
-> Maybe (SyntaxExpr p)
-> SyntaxExpr p
-> Pat p
NPat (forall e. e -> Located e
builtLoc HsOverLit'
l) forall a. Maybe a
Nothing forall (p :: Pass). IsPass p => SyntaxExpr (GhcPass p)
noSyntaxExpr
#endif

char :: HasLit e => Char -> e
char :: forall e. HasLit e => Char -> e
char = forall e. HasLit e => HsLit' -> e
lit forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (SourceText -> a) -> a
noSourceText forall x. XHsChar x -> Char -> HsLit x
HsChar

string :: HasLit e => String -> e
string :: forall e. HasLit e => String -> e
string = forall e. HasLit e => HsLit' -> e
lit forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (SourceText -> a) -> a
noSourceText forall x. XHsString x -> FastString -> HsLit x
HsString forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> FastString
fsLit

-- | Note: this is an *overloaded* integer.
int :: HasLit e => Integer -> e
#if MIN_VERSION_ghc(9,4,0)
int n = overLit $ withPlaceHolder $ withPlaceHolder (noExt OverLit n')
#else
int :: forall e. HasLit e => Integer -> e
int Integer
n = forall e. HasLit e => HsOverLit' -> e
overLit forall a b. (a -> b) -> a -> b
$ forall a. a -> a
withPlaceHolder forall a b. (a -> b) -> a -> b
$ forall a. a -> a
withPlaceHolder (forall a. (NoExtField -> a) -> a
noExt forall p. XOverLit p -> OverLitVal -> HsExpr p -> HsOverLit p
OverLit OverLitVal
n') forall (p :: Pass). HsExpr (GhcPass p)
noExpr
#endif
  where
    n' :: OverLitVal
n' = IntegralLit -> OverLitVal
HsIntegral forall a b. (a -> b) -> a -> b
$ forall a. Integral a => a -> IntegralLit
mkIntegralLit Integer
n

-- | Note: this is an *overloaded* rational, e.g., a decimal number.
frac :: HasLit e => Rational -> e
#if MIN_VERSION_ghc(9,4,0)
frac x = overLit $ withPlaceHolder $ withPlaceHolder (noExt OverLit $ HsFractional x')
#else
frac :: forall e. HasLit e => Rational -> e
frac Rational
x = forall e. HasLit e => HsOverLit' -> e
overLit forall a b. (a -> b) -> a -> b
$ forall a. a -> a
withPlaceHolder forall a b. (a -> b) -> a -> b
$ forall a. a -> a
withPlaceHolder (forall a. (NoExtField -> a) -> a
noExt forall p. XOverLit p -> OverLitVal -> HsExpr p -> HsOverLit p
OverLit forall a b. (a -> b) -> a -> b
$ FractionalLit -> OverLitVal
HsFractional FractionalLit
x') forall (p :: Pass). HsExpr (GhcPass p)
noExpr
#endif
  where
#if MIN_VERSION_ghc(9,2,0)
    x' :: FractionalLit
x' = Rational -> FractionalLit
mkTHFractionalLit Rational
x
#else
    x' = mkFractionalLit x
#endif