{-# language DeriveFunctor, DeriveFoldable, DeriveTraversable #-}
{-# language OverloadedStrings #-}
{-# language LambdaCase #-}
{-# language TemplateHaskell #-}
module Language.Python.Syntax.Strings
(
PyChar(..)
, fromHaskellString
, QuoteType(..)
, StringType(..)
, StringPrefix(..)
, RawStringPrefix(..)
, BytesPrefix(..)
, RawBytesPrefix(..)
, hasPrefix
, StringLiteral(..)
, stringLiteralStringType
, stringLiteralQuoteType
, stringLiteralValue
, stringLiteralWhitespace
, showQuoteType
, showStringPrefix
, showRawStringPrefix
, showBytesPrefix
, showRawBytesPrefix
, isEscape
)
where
import Control.Lens.Lens (lens)
import Control.Lens.TH (makeLensesFor)
import Data.Digit.Octal (OctDigit)
import Data.Digit.Hexadecimal.MixedCase (HeXDigit(..))
import Data.Maybe (isJust)
import Data.Text (Text)
import Language.Python.Syntax.Whitespace
data QuoteType
= SingleQuote
| DoubleQuote
deriving (Eq, Ord, Show)
data StringType
= ShortString
| LongString
deriving (Eq, Ord, Show)
data StringPrefix
= Prefix_u
| Prefix_U
deriving (Eq, Ord, Show)
data RawStringPrefix
= Prefix_r
| Prefix_R
deriving (Eq, Ord, Show)
data BytesPrefix
= Prefix_b
| Prefix_B
deriving (Eq, Ord, Show)
data RawBytesPrefix
= Prefix_br
| Prefix_Br
| Prefix_bR
| Prefix_BR
| Prefix_rb
| Prefix_rB
| Prefix_Rb
| Prefix_RB
deriving (Eq, Ord, Show)
hasPrefix :: StringLiteral a -> Bool
hasPrefix RawStringLiteral{} = True
hasPrefix RawBytesLiteral{} = True
hasPrefix (StringLiteral _ a _ _ _ _) = isJust a
hasPrefix BytesLiteral{} = True
data StringLiteral a
= RawStringLiteral
{ _stringLiteralAnn :: a
, _unsafeRawStringLiteralPrefix :: RawStringPrefix
, _stringLiteralStringType :: StringType
, _stringLiteralQuoteType :: QuoteType
, _stringLiteralValue :: [PyChar]
, _stringLiteralWhitespace :: [Whitespace]
}
| StringLiteral
{ _stringLiteralAnn :: a
, _unsafeStringLiteralPrefix :: Maybe StringPrefix
, _stringLiteralStringType :: StringType
, _stringLiteralQuoteType :: QuoteType
, _stringLiteralValue :: [PyChar]
, _stringLiteralWhitespace :: [Whitespace]
}
| RawBytesLiteral
{ _stringLiteralAnn :: a
, _unsafeRawBytesLiteralPrefix :: RawBytesPrefix
, _stringLiteralStringType :: StringType
, _stringLiteralQuoteType :: QuoteType
, _stringLiteralValue :: [PyChar]
, _stringLiteralWhitespace :: [Whitespace]
}
| BytesLiteral
{ _stringLiteralAnn :: a
, _unsafeBytesLiteralPrefix :: BytesPrefix
, _stringLiteralStringType :: StringType
, _stringLiteralQuoteType :: QuoteType
, _stringLiteralValue :: [PyChar]
, _stringLiteralWhitespace :: [Whitespace]
}
deriving (Eq, Ord, Show, Functor, Foldable, Traversable)
instance HasTrailingWhitespace (StringLiteral a) where
trailingWhitespace =
lens
(\case
RawStringLiteral _ _ _ _ _ ws -> ws
StringLiteral _ _ _ _ _ ws -> ws
RawBytesLiteral _ _ _ _ _ ws -> ws
BytesLiteral _ _ _ _ _ ws -> ws)
(\s ws -> case s of
StringLiteral a b c d e _ -> StringLiteral a b c d e ws
RawStringLiteral a b c d e _ -> RawStringLiteral a b c d e ws
BytesLiteral a b c d e _ -> BytesLiteral a b c d e ws
RawBytesLiteral a b c d e _ -> RawBytesLiteral a b c d e ws)
data PyChar
= Char_newline
| Char_octal1 OctDigit
| Char_octal2 OctDigit OctDigit
| Char_octal3 OctDigit OctDigit OctDigit
| Char_hex HeXDigit HeXDigit
| Char_uni16
HeXDigit
HeXDigit
HeXDigit
HeXDigit
| Char_uni32
HeXDigit
HeXDigit
HeXDigit
HeXDigit
HeXDigit
HeXDigit
HeXDigit
HeXDigit
| Char_esc_bslash
| Char_esc_singlequote
| Char_esc_doublequote
| Char_esc_a
| Char_esc_b
| Char_esc_f
| Char_esc_n
| Char_esc_r
| Char_esc_t
| Char_esc_v
| Char_lit Char
deriving (Eq, Ord, Show)
isEscape :: PyChar -> Bool
isEscape c =
case c of
Char_newline -> True
Char_octal1{} -> True
Char_octal2{} -> True
Char_octal3{} -> True
Char_hex{} -> True
Char_uni16{} -> True
Char_uni32{} -> True
Char_esc_bslash -> True
Char_esc_singlequote -> True
Char_esc_doublequote -> True
Char_esc_a -> True
Char_esc_b -> True
Char_esc_f -> True
Char_esc_n -> True
Char_esc_r -> True
Char_esc_t -> True
Char_esc_v -> True
Char_lit{} -> False
fromHaskellString :: String -> [PyChar]
fromHaskellString =
fmap
(\c -> case c of
'\\' -> Char_esc_bslash
'\'' -> Char_esc_singlequote
'\"' -> Char_esc_doublequote
'\a' -> Char_esc_a
'\b' -> Char_esc_b
'\f' -> Char_esc_f
'\n' -> Char_esc_n
'\r' -> Char_esc_r
'\t' -> Char_esc_t
'\v' -> Char_esc_v
'\0' -> Char_hex HeXDigit0 HeXDigit0
_ -> Char_lit c)
showStringPrefix :: StringPrefix -> Text
showStringPrefix sp =
case sp of
Prefix_u -> "u"
Prefix_U -> "U"
showRawStringPrefix :: RawStringPrefix -> Text
showRawStringPrefix sp =
case sp of
Prefix_r -> "r"
Prefix_R -> "R"
showBytesPrefix :: BytesPrefix -> Text
showBytesPrefix sp =
case sp of
Prefix_b -> "b"
Prefix_B -> "B"
showRawBytesPrefix :: RawBytesPrefix -> Text
showRawBytesPrefix sp =
case sp of
Prefix_br -> "br"
Prefix_Br -> "Br"
Prefix_bR -> "bR"
Prefix_BR -> "BR"
Prefix_rb -> "rb"
Prefix_rB -> "rB"
Prefix_Rb -> "Rb"
Prefix_RB -> "RB"
showQuoteType :: QuoteType -> Char
showQuoteType qt =
case qt of
DoubleQuote -> '\"'
SingleQuote -> '\''
makeLensesFor
[ ("_stringLiteralValue", "stringLiteralValue")
, ("_stringLiteralStringType", "stringLiteralStringType")
, ("_stringLiteralQuoteType", "stringLiteralQuoteType")
, ("_stringLiteralWhitespace", "stringLiteralWhitespace")
]
''StringLiteral