module Lexeme (
isLexCon, isLexVar, isLexId, isLexSym,
isLexConId, isLexConSym, isLexVarId, isLexVarSym,
startsVarSym, startsVarId, startsConSym, startsConId,
okVarOcc, okConOcc, okTcOcc,
okVarIdOcc, okVarSymOcc, okConIdOcc, okConSymOcc
) where
import GhcPrelude
import FastString
import Data.Char
import qualified Data.Set as Set
import GHC.Lexeme
isLexCon, isLexVar, isLexId, isLexSym :: FastString -> Bool
isLexConId, isLexConSym, isLexVarId, isLexVarSym :: FastString -> Bool
isLexCon :: FastString -> Bool
isLexCon cs :: FastString
cs = FastString -> Bool
isLexConId FastString
cs Bool -> Bool -> Bool
|| FastString -> Bool
isLexConSym FastString
cs
isLexVar :: FastString -> Bool
isLexVar cs :: FastString
cs = FastString -> Bool
isLexVarId FastString
cs Bool -> Bool -> Bool
|| FastString -> Bool
isLexVarSym FastString
cs
isLexId :: FastString -> Bool
isLexId cs :: FastString
cs = FastString -> Bool
isLexConId FastString
cs Bool -> Bool -> Bool
|| FastString -> Bool
isLexVarId FastString
cs
isLexSym :: FastString -> Bool
isLexSym cs :: FastString
cs = FastString -> Bool
isLexConSym FastString
cs Bool -> Bool -> Bool
|| FastString -> Bool
isLexVarSym FastString
cs
isLexConId :: FastString -> Bool
isLexConId cs :: FastString
cs
| FastString -> Bool
nullFS FastString
cs = Bool
False
| FastString
cs FastString -> FastString -> Bool
forall a. Eq a => a -> a -> Bool
== (String -> FastString
fsLit "[]") = Bool
True
| Bool
otherwise = Char -> Bool
startsConId (FastString -> Char
headFS FastString
cs)
isLexVarId :: FastString -> Bool
isLexVarId cs :: FastString
cs
| FastString -> Bool
nullFS FastString
cs = Bool
False
| Bool
otherwise = Char -> Bool
startsVarId (FastString -> Char
headFS FastString
cs)
isLexConSym :: FastString -> Bool
isLexConSym cs :: FastString
cs
| FastString -> Bool
nullFS FastString
cs = Bool
False
| FastString
cs FastString -> FastString -> Bool
forall a. Eq a => a -> a -> Bool
== (String -> FastString
fsLit "->") = Bool
True
| Bool
otherwise = Char -> Bool
startsConSym (FastString -> Char
headFS FastString
cs)
isLexVarSym :: FastString -> Bool
isLexVarSym fs :: FastString
fs
| FastString
fs FastString -> FastString -> Bool
forall a. Eq a => a -> a -> Bool
== (String -> FastString
fsLit "~R#") = Bool
True
| Bool
otherwise
= case (if FastString -> Bool
nullFS FastString
fs then [] else FastString -> String
unpackFS FastString
fs) of
[] -> Bool
False
(c :: Char
c:cs :: String
cs) -> Char -> Bool
startsVarSym Char
c Bool -> Bool -> Bool
&& (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
isVarSymChar String
cs
okVarOcc :: String -> Bool
okVarOcc :: String -> Bool
okVarOcc str :: String
str@(c :: Char
c:_)
| Char -> Bool
startsVarId Char
c
= String -> Bool
okVarIdOcc String
str
| Char -> Bool
startsVarSym Char
c
= String -> Bool
okVarSymOcc String
str
okVarOcc _ = Bool
False
okConOcc :: String -> Bool
okConOcc :: String -> Bool
okConOcc str :: String
str@(c :: Char
c:_)
| Char -> Bool
startsConId Char
c
= String -> Bool
okConIdOcc String
str
| Char -> Bool
startsConSym Char
c
= String -> Bool
okConSymOcc String
str
| String
str String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== "[]"
= Bool
True
okConOcc _ = Bool
False
okTcOcc :: String -> Bool
okTcOcc :: String -> Bool
okTcOcc "[]" = Bool
True
okTcOcc "->" = Bool
True
okTcOcc "~" = Bool
True
okTcOcc str :: String
str@(c :: Char
c:_)
| Char -> Bool
startsConId Char
c
= String -> Bool
okConIdOcc String
str
| Char -> Bool
startsConSym Char
c
= String -> Bool
okConSymOcc String
str
| Char -> Bool
startsVarSym Char
c
= String -> Bool
okVarSymOcc String
str
okTcOcc _ = Bool
False
okVarIdOcc :: String -> Bool
okVarIdOcc :: String -> Bool
okVarIdOcc str :: String
str = String -> Bool
okIdOcc String
str Bool -> Bool -> Bool
&&
(String
str String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== "_" Bool -> Bool -> Bool
|| Bool -> Bool
not (String
str String -> Set String -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set String
reservedIds))
okVarSymOcc :: String -> Bool
okVarSymOcc :: String -> Bool
okVarSymOcc str :: String
str = (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
okSymChar String
str Bool -> Bool -> Bool
&&
Bool -> Bool
not (String
str String -> Set String -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set String
reservedOps) Bool -> Bool -> Bool
&&
Bool -> Bool
not (String -> Bool
isDashes String
str)
okConIdOcc :: String -> Bool
okConIdOcc :: String -> Bool
okConIdOcc str :: String
str = String -> Bool
okIdOcc String
str Bool -> Bool -> Bool
||
Bool -> String -> Bool
is_tuple_name1 Bool
True String
str Bool -> Bool -> Bool
||
Bool -> String -> Bool
is_tuple_name1 Bool
False String
str Bool -> Bool -> Bool
||
String -> Bool
is_sum_name1 String
str
where
is_tuple_name1 :: Bool -> String -> Bool
is_tuple_name1 True ('(' : rest :: String
rest) = Bool -> String -> Bool
is_tuple_name2 Bool
True String
rest
is_tuple_name1 False ('(' : '#' : rest :: String
rest) = Bool -> String -> Bool
is_tuple_name2 Bool
False String
rest
is_tuple_name1 _ _ = Bool
False
is_tuple_name2 :: Bool -> String -> Bool
is_tuple_name2 True ")" = Bool
True
is_tuple_name2 False "#)" = Bool
True
is_tuple_name2 boxed :: Bool
boxed (',' : rest :: String
rest) = Bool -> String -> Bool
is_tuple_name2 Bool
boxed String
rest
is_tuple_name2 boxed :: Bool
boxed (ws :: Char
ws : rest :: String
rest)
| Char -> Bool
isSpace Char
ws = Bool -> String -> Bool
is_tuple_name2 Bool
boxed String
rest
is_tuple_name2 _ _ = Bool
False
is_sum_name1 :: String -> Bool
is_sum_name1 ('(' : '#' : rest :: String
rest) = Bool -> String -> Bool
is_sum_name2 Bool
False String
rest
is_sum_name1 _ = Bool
False
is_sum_name2 :: Bool -> String -> Bool
is_sum_name2 _ "#)" = Bool
True
is_sum_name2 underscore :: Bool
underscore ('|' : rest :: String
rest) = Bool -> String -> Bool
is_sum_name2 Bool
underscore String
rest
is_sum_name2 False ('_' : rest :: String
rest) = Bool -> String -> Bool
is_sum_name2 Bool
True String
rest
is_sum_name2 underscore :: Bool
underscore (ws :: Char
ws : rest :: String
rest)
| Char -> Bool
isSpace Char
ws = Bool -> String -> Bool
is_sum_name2 Bool
underscore String
rest
is_sum_name2 _ _ = Bool
False
okConSymOcc :: String -> Bool
okConSymOcc :: String -> Bool
okConSymOcc ":" = Bool
True
okConSymOcc str :: String
str = (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
okSymChar String
str Bool -> Bool -> Bool
&&
Bool -> Bool
not (String
str String -> Set String -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set String
reservedOps)
okIdOcc :: String -> Bool
okIdOcc :: String -> Bool
okIdOcc str :: String
str
= let hashes :: String
hashes = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
okIdChar String
str in
(Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '#') String
hashes
okIdChar :: Char -> Bool
okIdChar :: Char -> Bool
okIdChar c :: Char
c = case Char -> GeneralCategory
generalCategory Char
c of
UppercaseLetter -> Bool
True
LowercaseLetter -> Bool
True
TitlecaseLetter -> Bool
True
ModifierLetter -> Bool
True
OtherLetter -> Bool
True
NonSpacingMark -> Bool
True
DecimalNumber -> Bool
True
OtherNumber -> Bool
True
_ -> Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '\'' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '_'
reservedIds :: Set.Set String
reservedIds :: Set String
reservedIds = [String] -> Set String
forall a. Ord a => [a] -> Set a
Set.fromList [ "case", "class", "data", "default", "deriving"
, "do", "else", "foreign", "if", "import", "in"
, "infix", "infixl", "infixr", "instance", "let"
, "module", "newtype", "of", "then", "type", "where"
, "_" ]
reservedOps :: Set.Set String
reservedOps :: Set String
reservedOps = [String] -> Set String
forall a. Ord a => [a] -> Set a
Set.fromList [ "..", ":", "::", "=", "\\", "|", "<-", "->"
, "@", "~", "=>" ]
isDashes :: String -> Bool
isDashes :: String -> Bool
isDashes ('-' : '-' : rest :: String
rest) = (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '-') String
rest
isDashes _ = Bool
False