-----------------------------------------------------------------------------
-- |
-- 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 c :: Char
c
  | Char
c Char -> [Char] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` "(),;[]`{}_\"'"
  = Bool
False
  | Bool
otherwise
  = case Char -> GeneralCategory
generalCategory Char
c of
      ConnectorPunctuation -> Bool
True
      DashPunctuation      -> Bool
True
      OtherPunctuation     -> Bool
True
      MathSymbol           -> Bool
True
      CurrencySymbol       -> Bool
True
      ModifierSymbol       -> Bool
True
      OtherSymbol          -> Bool
True
      _                    -> Bool
False

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

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

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