-- |
-- Module      :  Cryptol.Utils.Ident
-- Copyright   :  (c) 2015-2016 Galois, Inc.
-- License     :  BSD3
-- Maintainer  :  cryptol@galois.com
-- Stability   :  provisional
-- Portability :  portable

{-# LANGUAGE DeriveGeneric, OverloadedStrings #-}
{-# LANGUAGE DeriveAnyClass #-}

module Cryptol.Utils.Ident
  ( -- * Module names
    ModPath(..)
  , apPathRoot
  , modPathCommon
  , topModuleFor
  , modPathSplit

  , ModName
  , modNameToText
  , textToModName
  , modNameChunks
  , packModName
  , preludeName
  , preludeReferenceName
  , floatName
  , suiteBName
  , arrayName
  , primeECName
  , interactiveName
  , noModuleName
  , exprModName

  , isParamInstModName
  , paramInstModName
  , notParamInstModName

    -- * Identifiers
  , Ident
  , packIdent
  , packInfix
  , unpackIdent
  , mkIdent
  , mkInfix
  , isInfixIdent
  , nullIdent
  , identText
  , modParamIdent

    -- * Namespaces
  , Namespace(..)
  , allNamespaces

    -- * Original names
  , OrigName(..)

    -- * Identifiers for primitives
  , PrimIdent(..)
  , prelPrim
  , floatPrim
  , arrayPrim
  , suiteBPrim
  , primeECPrim
  ) where

import           Control.DeepSeq (NFData)
import           Data.Char (isSpace)
import           Data.List (unfoldr)
import qualified Data.Text as T
import           Data.String (IsString(..))
import           GHC.Generics (Generic)


--------------------------------------------------------------------------------

-- | Namespaces for names
data Namespace = NSValue | NSType | NSModule
  deriving ((forall x. Namespace -> Rep Namespace x)
-> (forall x. Rep Namespace x -> Namespace) -> Generic Namespace
forall x. Rep Namespace x -> Namespace
forall x. Namespace -> Rep Namespace x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Namespace x -> Namespace
$cfrom :: forall x. Namespace -> Rep Namespace x
Generic,Int -> Namespace -> ShowS
[Namespace] -> ShowS
Namespace -> String
(Int -> Namespace -> ShowS)
-> (Namespace -> String)
-> ([Namespace] -> ShowS)
-> Show Namespace
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Namespace] -> ShowS
$cshowList :: [Namespace] -> ShowS
show :: Namespace -> String
$cshow :: Namespace -> String
showsPrec :: Int -> Namespace -> ShowS
$cshowsPrec :: Int -> Namespace -> ShowS
Show,Namespace -> ()
(Namespace -> ()) -> NFData Namespace
forall a. (a -> ()) -> NFData a
rnf :: Namespace -> ()
$crnf :: Namespace -> ()
NFData,Namespace -> Namespace -> Bool
(Namespace -> Namespace -> Bool)
-> (Namespace -> Namespace -> Bool) -> Eq Namespace
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Namespace -> Namespace -> Bool
$c/= :: Namespace -> Namespace -> Bool
== :: Namespace -> Namespace -> Bool
$c== :: Namespace -> Namespace -> Bool
Eq,Eq Namespace
Eq Namespace
-> (Namespace -> Namespace -> Ordering)
-> (Namespace -> Namespace -> Bool)
-> (Namespace -> Namespace -> Bool)
-> (Namespace -> Namespace -> Bool)
-> (Namespace -> Namespace -> Bool)
-> (Namespace -> Namespace -> Namespace)
-> (Namespace -> Namespace -> Namespace)
-> Ord Namespace
Namespace -> Namespace -> Bool
Namespace -> Namespace -> Ordering
Namespace -> Namespace -> Namespace
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Namespace -> Namespace -> Namespace
$cmin :: Namespace -> Namespace -> Namespace
max :: Namespace -> Namespace -> Namespace
$cmax :: Namespace -> Namespace -> Namespace
>= :: Namespace -> Namespace -> Bool
$c>= :: Namespace -> Namespace -> Bool
> :: Namespace -> Namespace -> Bool
$c> :: Namespace -> Namespace -> Bool
<= :: Namespace -> Namespace -> Bool
$c<= :: Namespace -> Namespace -> Bool
< :: Namespace -> Namespace -> Bool
$c< :: Namespace -> Namespace -> Bool
compare :: Namespace -> Namespace -> Ordering
$ccompare :: Namespace -> Namespace -> Ordering
$cp1Ord :: Eq Namespace
Ord,Int -> Namespace
Namespace -> Int
Namespace -> [Namespace]
Namespace -> Namespace
Namespace -> Namespace -> [Namespace]
Namespace -> Namespace -> Namespace -> [Namespace]
(Namespace -> Namespace)
-> (Namespace -> Namespace)
-> (Int -> Namespace)
-> (Namespace -> Int)
-> (Namespace -> [Namespace])
-> (Namespace -> Namespace -> [Namespace])
-> (Namespace -> Namespace -> [Namespace])
-> (Namespace -> Namespace -> Namespace -> [Namespace])
-> Enum Namespace
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Namespace -> Namespace -> Namespace -> [Namespace]
$cenumFromThenTo :: Namespace -> Namespace -> Namespace -> [Namespace]
enumFromTo :: Namespace -> Namespace -> [Namespace]
$cenumFromTo :: Namespace -> Namespace -> [Namespace]
enumFromThen :: Namespace -> Namespace -> [Namespace]
$cenumFromThen :: Namespace -> Namespace -> [Namespace]
enumFrom :: Namespace -> [Namespace]
$cenumFrom :: Namespace -> [Namespace]
fromEnum :: Namespace -> Int
$cfromEnum :: Namespace -> Int
toEnum :: Int -> Namespace
$ctoEnum :: Int -> Namespace
pred :: Namespace -> Namespace
$cpred :: Namespace -> Namespace
succ :: Namespace -> Namespace
$csucc :: Namespace -> Namespace
Enum,Namespace
Namespace -> Namespace -> Bounded Namespace
forall a. a -> a -> Bounded a
maxBound :: Namespace
$cmaxBound :: Namespace
minBound :: Namespace
$cminBound :: Namespace
Bounded)

allNamespaces :: [Namespace]
allNamespaces :: [Namespace]
allNamespaces = [ Namespace
forall a. Bounded a => a
minBound .. Namespace
forall a. Bounded a => a
maxBound ]

-- | Idnetifies a possibly nested module
data ModPath  = TopModule ModName
              | Nested ModPath Ident
                deriving (ModPath -> ModPath -> Bool
(ModPath -> ModPath -> Bool)
-> (ModPath -> ModPath -> Bool) -> Eq ModPath
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ModPath -> ModPath -> Bool
$c/= :: ModPath -> ModPath -> Bool
== :: ModPath -> ModPath -> Bool
$c== :: ModPath -> ModPath -> Bool
Eq,Eq ModPath
Eq ModPath
-> (ModPath -> ModPath -> Ordering)
-> (ModPath -> ModPath -> Bool)
-> (ModPath -> ModPath -> Bool)
-> (ModPath -> ModPath -> Bool)
-> (ModPath -> ModPath -> Bool)
-> (ModPath -> ModPath -> ModPath)
-> (ModPath -> ModPath -> ModPath)
-> Ord ModPath
ModPath -> ModPath -> Bool
ModPath -> ModPath -> Ordering
ModPath -> ModPath -> ModPath
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ModPath -> ModPath -> ModPath
$cmin :: ModPath -> ModPath -> ModPath
max :: ModPath -> ModPath -> ModPath
$cmax :: ModPath -> ModPath -> ModPath
>= :: ModPath -> ModPath -> Bool
$c>= :: ModPath -> ModPath -> Bool
> :: ModPath -> ModPath -> Bool
$c> :: ModPath -> ModPath -> Bool
<= :: ModPath -> ModPath -> Bool
$c<= :: ModPath -> ModPath -> Bool
< :: ModPath -> ModPath -> Bool
$c< :: ModPath -> ModPath -> Bool
compare :: ModPath -> ModPath -> Ordering
$ccompare :: ModPath -> ModPath -> Ordering
$cp1Ord :: Eq ModPath
Ord,Int -> ModPath -> ShowS
[ModPath] -> ShowS
ModPath -> String
(Int -> ModPath -> ShowS)
-> (ModPath -> String) -> ([ModPath] -> ShowS) -> Show ModPath
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ModPath] -> ShowS
$cshowList :: [ModPath] -> ShowS
show :: ModPath -> String
$cshow :: ModPath -> String
showsPrec :: Int -> ModPath -> ShowS
$cshowsPrec :: Int -> ModPath -> ShowS
Show,(forall x. ModPath -> Rep ModPath x)
-> (forall x. Rep ModPath x -> ModPath) -> Generic ModPath
forall x. Rep ModPath x -> ModPath
forall x. ModPath -> Rep ModPath x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ModPath x -> ModPath
$cfrom :: forall x. ModPath -> Rep ModPath x
Generic,ModPath -> ()
(ModPath -> ()) -> NFData ModPath
forall a. (a -> ()) -> NFData a
rnf :: ModPath -> ()
$crnf :: ModPath -> ()
NFData)

