{-# OPTIONS_GHC -Wno-incomplete-patterns #-}
{-# LANGUAGE DerivingStrategies,
             GeneralizedNewtypeDeriving #-}
{-|
Module      : Parsley.Internal.Backend.Machine.Identifiers
Description : Machine specific identifiers
License     : BSD-3-Clause
Maintainer  : Jamie Willis
Stability   : experimental

This module extends "Parsley.Internal.Core.Identifiers" with
`ΦVar`, which is used for join points. Re-exports other
identifiers.

@since 1.0.0.0
-}
module Parsley.Internal.Backend.Machine.Identifiers (
    ΦVar(..), IΦVar,
    module Parsley.Internal.Core.Identifiers,
  ) where

import Data.GADT.Compare                 (GEq, GCompare, gcompare, geq, GOrdering(..))
import Data.Kind                         (Type)
import Data.Typeable                     ((:~:)(Refl))
import Data.Word                         (Word64)
import Parsley.Internal.Core.Identifiers -- for re-export
import Unsafe.Coerce                     (unsafeCoerce)

{-|
Represents a join point which requires an argument.
of type @a@.

@since 1.0.0.0
-}
newtype ΦVar (a :: Type) = ΦVar IΦVar

{-|
Underlying untyped identifier, which is numeric but otherwise opaque.

@since 1.0.0.0
-}
newtype IΦVar = IΦVar Word64 deriving newtype (Eq IΦVar
Eq IΦVar
-> (IΦVar -> IΦVar -> Ordering)
-> (IΦVar -> IΦVar -> Bool)
-> (IΦVar -> IΦVar -> Bool)
-> (IΦVar -> IΦVar -> Bool)
-> (IΦVar -> IΦVar -> Bool)
-> (IΦVar -> IΦVar -> IΦVar)
-> (IΦVar -> IΦVar -> IΦVar)
-> Ord IΦVar
IΦVar -> IΦVar -> Bool
IΦVar -> IΦVar -> Ordering
IΦVar -> IΦVar -> IΦVar
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 :: IΦVar -> IΦVar -> IΦVar
$cmin :: IΦVar -> IΦVar -> IΦVar
max :: IΦVar -> IΦVar -> IΦVar
$cmax :: IΦVar -> IΦVar -> IΦVar
>= :: IΦVar -> IΦVar -> Bool
$c>= :: IΦVar -> IΦVar -> Bool
> :: IΦVar -> IΦVar -> Bool
$c> :: IΦVar -> IΦVar -> Bool
<= :: IΦVar -> IΦVar -> Bool
$c<= :: IΦVar -> IΦVar -> Bool
< :: IΦVar -> IΦVar -> Bool
$c< :: IΦVar -> IΦVar -> Bool
compare :: IΦVar -> IΦVar -> Ordering
$ccompare :: IΦVar -> IΦVar -> Ordering
$cp1Ord :: Eq IΦVar
Ord, IΦVar -> IΦVar -> Bool
(IΦVar -> IΦVar -> Bool) -> (IΦVar -> IΦVar -> Bool) -> Eq IΦVar
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: IΦVar -> IΦVar -> Bool
$c/= :: IΦVar -> IΦVar -> Bool
== :: IΦVar -> IΦVar -> Bool
$c== :: IΦVar -> IΦVar -> Bool
Eq, Integer -> IΦVar
IΦVar -> IΦVar
IΦVar -> IΦVar -> IΦVar
(IΦVar -> IΦVar -> IΦVar)
-> (IΦVar -> IΦVar -> IΦVar)
-> (IΦVar -> IΦVar -> IΦVar)
-> (IΦVar -> IΦVar)
-> (IΦVar -> IΦVar)
-> (IΦVar -> IΦVar)
-> (Integer -> IΦVar)
-> Num IΦVar
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> IΦVar
$cfromInteger :: Integer -> IΦVar
signum :: IΦVar -> IΦVar
$csignum :: IΦVar -> IΦVar
abs :: IΦVar -> IΦVar
$cabs :: IΦVar -> IΦVar
negate :: IΦVar -> IΦVar
$cnegate :: IΦVar -> IΦVar
* :: IΦVar -> IΦVar -> IΦVar
$c* :: IΦVar -> IΦVar -> IΦVar
- :: IΦVar -> IΦVar -> IΦVar
$c- :: IΦVar -> IΦVar -> IΦVar
+ :: IΦVar -> IΦVar -> IΦVar
$c+ :: IΦVar -> IΦVar -> IΦVar
Num, Int -> IΦVar
IΦVar -> Int
IΦVar -> [IΦVar]
IΦVar -> IΦVar
IΦVar -> IΦVar -> [IΦVar]
IΦVar -> IΦVar -> IΦVar -> [IΦVar]
(IΦVar -> IΦVar)
-> (IΦVar -> IΦVar)
-> (Int -> IΦVar)
-> (IΦVar -> Int)
-> (IΦVar -> [IΦVar])
-> (IΦVar -> IΦVar -> [IΦVar])
-> (IΦVar -> IΦVar -> [IΦVar])
-> (IΦVar -> IΦVar -> IΦVar -> [IΦVar])
-> Enum IΦVar
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 :: IΦVar -> IΦVar -> IΦVar -> [IΦVar]
$cenumFromThenTo :: IΦVar -> IΦVar -> IΦVar -> [IΦVar]
enumFromTo :: IΦVar -> IΦVar -> [IΦVar]
$cenumFromTo :: IΦVar -> IΦVar -> [IΦVar]
enumFromThen :: IΦVar -> IΦVar -> [IΦVar]
$cenumFromThen :: IΦVar -> IΦVar -> [IΦVar]
enumFrom :: IΦVar -> [IΦVar]
$cenumFrom :: IΦVar -> [IΦVar]
fromEnum :: IΦVar -> Int
$cfromEnum :: IΦVar -> Int
toEnum :: Int -> IΦVar
$ctoEnum :: Int -> IΦVar
pred :: IΦVar -> IΦVar
$cpred :: IΦVar -> IΦVar
succ :: IΦVar -> IΦVar
$csucc :: IΦVar -> IΦVar
Enum, Int -> IΦVar -> ShowS
[IΦVar] -> ShowS
IΦVar -> String
(Int -> IΦVar -> ShowS)
-> (IΦVar -> String) -> ([IΦVar] -> ShowS) -> Show IΦVar
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IΦVar] -> ShowS
$cshowList :: [IΦVar] -> ShowS
show :: IΦVar -> String
$cshow :: IΦVar -> String
showsPrec :: Int -> IΦVar -> ShowS
$cshowsPrec :: Int -> IΦVar -> ShowS
Show)

instance Show (ΦVar a) where show :: ΦVar a -> String
show (ΦVar IΦVar
φ) = String
"φ" String -> ShowS
forall a. [a] -> [a] -> [a]
++ IΦVar -> String
forall a. Show a => a -> String
show IΦVar
φ

instance GEq ΦVar where
  geq :: ΦVar a -> ΦVar b -> Maybe (a :~: b)
geq (ΦVar IΦVar
u) (ΦVar IΦVar
v)
    | IΦVar
u IΦVar -> IΦVar -> Bool
forall a. Eq a => a -> a -> Bool
== IΦVar
v    = (a :~: b) -> Maybe (a :~: b)
forall a. a -> Maybe a
Just ((Any :~: Any) -> a :~: b
forall a b. a -> b
unsafeCoerce Any :~: Any
forall k (a :: k). a :~: a
Refl)
    | Bool
otherwise = Maybe (a :~: b)
forall a. Maybe a
Nothing

instance GCompare ΦVar where
  gcompare :: ΦVar a -> ΦVar b -> GOrdering a b
gcompare φ1 :: ΦVar a
φ1@(ΦVar IΦVar
u) φ2 :: ΦVar b
φ2@(ΦVar IΦVar
v) = case IΦVar -> IΦVar -> Ordering
forall a. Ord a => a -> a -> Ordering
compare IΦVar
u IΦVar
v of
    Ordering
LT -> GOrdering a b
forall k (a :: k) (b :: k). GOrdering a b
GLT
    Ordering
EQ -> case ΦVar a -> ΦVar b -> Maybe (a :~: b)
forall k (f :: k -> Type) (a :: k) (b :: k).
GEq f =>
f a -> f b -> Maybe (a :~: b)
geq ΦVar a
φ1 ΦVar b
φ2 of Just a :~: b
Refl -> GOrdering a b
forall k (a :: k). GOrdering a a
GEQ
    Ordering
GT -> GOrdering a b
forall k (a :: k) (b :: k). GOrdering a b
GGT