module Graphics.HaGL.GLExpr (
    GLExpr(..),
    GLAtom(..),
    GLFunc(..),
    GLGenExpr(..),
    GLDomain(..),
    shaderDomains,
    InterpolationType(..),
    IOVarID,
    GLCoord(..),
    GLCoordList(..),
    GLCol(..),
    GLExprException(..),
    ConstExpr,
    HostExpr,
    VertExpr,
    FragExpr
) where

import Prelude hiding (id)
import GHC.TypeNats
import Control.Exception (Exception)

import Graphics.HaGL.GLType
import Graphics.HaGL.ExprID
import Graphics.HaGL.Util.Types
import qualified Graphics.HaGL.Util.DepMap as DepMap


-- * Expression definitions

-- | A generic HaGL expression with domain of computation @d@ and underlying type @t@
data GLExpr (d :: GLDomain) (t :: *) where
    GLAtom :: GLType t => ExprID -> GLAtom d t -> GLExpr d t
    GLFunc :: GLType t => ExprID -> GLFunc d t -> GLExpr d t
    GLGenExpr :: GLType t => ExprID -> GLGenExpr d t -> GLExpr d t


-- Irreducible variables and placeholders

data GLAtom (d :: GLDomain) (t :: *) where

    Const :: GLType t => 
        t -> GLAtom d t
    -- Generic variables; e.g., function parameters
    GenVar :: GLType t => GLAtom d t
    Uniform :: GLType t => 
        GLExpr HostDomain t -> GLAtom d t
    GenericUniform :: GLType t => 
        String -> GLAtom d t
    Inp :: GLInputType t => 
        [GLExpr ConstDomain t] -> GLAtom VertexDomain t
    Frag :: GLInputType t =>
        InterpolationType -> GLExpr VertexDomain t -> GLAtom FragmentDomain t

    -- IO variables and placeholders exclusive to HostDomain
    IOFloat :: IOVarID -> GLAtom HostDomain Float
    IODouble :: IOVarID -> GLAtom HostDomain Double
    IOInt :: IOVarID -> GLAtom HostDomain Int
    IOUInt :: IOVarID -> GLAtom HostDomain UInt
    IOBool :: IOVarID -> GLAtom HostDomain Bool
    IOPrec :: GLType t => GLExpr HostDomain t -> GLExpr HostDomain t -> GLAtom HostDomain t
    GLLift0 :: GLType t =>
        t -> GLAtom HostDomain t 
    GLLift1 :: (GLType t, GLType t1) =>
        (t1 -> t) -> GLExpr HostDomain t1 -> GLAtom HostDomain t
    GLLift2 :: (GLType t, GLType t1, GLType t2) =>
        (t1 -> t2 -> t) -> GLExpr HostDomain t1 -> GLExpr HostDomain t2 -> GLAtom HostDomain t
    GLLift3 :: (GLType t, GLType t1, GLType t2, GLType t3) =>
        (t1 -> t2 -> t3 -> t) -> GLExpr HostDomain t1 -> GLExpr HostDomain t2 -> GLExpr HostDomain t3 -> GLAtom HostDomain t
    GLLift4 :: (GLType t, GLType t1, GLType t2, GLType t3, GLType t4) =>
        (t1 -> t2 -> t3 -> t4 -> t) -> GLExpr HostDomain t1 -> GLExpr HostDomain t2 -> GLExpr HostDomain t3 -> GLExpr HostDomain t4 -> GLAtom HostDomain t
    GLLift5 :: (GLType t, GLType t1, GLType t2, GLType t3, GLType t4, GLType t5) =>
        (t1 -> t2 -> t3 -> t4 -> t5 -> t) -> GLExpr HostDomain t1 -> GLExpr HostDomain t2 -> GLExpr HostDomain t3 -> GLExpr HostDomain t4 -> GLExpr HostDomain t5 -> GLAtom HostDomain t
    GLLift6 :: (GLType t, GLType t1, GLType t2, GLType t3, GLType t4, GLType t5, GLType t6) =>
        (t1 -> t2 -> t3 -> t4 -> t5 -> t6 -> t) -> GLExpr HostDomain t1 -> GLExpr HostDomain t2 -> GLExpr HostDomain t3 -> GLExpr HostDomain t4 -> GLExpr HostDomain t5 -> GLExpr HostDomain t6 -> GLAtom HostDomain t