apPathRoot :: (ModName -> ModName) -> ModPath -> ModPath
apPathRoot :: (ModName -> ModName) -> ModPath -> ModPath
apPathRoot ModName -> ModName
f ModPath
path =
  case ModPath
path of
    TopModule ModName
m -> ModName -> ModPath
TopModule (ModName -> ModName
f ModName
m)
    Nested ModPath
p Ident
q  -> ModPath -> Ident -> ModPath
Nested ((ModName -> ModName) -> ModPath -> ModPath
apPathRoot ModName -> ModName
f ModPath
p) Ident
q

topModuleFor :: ModPath -> ModName
topModuleFor :: ModPath -> ModName
topModuleFor ModPath
m =
  case ModPath
m of
    TopModule ModName
x -> ModName
x
    Nested ModPath
p Ident
_ -> ModPath -> ModName
topModuleFor ModPath
p

-- | Compute a common prefix between two module paths, if any.
-- This is basically "anti-unification" of the two paths, where we
-- compute the longest common prefix, and the remaining differences for
-- each module.
modPathCommon :: ModPath -> ModPath -> Maybe (ModPath, [Ident], [Ident])
modPathCommon :: ModPath -> ModPath -> Maybe (ModPath, [Ident], [Ident])
modPathCommon ModPath
p1 ModPath
p2
  | ModName
