-----------------------------------------------------------------------------
-- |
-- Module      :  GHC.Lexeme
-- Copyright   :  (c) The GHC Team
--
-- Maintainer  :  ghc-devs@haskell.org
-- Portability :  portable
--
-- Functions to evaluate whether or not a string is a valid identifier.
--
module GHC.Lexeme (
          -- * Lexical characteristics of Haskell names
        startsVarSym, startsVarId, startsConSym, startsConId,
        startsVarSymASCII, isVarSymChar, okSymChar
  ) where

import Prelude -- See note [Why do we import Prelude here?]
import Data.Char

-- | Is this character acceptable in a symbol (after the first char)?
-- See alexGetByte in Lexer.x
okSymChar :: Char -> Bool
okSymChar :: Char -> Bool
okSymChar Char
c
  | Char
c Char -> [Char] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Char]
"(),;[]`{}_\"'"
  = Bool
False
  | Bool
otherwise
  = case Char -> GeneralCategory
generalCategory Char
c of
      GeneralCategory
ConnectorPunctuation -> Bool
True
      GeneralCategory
DashPunctuation      -> Bool
True
      GeneralCategory
OtherPunctuation     -> Bool
True
      GeneralCategory
MathSymbol           -> Bool
True
      GeneralCategory
CurrencySymbol       -> Bool
True
      GeneralCategory
ModifierSymbol       -> Bool
True
      GeneralCategory
OtherSymbol          -> Bool
True
      GeneralCategory
_                    -> Bool
False

startsVarSym, startsVarId, startsConSym, startsConId :: Char -> Bool
startsVarSym :: Char -> Bool
startsVarSym Char
c = Char -> Bool
okSymChar Char
c Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
':' -- Infix Ids
startsConSym :: Char -> Bool
startsConSym Char
c = Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
':'                -- Infix data constructors
startsVarId :: Char -> Bool
startsVarId Char
c  = Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'_' Bool -> Bool -> Bool
|| case Char -> GeneralCategory
generalCategory Char
c of  -- Ordinary Ids
  GeneralCategory
LowercaseLetter -> Bool
True
  GeneralCategory
OtherLetter     -> Bool
True   -- See #1103
  GeneralCategory
_               -> Bool
False
startsConId :: Char -> Bool
startsConId Char
c  = Char -> Bool
isUpper Char
c Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'('  -- Ordinary type constructors and data constructors

startsVarSymASCII :: Char -> Bool
startsVarSymASCII :: Char -> Bool
startsVarSymASCII Char
c = Char
c Char -> [Char] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Char]
"!#$%&*+./<=>?@\\^|~-"

isVarSymChar :: Char -> Bool
isVarSymChar :: Char -> Bool
isVarSymChar Char
c = Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
':' Bool -> Bool -> Bool
|| Char -> Bool
startsVarSym Char
c