-- User-defined functions

data GLFunc (d :: GLDomain) (t :: *) where

    GLFunc1 :: (GLType t, GLType t1) =>
        (GLExpr d t1 -> GLExpr d t) ->
        GLExpr d t1 -> GLExpr d t1 -> GLFunc d t
    GLFunc2 :: (GLType t, GLType t1, GLType t2) =>
        (GLExpr d t1 -> GLExpr d t2 -> GLExpr d t) ->
        GLExpr d t1 -> GLExpr d t2 -> 
        GLExpr d t1 -> GLExpr d t2 -> GLFunc d t
    GLFunc3 :: (GLType t, GLType t1, GLType t2, GLType t3) =>
        (GLExpr d t1 -> GLExpr d t2 -> GLExpr d t3 -> GLExpr d t) ->
        GLExpr d t1 -> GLExpr d t2 -> GLExpr d t3 ->
        GLExpr d t1 -> GLExpr d t2 -> GLExpr d t3 -> GLFunc d t
    GLFunc4 :: (GLType t, GLType t1, GLType t2, GLType t3) =>
        (GLExpr d t1 -> GLExpr d t2 -> GLExpr d t3 -> GLExpr d t4 -> GLExpr d t) ->
        GLExpr d t1 -> GLExpr d t2 -> GLExpr d t3 -> GLExpr d t4 ->
        GLExpr d t1 -> GLExpr d t2 -> GLExpr d t3 -> GLExpr d t4 -> GLFunc d t
    GLFunc5 :: (GLType t, GLType t1, GLType t2, GLType t3, GLType t4, GLType t5) =>
        (GLExpr d t1 -> GLExpr d t2 -> GLExpr d t3 -> GLExpr d t4 -> GLExpr d t5 -> GLExpr d t) ->
        GLExpr d t1 -> GLExpr d t2 -> GLExpr d t3 -> GLExpr d t4 -> GLExpr d t5 ->
        GLExpr d t1 -> GLExpr d t2 -> GLExpr d t3 -> GLExpr d t4 -> GLExpr d t5 -> GLFunc d t
    GLFunc6 :: (GLType t, GLType t1, GLType t2, GLType t3, GLType t4, GLType t5, GLType t6) =>
        (GLExpr d t1 -> GLExpr d t2 -> GLExpr d t3 -> GLExpr d t4 -> GLExpr d t5 -> GLExpr d t6 -> GLExpr d t) ->
        GLExpr d t1 -> GLExpr d t2 -> GLExpr d t3 -> GLExpr d t4 -> GLExpr d t5 -> GLExpr d t6 ->
        GLExpr d t1 -> GLExpr d t2 -> GLExpr d t3 -> GLExpr d t4 -> GLExpr d t5 -> GLExpr d t6 -> GLFunc d t


-- Compound expressions corresponding to built-in functions and operators