top1 ModName -> ModName -> Bool
forall a. Eq a => a -> a -> Bool
== ModName
top2 = (ModPath, [Ident], [Ident]) -> Maybe (ModPath, [Ident], [Ident])
forall a. a -> Maybe a
Just (ModPath -> [Ident] -> [Ident] -> (ModPath, [Ident], [Ident])
findCommon (ModName -> ModPath
TopModule ModName
top1) [Ident]
as [Ident]
bs)
  | Bool
otherwise    = Maybe (ModPath, [Ident], [Ident])
forall a. Maybe a
Nothing
  where
  (ModName
top1,[Ident]
as) = ModPath -> (ModName, [Ident])
modPathSplit ModPath
p1
  (ModName
top2,[Ident]
bs) = ModPath -> (ModName, [Ident])
modPathSplit ModPath
p2

  findCommon :: ModPath -> [Ident] -> [Ident] -> (ModPath, [Ident], [Ident])
findCommon ModPath
com [Ident]
xs [Ident]
ys =
    case ([Ident]
xs,[Ident]
ys) of
      (Ident
x:[Ident]
xs',Ident
y:[Ident]
ys') | Ident
x Ident -> Ident -> Bool
forall a. Eq a => a -> a -> Bool
== Ident
y -> ModPath -> [Ident] -> [Ident] -> (ModPath, [Ident], [Ident])
findCommon (ModPath -> Ident -> ModPath
Nested ModPath
com Ident
x) [Ident]
xs' [Ident]
ys'
      ([Ident], [Ident])
_                      -> (ModPath
com, [Ident]
xs, [Ident]
ys)

modPathSplit :: ModPath -> (ModName, [Ident])
modPathSplit :: ModPath -> (ModName, [Ident])
modPathSplit ModPath
p0 = (ModName
top,[Ident] -> [Ident]
forall a. [a] -> [a]
reverse [Ident]
xs)
  where
  (ModName
top,[Ident]
xs) = ModPath -> (ModName, [Ident])
go ModPath
p0
  go :: ModPath -> (ModName, [Ident])
go ModPath
p =
    case ModPath
p of
      TopModule ModName
a -> (ModName
a, [])
      Nested ModPath
b Ident
i  -> (ModName
a, Ident
iIdent -> [Ident] -> [Ident]
forall a. a -> [a] -> [a]
:[Ident]
bs)
        where (ModName
a,[Ident]
bs) = ModPath -> (ModName, [Ident])
go ModPath
b




--------------------------------------------------------------------------------
-- | Top-level Module names are just text.
data ModName = ModName T.Text
  deriving (ModName -> ModName -> Bool
(ModName -> ModName -> Bool)
-> (ModName -> ModName -> Bool) -> Eq ModName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ModName -> ModName -> Bool
$c/= :: ModName -> ModName -> Bool
== :: ModName -> ModName -> Bool
$c== :: ModName -> ModName -> Bool
Eq,Eq ModName
Eq ModName
-> (ModName -> ModName -> Ordering)
-> (ModName -> ModName -> Bool)
-> (ModName -> ModName -> Bool)
-> (ModName -> ModName -> Bool)
-> (ModName -> ModName -> Bool)
-> (ModName -> ModName -> ModName)
-> (ModName -> ModName -> ModName)
-> Ord ModName
ModName -> ModName -> Bool
ModName -> ModName -> Ordering
ModName -> ModName -> ModName
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ModName -> ModName -> ModName
$cmin :: ModName -> ModName -> ModName
max :: ModName -> ModName -> ModName
$cmax :: ModName -> ModName -> ModName
>= :: ModName -> ModName -> Bool
$c>= :: ModName -> ModName -> Bool
> :: ModName -> ModName -> Bool
$c> :: ModName -> ModName -> Bool
<= :: ModName -> ModName -> Bool
$c<= :: ModName -> ModName -> Bool
< :: ModName -> ModName -> Bool
$c< :: ModName -> ModName -> Bool
compare :: ModName -> ModName -> Ordering
$ccompare :: ModName -> ModName -> Ordering
$cp1Ord :: Eq ModName
Ord,Int -> ModName -> ShowS
[ModName] -> ShowS
ModName -> String
(Int -> ModName -> ShowS)
-> (ModName -> String) -> ([ModName] -> ShowS) -> Show ModName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ModName] -> ShowS
$cshowList :: [ModName] -> ShowS
show :: ModName -> String
$cshow :: ModName -> String
showsPrec :: Int -> ModName -> ShowS
$cshowsPrec :: Int -> ModName -> ShowS
Show,(forall x. ModName -> Rep ModName x)
-> (forall x. Rep ModName x -> ModName) -> Generic ModName
forall x. Rep ModName x -> ModName
forall x. ModName -> Rep ModName x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ModName x -> ModName
$cfrom :: forall x. ModName -> Rep ModName x
Generic)