data GLGenExpr (d :: GLDomain) (t :: *) where

    GLVec2 :: (GLType (Vec 2 t)) =>
        GLExpr d t -> GLExpr d t -> GLGenExpr d (Vec 2 t)
    GLVec3 :: (GLType (Vec 3 t)) =>
        GLExpr d t -> GLExpr d t -> GLExpr d t -> GLGenExpr d (Vec 3 t)
    GLVec4 :: (GLType (Vec 4 t)) =>
        GLExpr d t -> GLExpr d t -> GLExpr d t -> GLExpr d t -> GLGenExpr d (Vec 4 t)
    GLMat2x2 :: (GLFloating t, GLType (Vec 2 t), GLType (Mat 2 2 t)) =>
        GLExpr d (Vec 2 t) -> GLExpr d (Vec 2 t) -> GLGenExpr d (Mat 2 2 t)
    GLMat2x3 :: (GLFloating t, GLType (Vec 2 t), GLType (Mat 2 3 t)) =>
        GLExpr d (Vec 2 t) -> GLExpr d (Vec 2 t) -> GLExpr d (Vec 2 t) -> GLGenExpr d (Mat 2 3 t)
    GLMat2x4 :: (GLFloating t, GLType (Vec 2 t), GLType (Mat 2 4 t)) =>
        GLExpr d (Vec 2 t) -> GLExpr d (Vec 2 t) -> GLExpr d (Vec 2 t) -> GLExpr d (Vec 2 t) -> GLGenExpr d (Mat 2 4 t)
    GLMat3x2 :: (GLFloating t, GLType (Vec 3 t), GLType (Mat 3 2 t)) =>
        GLExpr d (Vec 3 t) -> GLExpr d (Vec 3 t) -> GLGenExpr d (Mat 3 2 t)
    GLMat3x3 :: (GLFloating t, GLType (Vec 3 t), GLType (Mat 3 3 t)) =>
        GLExpr d (Vec 3 t) -> GLExpr d (Vec 3 t) -> GLExpr d (Vec 3 t) -> GLGenExpr d (Mat 3 3 t)
    GLMat3x4 :: (GLFloating t, GLType (Vec 3 t), GLType (Mat 3 4 t)) =>
        GLExpr d (Vec 3 t) -> GLExpr d (Vec 3 t) -> GLExpr d (Vec 3 t) -> GLExpr d (Vec 3 t) -> GLGenExpr d (Mat 3 4 t)
    GLMat4x2 :: (GLFloating t, GLType (Vec 4 t), GLType (Mat 4 2 t)) =>
        GLExpr d (Vec 4 t) -> GLExpr d (Vec 4 t) -> GLGenExpr d (Mat 4 2 t)
    GLMat4x3 :: (GLFloating t, GLType (Vec 4 t), GLType (Mat 4 3 t)) =>
        GLExpr d (Vec 4 t) -> GLExpr d (Vec 4 t) -> GLExpr d (Vec 4 t) -> GLGenExpr d (Mat 4 3 t)
    GLMat4x4 :: (GLFloating t, GLType (Vec 4 t), GLType (Mat 4 4 t)) =>
        GLExpr d (Vec 4 t) -> GLExpr d (Vec 4 t) -> GLExpr d (Vec 4 t) -> GLExpr d (Vec 4 t) -> GLGenExpr d (Mat 4 4 t)
    Pre :: (GLType (Vec n t), GLType (Vec (n + 1) t)) => 
        GLExpr d t -> GLExpr d (Vec n t) -> GLGenExpr d (Vec (n + 1) t)
    App :: (GLType (Vec n t), GLType t, GLType (Vec (n + 1) t)) => 
        GLExpr d (Vec n t) -> GLExpr d t -> GLGenExpr d (Vec (n + 1) t)
    Conc :: (GLType (Vec m t), GLType (Vec n t), GLType (Vec (m + n) t)) => 
        GLExpr d (Vec m t) -> GLExpr d (Vec n t) -> GLGenExpr d (Vec (m + n) t)
    GLArray :: GLType [t] =>
        [GLExpr HostDomain t] -> GLGenExpr HostDomain [t]

    OpCoord :: (GLType (Vec n t), m <= n) =>
        GLCoord m -> GLExpr d (Vec n t) -> GLGenExpr d t
    OpCoordMulti :: (GLType (Vec n t), GLType (Vec l t), m <= n) =>
        GLCoordList l m -> GLExpr d (Vec n t) -> GLGenExpr d (Vec l t)
    OpCol :: (GLType (Mat r c t), GLType (Vec r t), m + 1 <= c) =>
        GLCol m -> GLExpr d (Mat r c t) -> GLGenExpr d (Vec r t)
    OpArrayElt :: (GLType [t], GLType t) =>
        GLExpr d [t] -> GLExpr d Int -> GLGenExpr d t

    Cast :: (GLPrim t1, GLPrim t2) => 
        GLExpr d t1 -> GLGenExpr d t2
    MatCast :: (GLPrim t1, GLPrim t2, KnownNat p, KnownNat q) => 
        GLExpr d (Mat p q t1) -> GLGenExpr d (Mat p q t2)

    OpAdd :: (GLNumeric (GLElt t), GLType t) => 
        GLExpr d t -> GLExpr d t -> GLGenExpr d t
    OpSubt :: (GLNumeric (GLElt t), GLType t) =>
        GLExpr d t -> GLExpr d t -> GLGenExpr d t
    OpMult :: (GLNumeric (GLElt t), GLType t) => 
        GLExpr d t -> GLExpr d t -> GLGenExpr d t
    OpDiv :: (GLNumeric (GLElt t), GLType t) => 
        GLExpr d t -> GLExpr d t -> GLGenExpr d t
    OpMod :: (GLInteger (GLElt t), GLPrimOrVec t) =>
        GLExpr d t -> GLExpr d t -> GLGenExpr d t
    OpNeg :: (GLNumeric (GLElt t), GLType t) => 
        GLExpr d t -> GLGenExpr d t
    OpLessThan :: GLNumeric t =>
        GLExpr d t -> GLExpr d t -> GLGenExpr d Bool
    OpLessThanEqual :: GLNumeric t =>
        GLExpr d t -> GLExpr d t -> GLGenExpr d Bool
    OpGreaterThan :: GLNumeric t =>
        GLExpr d t -> GLExpr d t -> GLGenExpr d Bool
    OpGreaterThanEqual :: GLNumeric t =>
        GLExpr d t -> GLExpr d t -> GLGenExpr d Bool
    OpEqual :: GLType t =>
        GLExpr d t -> GLExpr d t -> GLGenExpr d Bool
    OpNotEqual :: GLType t =>
        GLExpr d t -> GLExpr d t -> GLGenExpr d Bool
    OpAnd :: GLExpr d Bool -> GLExpr d Bool -> GLGenExpr d Bool
    OpOr :: GLExpr d Bool -> GLExpr d Bool -> GLGenExpr d Bool
    OpXor :: GLExpr d Bool -> GLExpr d Bool -> GLGenExpr d Bool
    OpNot :: GLExpr d Bool -> GLGenExpr d Bool
    OpCond :: GLType t =>
        GLExpr d Bool -> GLExpr d t -> GLExpr d t -> GLGenExpr d t
    OpCompl :: GLSupportsBitwiseOps t => 
        GLExpr d t -> GLGenExpr d t
    OpLshift :: GLSupportsBitwiseOps t => 
        GLExpr d t -> GLExpr d t -> GLGenExpr d t
    OpRshift :: GLSupportsBitwiseOps t => 
        GLExpr d t -> GLExpr d t -> GLGenExpr d t
    OpBitAnd :: GLSupportsBitwiseOps t => 
        GLExpr d t -> GLExpr d t -> GLGenExpr d t
    OpBitOr :: GLSupportsBitwiseOps t => 
        GLExpr d t -> GLExpr d t -> GLGenExpr d t
    OpBitXor :: GLSupportsBitwiseOps t => 
        GLExpr d t -> GLExpr d t -> GLGenExpr d t
    OpScalarMult :: (GLNumeric t, GLType (Mat p q t)) => 
        GLExpr d t -> GLExpr d (Mat p q t) -> GLGenExpr d (Mat p q t)
    OpMatrixMult :: (GLFloating t, GLType (Mat p q t), GLType (Mat q r t), GLType (Mat p r t)) => 
        GLExpr d (Mat p q t) -> GLExpr d (Mat q r t) -> GLGenExpr d (Mat p r t)

    Radians :: (GLElt t ~ Float, GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Degrees :: (GLElt t ~ Float, GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Sin :: (GLElt t ~ Float, GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Cos :: (GLElt t ~ Float, GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Tan :: (GLElt t ~ Float, GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Asin :: (GLElt t ~ Float, GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Acos :: (GLElt t ~ Float, GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Atan :: (GLElt t ~ Float, GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Sinh :: (GLElt t ~ Float, GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Cosh :: (GLElt t ~ Float, GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Tanh :: (GLElt t ~ Float, GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Asinh :: (GLElt t ~ Float, GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Acosh :: (GLElt t ~ Float, GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Atanh :: (GLElt t ~ Float, GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t

    Pow :: (GLElt t ~ Float, GLPrimOrVec t) =>
        GLExpr d t -> GLExpr d t -> GLGenExpr d t
    Exp :: (GLElt t ~ Float, GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Log :: (GLElt t ~ Float, GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Exp2 :: (GLElt t ~ Float, GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Log2 :: (GLElt t ~ Float, GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Sqrt :: (GLFloating (GLElt t), GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Inversesqrt :: (GLFloating (GLElt t), GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t

    Abs :: (GLSigned (GLElt t), GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Sign :: (GLSigned (GLElt t), GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Floor :: (GLFloating (GLElt t), GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Trunc :: (GLFloating (GLElt t), GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Round :: (GLFloating (GLElt t), GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    RoundEven :: (GLFloating (GLElt t), GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Ceil :: (GLFloating (GLElt t), GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Fract :: (GLFloating (GLElt t), GLPrimOrVec t) => 
        GLExpr d t -> GLGenExpr d t
    Mod :: (GLFloating (GLElt t), GLPrimOrVec t) => 
        GLExpr d t -> GLExpr d t -> GLGenExpr d t
    Min :: (GLNumeric (GLElt t), GLPrimOrVec t) => 
        GLExpr d t -> GLExpr d t -> GLGenExpr d t
    Max :: (GLNumeric (GLElt t), GLPrimOrVec t) => 
        GLExpr d t -> GLExpr d t -> GLGenExpr d t
    Clamp :: (GLNumeric (GLElt t), GLPrimOrVec t) => 
        GLExpr d t -> GLExpr d t -> GLExpr d t -> GLGenExpr d t
    Mix :: (GLFloating (GLElt t), GLPrimOrVec t) => 
        GLExpr d t -> GLExpr d t -> GLExpr d t -> GLGenExpr d t
    Step :: (GLFloating (GLElt t), GLPrimOrVec t) => 
        GLExpr d t -> GLExpr d t -> GLGenExpr d t
    Smoothstep :: (GLFloating (GLElt t), GLPrimOrVec t) => 
        GLExpr d t -> GLExpr d t -> GLExpr d t -> GLGenExpr d t

    Length :: GLFloating t =>
        GLExpr d (Vec n t) -> GLGenExpr d t
    Distance :: GLFloating t =>
        GLExpr d (Vec n t) -> GLExpr d (Vec n t) -> GLGenExpr d t
    Dot :: (GLFloating t, GLType (Vec n t))  =>
        GLExpr d (Vec n t) -> GLExpr d (Vec n t) -> GLGenExpr d t
    Cross :: (GLFloating t, GLType (Vec 3 t)) =>
        GLExpr d (Vec 3 t) -> GLExpr d (Vec 3 t) -> GLGenExpr d (Vec 3 t)
    Normalize :: (GLFloating t, GLType (Vec n t))=>
        GLExpr d (Vec n t) -> GLGenExpr d (Vec n t)
    Faceforward :: (GLFloating t, KnownNat n, GLType (Vec n t)) =>
        GLExpr d (Vec n t) -> GLExpr d (Vec n t) -> GLExpr d (Vec n t) -> GLGenExpr d (Vec n t)
    Reflect :: (GLFloating t, KnownNat n, GLType (Vec n t)) =>
        GLExpr d (Vec n t) -> GLExpr d (Vec n t) -> GLGenExpr d (Vec n t)
    Refract :: (GLFloating t, KnownNat n, GLType (Vec n t), GLType t) =>
        GLExpr d (Vec n t) -> GLExpr d (Vec n t) -> GLExpr d t -> GLGenExpr d (Vec n t)

    MatrixCompMult :: (GLFloating t, GLType (Mat p q t), GLType (Mat p q t)) => 
        GLExpr d (Mat p q t) -> GLExpr d (Mat p q t) -> GLGenExpr d (Mat p q t)
    OuterProduct :: (GLFloating t, GLType (Vec q t), GLType (Mat p q t)) => 
        GLExpr d (Vec p t) -> GLExpr d (Vec q t) -> GLGenExpr d (Mat p q t)
    Transpose :: (GLFloating t, GLType (Mat p q t), GLType (Mat q p t)) => 
        GLExpr d (Mat p q t) -> GLGenExpr d (Mat q p t)
    Determinant :: GLType (Mat p p Float) => 
        GLExpr d (Mat p p Float) -> GLGenExpr d Float
    Inverse :: GLType (Mat p p Float) => 
        GLExpr d (Mat p p Float) -> GLGenExpr d (Mat p p Float)

    LessThan :: (GLSingleNumeric t, KnownNat n, GLType (Vec n Bool)) =>
        GLExpr d (Vec n t) -> GLExpr d (Vec n t) -> GLGenExpr d (Vec n Bool)
    LessThanEqual :: (GLSingleNumeric t, KnownNat n, GLType (Vec n Bool)) =>
        GLExpr d (Vec n t) -> GLExpr d (Vec n t) -> GLGenExpr d (Vec n Bool)
    GreaterThan :: (GLSingleNumeric t, KnownNat n, GLType (Vec n Bool)) =>
        GLExpr d (Vec n t) -> GLExpr d (Vec n t) -> GLGenExpr d (Vec n Bool)
    GreaterThanEqual :: (GLSingleNumeric t, KnownNat n, GLType (Vec n Bool)) =>
        GLExpr d (Vec n t) -> GLExpr d (Vec n t) -> GLGenExpr d (Vec n Bool)
    Equal :: (GLSingle t, KnownNat n, GLType (Vec n Bool)) =>
        GLExpr d (Vec n t) -> GLExpr d (Vec n t) -> GLGenExpr d (Vec n Bool)
    NotEqual :: (GLSingle t, KnownNat n, GLType (Vec n Bool)) =>
        GLExpr d (Vec n t) -> GLExpr d (Vec n t) -> GLGenExpr d (Vec n Bool)
    Any :: GLType (Vec n Bool) =>
        GLExpr d (Vec n Bool) -> GLGenExpr d Bool
    All :: GLType (Vec n Bool) =>
        GLExpr d (Vec n Bool) -> GLGenExpr d Bool
    Not :: GLType (Vec n Bool) =>
        GLExpr d (Vec n Bool) -> GLGenExpr d (Vec n Bool)

-- | A label for the domain where a given computation make take place
data GLDomain = 
    -- | Labels a constant value computed on the host CPU
    ConstDomain | 
    -- | Labels a potentially I/O-dependent value computed on the host CPU
    HostDomain | 
    -- | Labels a vertex shader variable
    VertexDomain | 
    -- | Labels a fragment shader variable
    FragmentDomain
    deriving (GLDomain -> GLDomain -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GLDomain -> GLDomain -> Bool
$c/= :: GLDomain -> GLDomain -> Bool
== :: GLDomain -> GLDomain -> Bool
$c== :: GLDomain -> GLDomain -> Bool
Eq, Eq GLDomain
GLDomain -> GLDomain -> Bool
GLDomain -> GLDomain -> Ordering
GLDomain -> GLDomain -> GLDomain
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 :: GLDomain -> GLDomain -> GLDomain
$cmin :: GLDomain -> GLDomain -> GLDomain
max :: GLDomain -> GLDomain -> GLDomain
$cmax :: GLDomain -> GLDomain -> GLDomain
>= :: GLDomain -> GLDomain -> Bool
$c>= :: GLDomain -> GLDomain -> Bool
> :: GLDomain -> GLDomain -> Bool
$c> :: GLDomain -> GLDomain -> Bool
<= :: GLDomain -> GLDomain -> Bool
$c<= :: GLDomain -> GLDomain -> Bool
< :: GLDomain -> GLDomain -> Bool
$c< :: GLDomain -> GLDomain -> Bool
compare :: GLDomain -> GLDomain -> Ordering
$ccompare :: GLDomain -> GLDomain -> Ordering
Ord)

shaderDomains :: [GLDomain]
shaderDomains :: [GLDomain]
shaderDomains = [GLDomain
VertexDomain, GLDomain
FragmentDomain]


-- * Internal auxillary types

data InterpolationType = Smooth | NoPerspective | Flat

instance Show InterpolationType where
    show :: InterpolationType -> String
show InterpolationType
Smooth = String
"smooth"
    show InterpolationType
NoPerspective = String
"noperspective"
    show InterpolationType
Flat = String
"flat"

type IOVarID = String

data GLCoord (m :: Nat) where
    CoordX :: GLCoord 1
    CoordY :: GLCoord 2
    CoordZ :: GLCoord 3
    CoordW :: GLCoord 4

data GLCoordList (l :: Nat) (m :: Nat) where
    CoordNil :: GLCoordList 0 0
    CoordCons :: GLCoord m1 -> GLCoordList l2 m2 -> GLCoordList (l2 + 1) (Max m1 m2)

instance Show (GLCoord m) where
    show :: GLCoord m -> String
show GLCoord m
CoordX = String
"x"
    show GLCoord m
CoordY = String
"y"
    show GLCoord m
CoordZ = String
"z"
    show GLCoord m
CoordW = String
"w"

instance Show (GLCoordList l m) where
    show :: GLCoordList l m -> String
show GLCoordList l m
CoordNil = String
""
    show (CoordCons GLCoord m1
c GLCoordList l2 m2
cs) = forall a. Show a => a -> String
show GLCoord m1
c forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show GLCoordList l2 m2
cs

data GLCol (m :: Nat) where
    Col0 :: GLCol 0
    Col1 :: GLCol 1
    Col2 :: GLCol 2
    Col3 :: GLCol 3

instance Show (GLCol m) where
    show :: GLCol m -> String
show GLCol m
Col0 = String
"[0]"
    show GLCol m
Col1 = String
"[1]"
    show GLCol m
Col2 = String
"[2]"
    show GLCol m
Col3 = String
"[3]"


-- * glExprID

instance HasExprID (GLExpr d t) where
    getID :: GLExpr d t -> ExprID
getID (GLAtom ExprID
id GLAtom d t
_) = ExprID
id
    getID (GLFunc ExprID
fnID (GLFunc1 GLExpr d t1 -> GLExpr d t
_ GLExpr d t1
_ GLExpr d t1
x0)) = 
        [ExprID] -> ExprID
combineIDs [ExprID
fnID, forall a. HasExprID a => a -> ExprID
getID GLExpr d t1
x0]
    getID (GLFunc ExprID
fnID (GLFunc2 GLExpr d t1 -> GLExpr d t2 -> GLExpr d t
_ GLExpr d t1
_ GLExpr d t2
_ GLExpr d t1
x0 GLExpr d t2
y0)) = 
        [ExprID] -> ExprID
combineIDs [ExprID
fnID, forall a. HasExprID a => a -> ExprID
getID GLExpr d t1
x0, forall a. HasExprID a => a -> ExprID
getID GLExpr d t2
y0]
    getID (GLFunc ExprID
fnID (GLFunc3 GLExpr d t1 -> GLExpr d t2 -> GLExpr d t3 -> GLExpr d t
_ GLExpr d t1
_ GLExpr d t2
_ GLExpr d t3
_ GLExpr d t1
x0 GLExpr d t2
y0 GLExpr d t3
z0)) = 
        [ExprID] -> ExprID
combineIDs [ExprID
fnID, forall a. HasExprID a => a -> ExprID
getID GLExpr d t1
x0, forall a. HasExprID a => a -> ExprID
getID GLExpr d t2
y0, forall a. HasExprID a => a -> ExprID
getID GLExpr d t3
z0]
    getID (GLFunc ExprID
fnID (GLFunc4 GLExpr d t1
-> GLExpr d t2 -> GLExpr d t3 -> GLExpr d t4 -> GLExpr d t
_ GLExpr d t1
_ GLExpr d t2
_ GLExpr d t3
_ GLExpr d t4
_ GLExpr d t1
x0 GLExpr d t2
y0 GLExpr d t3
z0 GLExpr d t4
w0)) = 
        [ExprID] -> ExprID
combineIDs [ExprID
fnID, forall a. HasExprID a => a -> ExprID
getID GLExpr d t1
x0, forall a. HasExprID a => a -> ExprID
getID GLExpr d t2
y0, forall a. HasExprID a => a -> ExprID
getID GLExpr d t3
z0, forall a. HasExprID a => a -> ExprID
getID GLExpr d t4
w0]
    getID (GLFunc ExprID
fnID (GLFunc5 GLExpr d t1
-> GLExpr d t2
-> GLExpr d t3
-> GLExpr d t4
-> GLExpr d t5
-> GLExpr d t
_ GLExpr d t1
_ GLExpr d t2
_ GLExpr d t3
_ GLExpr d t4
_ GLExpr d t5
_ GLExpr d t1
x0 GLExpr d t2
y0 GLExpr d t3
z0 GLExpr d t4
w0 GLExpr d t5
u0)) = 
        [ExprID] -> ExprID
combineIDs [ExprID
fnID, forall a. HasExprID a => a -> ExprID
getID GLExpr d t1
x0, forall a. HasExprID a => a -> ExprID
getID GLExpr d t2
y0, forall a. HasExprID a => a -> ExprID
getID GLExpr d t3
z0, forall a. HasExprID a => a -> ExprID
getID GLExpr d t4
w0, forall a. HasExprID a => a -> ExprID
getID GLExpr d t5
u0]
    getID (GLFunc ExprID
fnID (GLFunc6 GLExpr d t1
-> GLExpr d t2
-> GLExpr d t3
-> GLExpr d t4
-> GLExpr d t5
-> GLExpr d t6
-> GLExpr d t
_ GLExpr d t1
_ GLExpr d t2
_ GLExpr d t3
_ GLExpr d t4
_ GLExpr d t5
_ GLExpr d t6
_ GLExpr d t1
x0 GLExpr d t2
y0 GLExpr d t3
z0 GLExpr d t4
w0 GLExpr d t5
u0 GLExpr d t6
v0)) = 
        [ExprID] -> ExprID
combineIDs [ExprID
fnID, forall a. HasExprID a => a -> ExprID
getID GLExpr d t1
x0, forall a. HasExprID a => a -> ExprID
getID GLExpr d t2
y0, forall a. HasExprID a => a -> ExprID
getID GLExpr d t3
z0, forall a. HasExprID a => a -> ExprID
getID GLExpr d t4
w0, forall a. HasExprID a => a -> ExprID
getID GLExpr d t5
u0, forall a. HasExprID a => a -> ExprID
getID GLExpr d t6
v0]
    getID (GLGenExpr ExprID
id GLGenExpr d t
_) = ExprID
id

instance DepMap.GenHashable (GLExpr d) where
    genHash :: forall t. GLExpr d t -> ExprID
genHash = forall a. HasExprID a => a -> ExprID
getID


-- * Exceptions for illegal expressions that are difficult to disallow at the type level

data GLExprException =
    UnsupportedRecCall |
    UnsupportedNameCapture |
    UnknownArraySize
    deriving GLExprException -> GLExprException -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GLExprException -> GLExprException -> Bool
$c/= :: GLExprException -> GLExprException -> Bool
== :: GLExprException -> GLExprException -> Bool
$c== :: GLExprException -> GLExprException -> Bool
Eq

instance Show GLExprException where
    show :: GLExprException -> String
show GLExprException
UnsupportedRecCall = String
"Unsupported recursive function call"
    show GLExprException
UnsupportedNameCapture = String
"Unsupported name capture in nested glFunc"
    show GLExprException
UnknownArraySize = String
"GLLift*: Function may only return a fixed-size list"

instance Exception GLExprException


-- * Synonyms

type ConstExpr = GLExpr ConstDomain
type HostExpr = GLExpr HostDomain
type VertExpr = GLExpr VertexDomain
type FragExpr = GLExpr FragmentDomain