instance NFData ModName

modNameToText :: ModName -> T.Text
modNameToText :: ModName -> Text
modNameToText (ModName Text
x) = Text
x

textToModName :: T.Text -> ModName
textToModName :: Text -> ModName
textToModName = Text -> ModName
ModName

modNameChunks :: ModName -> [String]
modNameChunks :: ModName -> [String]
modNameChunks  = (Text -> Maybe (String, Text)) -> Text -> [String]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
unfoldr Text -> Maybe (String, Text)
step (Text -> [String]) -> (ModName -> Text) -> ModName -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ModName -> Text
modNameToText (ModName -> Text) -> (ModName -> ModName) -> ModName -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ModName -> ModName
notParamInstModName
  where
  step :: Text -> Maybe (String, Text)
step Text
str
    | Text -> Bool
T.null Text
str = Maybe (String, Text)
forall a. Maybe a
Nothing
    | Bool
otherwise  = case Text -> Text -> (Text, Text)
T.breakOn Text
modSep Text
str of
                     (Text
a,Text
b) -> (String, Text) -> Maybe (String, Text)
forall a. a -> Maybe a
Just (Text -> String
T.unpack Text
a,Int -> Text -> Text
T.drop (Text -> Int
T.length Text
modSep) Text
b)

isParamInstModName :: ModName -> Bool
isParamInstModName :: ModName -> Bool
isParamInstModName (ModName Text
x) = Text
modInstPref Text -> Text -> Bool
`T.isPrefixOf` Text
x

-- | Convert a parameterized module's name to the name of the module
-- containing the same definitions but with explicit parameters on each
-- definition.
paramInstModName :: ModName -> ModName
paramInstModName :: ModName -> ModName
paramInstModName (ModName Text
x)
  | Text
modInstPref Text -> Text -> Bool
`T.isPrefixOf` Text
x = Text -> ModName
ModName Text
x
  | Bool
otherwise = Text -> ModName
ModName (Text -> Text -> Text
T.append Text
modInstPref Text
x)


notParamInstModName :: ModName -> ModName
notParamInstModName :: ModName -> ModName
notParamInstModName (ModName Text
x)
  | Text
modInstPref Text -> Text -> Bool
`T.isPrefixOf` Text
x = Text -> ModName
ModName (Int -> Text -> Text
T.drop (Text -> Int
T.length Text
modInstPref) Text
x)
  | Bool
otherwise = Text -> ModName
ModName Text
x


packModName :: [T.Text] -> ModName
packModName :: [Text] -> ModName
packModName [Text]
strs = Text -> ModName
textToModName (Text -> [Text] -> Text
T.intercalate Text
modSep ((Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Text
trim [Text]
strs))
  where
  -- trim space off of the start and end of the string
  trim :: Text -> Text
trim Text
str = (Char -> Bool) -> Text -> Text
T.dropWhile Char -> Bool
isSpace ((Char -> Bool) -> Text -> Text
T.dropWhileEnd Char -> Bool
isSpace Text
str)

modSep :: T.Text
modSep :: Text
modSep  = Text
"::"

modInstPref :: T.Text
modInstPref :: Text
modInstPref = Text
"`"


preludeName :: ModName
preludeName :: ModName
preludeName  = [Text] -> ModName
packModName [Text
"Cryptol"]

preludeReferenceName :: ModName
preludeReferenceName :: ModName
preludeReferenceName = [Text] -> ModName
packModName [Text
"Cryptol",Text
"Reference"]

floatName :: ModName
floatName :: ModName
floatName = [Text] -> ModName
packModName [Text
"Float"]

arrayName :: ModName
arrayName :: ModName
arrayName  = [Text] -> ModName
packModName [Text
"Array"]

suiteBName :: ModName
suiteBName :: ModName
suiteBName = [Text] -> ModName
packModName [Text
"SuiteB"]

primeECName :: ModName
primeECName :: ModName
primeECName = [Text] -> ModName
packModName [Text
"PrimeEC"]

interactiveName :: ModName
interactiveName :: ModName
interactiveName  = [Text] -> ModName
packModName [Text
"<interactive>"]

noModuleName :: ModName
noModuleName :: ModName
noModuleName = [Text] -> ModName
packModName [Text
"<none>"]

exprModName :: ModName
exprModName :: ModName
exprModName = [Text] -> ModName
packModName [Text
"<expr>"]


--------------------------------------------------------------------------------
-- | Identifies an entitiy
data OrigName = OrigName
  { OrigName -> Namespace
ogNamespace :: Namespace
  , OrigName -> ModPath
ogModule    :: ModPath
  , OrigName -> Ident
ogName      :: Ident
  } deriving (OrigName -> OrigName -> Bool
(OrigName -> OrigName -> Bool)
-> (OrigName -> OrigName -> Bool) -> Eq OrigName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: OrigName -> OrigName -> Bool
$c/= :: OrigName -> OrigName -> Bool
== :: OrigName -> OrigName -> Bool
$c== :: OrigName -> OrigName -> Bool
Eq,Eq OrigName
Eq OrigName
-> (OrigName -> OrigName -> Ordering)
-> (OrigName -> OrigName -> Bool)
-> (OrigName -> OrigName -> Bool)
-> (OrigName -> OrigName -> Bool)
-> (OrigName -> OrigName -> Bool)
-> (OrigName -> OrigName -> OrigName)
-> (OrigName -> OrigName -> OrigName)
-> Ord OrigName
OrigName -> OrigName -> Bool
OrigName -> OrigName -> Ordering
OrigName -> OrigName -> OrigName
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: OrigName -> OrigName -> OrigName
$cmin :: OrigName -> OrigName -> OrigName
max :: OrigName -> OrigName -> OrigName
$cmax :: OrigName -> OrigName -> OrigName
>= :: OrigName -> OrigName -> Bool
$c>= :: OrigName -> OrigName -> Bool
> :: OrigName -> OrigName -> Bool
$c> :: OrigName -> OrigName -> Bool
<= :: OrigName -> OrigName -> Bool
$c<= :: OrigName -> OrigName -> Bool
< :: OrigName -> OrigName -> Bool
$c< :: OrigName -> OrigName -> Bool
compare :: OrigName -> OrigName -> Ordering
$ccompare :: OrigName -> OrigName -> Ordering
$cp1Ord :: Eq OrigName
Ord,Int -> OrigName -> ShowS
[OrigName] -> ShowS
OrigName -> String
(Int -> OrigName -> ShowS)
-> (OrigName -> String) -> ([OrigName] -> ShowS) -> Show OrigName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [OrigName] -> ShowS
$cshowList :: [OrigName] -> ShowS
show :: OrigName -> String
$cshow :: OrigName -> String
showsPrec :: Int -> OrigName -> ShowS
$cshowsPrec :: Int -> OrigName -> ShowS
Show,(forall x. OrigName -> Rep OrigName x)
-> (forall x. Rep OrigName x -> OrigName) -> Generic OrigName
forall x. Rep OrigName x -> OrigName
forall x. OrigName -> Rep OrigName x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep OrigName x -> OrigName
$cfrom :: forall x. OrigName -> Rep OrigName x
Generic,OrigName -> ()
(OrigName -> ()) -> NFData OrigName
forall a. (a -> ()) -> NFData a
rnf :: OrigName -> ()
$crnf :: OrigName -> ()
NFData)


--------------------------------------------------------------------------------

-- | Identifiers, along with a flag that indicates whether or not they're infix
-- operators. The boolean is present just as cached information from the lexer,
-- and never used during comparisons.
data Ident = Ident Bool T.Text
             deriving (Int -> Ident -> ShowS
[Ident] -> ShowS
Ident -> String
(Int -> Ident -> ShowS)
-> (Ident -> String) -> ([Ident] -> ShowS) -> Show Ident
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Ident] -> ShowS
$cshowList :: [Ident] -> ShowS
show :: Ident -> String
$cshow :: Ident -> String
showsPrec :: Int -> Ident -> ShowS
$cshowsPrec :: Int -> Ident -> ShowS
Show,(forall x. Ident -> Rep Ident x)
-> (forall x. Rep Ident x -> Ident) -> Generic Ident
forall x. Rep Ident x -> Ident
forall x. Ident -> Rep Ident x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Ident x -> Ident
$cfrom :: forall x. Ident -> Rep Ident x
Generic)

instance Eq Ident where
  Ident
a == :: Ident -> Ident -> Bool
== Ident
b = Ident -> Ident -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Ident
a Ident
b Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
EQ
  Ident
a /= :: Ident -> Ident -> Bool
/= Ident
b = Ident -> Ident -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Ident
a Ident
b Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
/= Ordering
EQ

instance Ord Ident where
  compare :: Ident -> Ident -> Ordering
compare (Ident Bool
_ Text
i1) (Ident Bool
_ Text
i2) = Text -> Text -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Text
i1 Text
i2

instance IsString Ident where
  fromString :: String -> Ident
fromString String
str = Text -> Ident
mkIdent (String -> Text
T.pack String
str)

instance NFData Ident

packIdent :: String -> Ident
packIdent :: String -> Ident
packIdent  = Text -> Ident
mkIdent (Text -> Ident) -> (String -> Text) -> String -> Ident
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack

packInfix :: String -> Ident
packInfix :: String -> Ident
packInfix  = Text -> Ident
mkInfix (Text -> Ident) -> (String -> Text) -> String -> Ident
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack

unpackIdent :: Ident -> String
unpackIdent :: Ident -> String
unpackIdent  = Text -> String
T.unpack (Text -> String) -> (Ident -> Text) -> Ident -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ident -> Text
identText

mkIdent :: T.Text -> Ident
mkIdent :: Text -> Ident
mkIdent  = Bool -> Text -> Ident
Ident Bool
False

mkInfix :: T.Text -> Ident
mkInfix :: Text -> Ident
mkInfix  = Bool -> Text -> Ident
Ident Bool
True

isInfixIdent :: Ident -> Bool
isInfixIdent :: Ident -> Bool
isInfixIdent (Ident Bool
b Text
_) = Bool
b

nullIdent :: Ident -> Bool
nullIdent :: Ident -> Bool
nullIdent (Ident Bool
_ Text
t) = Text -> Bool
T.null Text
t

identText :: Ident -> T.Text
identText :: Ident -> Text
identText (Ident Bool
_ Text
t) = Text
t

modParamIdent :: Ident -> Ident
modParamIdent :: Ident -> Ident
modParamIdent (Ident Bool
x Text
t) = Bool -> Text -> Ident
Ident Bool
x (Text -> Text -> Text
T.append (String -> Text
T.pack String
"module parameter ") Text
t)


--------------------------------------------------------------------------------

{- | A way to identify primitives: we used to use just 'Ident', but this
isn't good anymore as now we have primitives in multiple modules.
This is used as a key when we need to lookup details about a specific
primitive.  Also, this is intended to mostly be used internally, so
we don't store the fixity flag of the `Ident` -}
data PrimIdent = PrimIdent ModName T.Text
  deriving (PrimIdent -> PrimIdent -> Bool
(PrimIdent -> PrimIdent -> Bool)
-> (PrimIdent -> PrimIdent -> Bool) -> Eq PrimIdent
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PrimIdent -> PrimIdent -> Bool
$c/= :: PrimIdent -> PrimIdent -> Bool
== :: PrimIdent -> PrimIdent -> Bool
$c== :: PrimIdent -> PrimIdent -> Bool
Eq,Eq PrimIdent
Eq PrimIdent
-> (PrimIdent -> PrimIdent -> Ordering)
-> (PrimIdent -> PrimIdent -> Bool)
-> (PrimIdent -> PrimIdent -> Bool)
-> (PrimIdent -> PrimIdent -> Bool)
-> (PrimIdent -> PrimIdent -> Bool)
-> (PrimIdent -> PrimIdent -> PrimIdent)
-> (PrimIdent -> PrimIdent -> PrimIdent)
-> Ord PrimIdent
PrimIdent -> PrimIdent -> Bool
PrimIdent -> PrimIdent -> Ordering
PrimIdent -> PrimIdent -> PrimIdent
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PrimIdent -> PrimIdent -> PrimIdent
$cmin :: PrimIdent -> PrimIdent -> PrimIdent
max :: PrimIdent -> PrimIdent -> PrimIdent
$cmax :: PrimIdent -> PrimIdent -> PrimIdent
>= :: PrimIdent -> PrimIdent -> Bool
$c>= :: PrimIdent -> PrimIdent -> Bool
> :: PrimIdent -> PrimIdent -> Bool
$c> :: PrimIdent -> PrimIdent -> Bool
<= :: PrimIdent -> PrimIdent -> Bool
$c<= :: PrimIdent -> PrimIdent -> Bool
< :: PrimIdent -> PrimIdent -> Bool
$c< :: PrimIdent -> PrimIdent -> Bool
compare :: PrimIdent -> PrimIdent -> Ordering
$ccompare :: PrimIdent -> PrimIdent -> Ordering
$cp1Ord :: Eq PrimIdent
Ord,Int -> PrimIdent -> ShowS
[PrimIdent] -> ShowS
PrimIdent -> String
(Int -> PrimIdent -> ShowS)
-> (PrimIdent -> String)
-> ([PrimIdent] -> ShowS)
-> Show PrimIdent
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PrimIdent] -> ShowS
$cshowList :: [PrimIdent] -> ShowS
show :: PrimIdent -> String
$cshow :: PrimIdent -> String
showsPrec :: Int -> PrimIdent -> ShowS
$cshowsPrec :: Int -> PrimIdent -> ShowS
Show,(forall x. PrimIdent -> Rep PrimIdent x)
-> (forall x. Rep PrimIdent x -> PrimIdent) -> Generic PrimIdent
forall x. Rep PrimIdent x -> PrimIdent
forall x. PrimIdent -> Rep PrimIdent x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PrimIdent x -> PrimIdent
$cfrom :: forall x. PrimIdent -> Rep PrimIdent x
Generic)

-- | A shortcut to make (non-infix) primitives in the prelude.
prelPrim :: T.Text -> PrimIdent
prelPrim :: Text -> PrimIdent
prelPrim = ModName -> Text -> PrimIdent
PrimIdent ModName
preludeName

floatPrim :: T.Text -> PrimIdent
floatPrim :: Text -> PrimIdent
floatPrim = ModName -> Text -> PrimIdent
PrimIdent ModName
floatName

suiteBPrim :: T.Text -> PrimIdent
suiteBPrim :: Text -> PrimIdent
suiteBPrim = ModName -> Text -> PrimIdent
PrimIdent ModName
suiteBName

primeECPrim :: T.Text -> PrimIdent
primeECPrim :: Text -> PrimIdent
primeECPrim = ModName -> Text -> PrimIdent
PrimIdent ModName
primeECName

arrayPrim :: T.Text -> PrimIdent
arrayPrim :: Text -> PrimIdent
arrayPrim = ModName -> Text -> PrimIdent
PrimIdent ModName
arrayName

instance NFData PrimIdent