module Language.GLSL.Syntax where

-- TODO:
-- - add support for 'array of strings' ?
-- - add support for macro preprocessing
-- - add support for optional macro #include
-- - applicative style (see http://github.com/markusle/husky)?
-- - type checking
-- - check for constant expression where expected
-- - error reporting
-- - pretty-printing
-- - basic queries (inputs and outputs of the shader)
-- - support GLSL 1.40?
-- - proper testing (HUnit and QuickCheck)
-- - use hpc with the tests
-- - scoping
-- - clean module import/export
-- - order of Syntax data types and Pretty instances should be the same
-- - build with no warning
-- - use hlint
-- - push to github
-- - push to hackage
-- - use parsec 3
-- - handle all possible newlines (\n, \r, \r\n, \n\r)
-- - 80-columns clean

-- - lot of restriction of Samplers use (section 4.1.7),
-- well in fact, for plenty of things.

----------------------------------------------------------------------
-- Abstract syntax tree
----------------------------------------------------------------------

data TranslationUnit = TranslationUnit [ExternalDeclaration] -- at least one
  deriving (Int -> TranslationUnit -> ShowS
[TranslationUnit] -> ShowS
TranslationUnit -> String
(Int -> TranslationUnit -> ShowS)
-> (TranslationUnit -> String)
-> ([TranslationUnit] -> ShowS)
-> Show TranslationUnit
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TranslationUnit -> ShowS
showsPrec :: Int -> TranslationUnit -> ShowS
$cshow :: TranslationUnit -> String
show :: TranslationUnit -> String
$cshowList :: [TranslationUnit] -> ShowS
showList :: [TranslationUnit] -> ShowS
Show, TranslationUnit -> TranslationUnit -> Bool
(TranslationUnit -> TranslationUnit -> Bool)
-> (TranslationUnit -> TranslationUnit -> Bool)
-> Eq TranslationUnit
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TranslationUnit -> TranslationUnit -> Bool
== :: TranslationUnit -> TranslationUnit -> Bool
$c/= :: TranslationUnit -> TranslationUnit -> Bool
/= :: TranslationUnit -> TranslationUnit -> Bool
Eq)

data ExternalDeclaration =
    -- function declarations should be at top level (page 28)
    FunctionDeclaration FunctionPrototype
  | FunctionDefinition FunctionPrototype Compound
  | Declaration Declaration
  deriving (Int -> ExternalDeclaration -> ShowS
[ExternalDeclaration] -> ShowS
ExternalDeclaration -> String
(Int -> ExternalDeclaration -> ShowS)
-> (ExternalDeclaration -> String)
-> ([ExternalDeclaration] -> ShowS)
-> Show ExternalDeclaration
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ExternalDeclaration -> ShowS
showsPrec :: Int -> ExternalDeclaration -> ShowS
$cshow :: ExternalDeclaration -> String
show :: ExternalDeclaration -> String
$cshowList :: [ExternalDeclaration] -> ShowS
showList :: [ExternalDeclaration] -> ShowS
Show, ExternalDeclaration -> ExternalDeclaration -> Bool
(ExternalDeclaration -> ExternalDeclaration -> Bool)
-> (ExternalDeclaration -> ExternalDeclaration -> Bool)
-> Eq ExternalDeclaration
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ExternalDeclaration -> ExternalDeclaration -> Bool
== :: ExternalDeclaration -> ExternalDeclaration -> Bool
$c/= :: ExternalDeclaration -> ExternalDeclaration -> Bool
/= :: ExternalDeclaration -> ExternalDeclaration -> Bool
Eq)

-- TODO clean
data Declaration =
-- e.g. layout (origin_upper_left) in vec4 gl_FragCoord;
--      struct name { ... };
--      struct name { ... } name;
    InitDeclaration InvariantOrType [InitDeclarator]
  | Precision PrecisionQualifier TypeSpecifierNoPrecision
  | Block TypeQualifier String [Field] (Maybe (String, Maybe (Maybe Expr))) -- constant expression
-- e.g. layout (origin_upper_left) in; TODO check if it is only used for default layout.
  | TQ TypeQualifier
  deriving (Int -> Declaration -> ShowS
[Declaration] -> ShowS
Declaration -> String
(Int -> Declaration -> ShowS)
-> (Declaration -> String)
-> ([Declaration] -> ShowS)
-> Show Declaration
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Declaration -> ShowS
showsPrec :: Int -> Declaration -> ShowS
$cshow :: Declaration -> String
show :: Declaration -> String
$cshowList :: [Declaration] -> ShowS
showList :: [Declaration] -> ShowS
Show, Declaration -> Declaration -> Bool
(Declaration -> Declaration -> Bool)
-> (Declaration -> Declaration -> Bool) -> Eq Declaration
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Declaration -> Declaration -> Bool
== :: Declaration -> Declaration -> Bool
$c/= :: Declaration -> Declaration -> Bool
/= :: Declaration -> Declaration -> Bool
Eq)

-- TODO regroup String (Maybe (Maybe Expr)) as Declarator and use it for
-- StructDeclarator.
data InitDeclarator = InitDecl String (Maybe (Maybe Expr)) (Maybe Expr) -- constant expression; assignment expression
  deriving (Int -> InitDeclarator -> ShowS
[InitDeclarator] -> ShowS
InitDeclarator -> String
(Int -> InitDeclarator -> ShowS)
-> (InitDeclarator -> String)
-> ([InitDeclarator] -> ShowS)
-> Show InitDeclarator
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> InitDeclarator -> ShowS
showsPrec :: Int -> InitDeclarator -> ShowS
$cshow :: InitDeclarator -> String
show :: InitDeclarator -> String
$cshowList :: [InitDeclarator] -> ShowS
showList :: [InitDeclarator] -> ShowS
Show, InitDeclarator -> InitDeclarator -> Bool
(InitDeclarator -> InitDeclarator -> Bool)
-> (InitDeclarator -> InitDeclarator -> Bool) -> Eq InitDeclarator
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: InitDeclarator -> InitDeclarator -> Bool
== :: InitDeclarator -> InitDeclarator -> Bool
$c/= :: InitDeclarator -> InitDeclarator -> Bool
/= :: InitDeclarator -> InitDeclarator -> Bool
Eq)

data InvariantOrType = InvariantDeclarator | TypeDeclarator FullType
  deriving (Int -> InvariantOrType -> ShowS
[InvariantOrType] -> ShowS
InvariantOrType -> String
(Int -> InvariantOrType -> ShowS)
-> (InvariantOrType -> String)
-> ([InvariantOrType] -> ShowS)
-> Show InvariantOrType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> InvariantOrType -> ShowS
showsPrec :: Int -> InvariantOrType -> ShowS
$cshow :: InvariantOrType -> String
show :: InvariantOrType -> String
$cshowList :: [InvariantOrType] -> ShowS
showList :: [InvariantOrType] -> ShowS
Show, InvariantOrType -> InvariantOrType -> Bool
(InvariantOrType -> InvariantOrType -> Bool)
-> (InvariantOrType -> InvariantOrType -> Bool)
-> Eq InvariantOrType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: InvariantOrType -> InvariantOrType -> Bool
== :: InvariantOrType -> InvariantOrType -> Bool
$c/= :: InvariantOrType -> InvariantOrType -> Bool
/= :: InvariantOrType -> InvariantOrType -> Bool
Eq)

data FunctionPrototype = FuncProt FullType String [ParameterDeclaration]
  deriving (Int -> FunctionPrototype -> ShowS
[FunctionPrototype] -> ShowS
FunctionPrototype -> String
(Int -> FunctionPrototype -> ShowS)
-> (FunctionPrototype -> String)
-> ([FunctionPrototype] -> ShowS)
-> Show FunctionPrototype
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FunctionPrototype -> ShowS
showsPrec :: Int -> FunctionPrototype -> ShowS
$cshow :: FunctionPrototype -> String
show :: FunctionPrototype -> String
$cshowList :: [FunctionPrototype] -> ShowS
showList :: [FunctionPrototype] -> ShowS
Show, FunctionPrototype -> FunctionPrototype -> Bool
(FunctionPrototype -> FunctionPrototype -> Bool)
-> (FunctionPrototype -> FunctionPrototype -> Bool)
-> Eq FunctionPrototype
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: FunctionPrototype -> FunctionPrototype -> Bool
== :: FunctionPrototype -> FunctionPrototype -> Bool
$c/= :: FunctionPrototype -> FunctionPrototype -> Bool
/= :: FunctionPrototype -> FunctionPrototype -> Bool
Eq)

data ParameterDeclaration =
  ParameterDeclaration (Maybe ParameterTypeQualifier)
                       (Maybe ParameterQualifier)
                       TypeSpecifier
                       (Maybe (String, Maybe Expr)) -- constant expression
  deriving (Int -> ParameterDeclaration -> ShowS
[ParameterDeclaration] -> ShowS
ParameterDeclaration -> String
(Int -> ParameterDeclaration -> ShowS)
-> (ParameterDeclaration -> String)
-> ([ParameterDeclaration] -> ShowS)
-> Show ParameterDeclaration
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ParameterDeclaration -> ShowS
showsPrec :: Int -> ParameterDeclaration -> ShowS
$cshow :: ParameterDeclaration -> String
show :: ParameterDeclaration -> String
$cshowList :: [ParameterDeclaration] -> ShowS
showList :: [ParameterDeclaration] -> ShowS
Show, ParameterDeclaration -> ParameterDeclaration -> Bool
(ParameterDeclaration -> ParameterDeclaration -> Bool)
-> (ParameterDeclaration -> ParameterDeclaration -> Bool)
-> Eq ParameterDeclaration
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ParameterDeclaration -> ParameterDeclaration -> Bool
== :: ParameterDeclaration -> ParameterDeclaration -> Bool
$c/= :: ParameterDeclaration -> ParameterDeclaration -> Bool
/= :: ParameterDeclaration -> ParameterDeclaration -> Bool
Eq)

data FullType = FullType (Maybe TypeQualifier) TypeSpecifier
  deriving (Int -> FullType -> ShowS
[FullType] -> ShowS
FullType -> String
(Int -> FullType -> ShowS)
-> (FullType -> String) -> ([FullType] -> ShowS) -> Show FullType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FullType -> ShowS
showsPrec :: Int -> FullType -> ShowS
$cshow :: FullType -> String
show :: FullType -> String
$cshowList :: [FullType] -> ShowS
showList :: [FullType] -> ShowS
Show, FullType -> FullType -> Bool
(FullType -> FullType -> Bool)
-> (FullType -> FullType -> Bool) -> Eq FullType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: FullType -> FullType -> Bool
== :: FullType -> FullType -> Bool
$c/= :: FullType -> FullType -> Bool
/= :: FullType -> FullType -> Bool
Eq)

-- sto
-- lay [sto]
-- int [sto]
-- inv [sto]
-- inv int sto
data TypeQualifier =
    TypeQualSto StorageQualifier
  | TypeQualLay LayoutQualifier (Maybe StorageQualifier)
  | TypeQualInt InterpolationQualifier (Maybe StorageQualifier)
  | TypeQualInv InvariantQualifier (Maybe StorageQualifier)
  | TypeQualInv3 InvariantQualifier InterpolationQualifier StorageQualifier
  deriving (Int -> TypeQualifier -> ShowS
[TypeQualifier] -> ShowS
TypeQualifier -> String
(Int -> TypeQualifier -> ShowS)
-> (TypeQualifier -> String)
-> ([TypeQualifier] -> ShowS)
-> Show TypeQualifier
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TypeQualifier -> ShowS
showsPrec :: Int -> TypeQualifier -> ShowS
$cshow :: TypeQualifier -> String
show :: TypeQualifier -> String
$cshowList :: [TypeQualifier] -> ShowS
showList :: [TypeQualifier] -> ShowS
Show, TypeQualifier -> TypeQualifier -> Bool
(TypeQualifier -> TypeQualifier -> Bool)
-> (TypeQualifier -> TypeQualifier -> Bool) -> Eq TypeQualifier
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TypeQualifier -> TypeQualifier -> Bool
== :: TypeQualifier -> TypeQualifier -> Bool
$c/= :: TypeQualifier -> TypeQualifier -> Bool
/= :: TypeQualifier -> TypeQualifier -> Bool
Eq)

data TypeSpecifier = TypeSpec (Maybe PrecisionQualifier) TypeSpecifierNoPrecision
  deriving (Int -> TypeSpecifier -> ShowS
[TypeSpecifier] -> ShowS
TypeSpecifier -> String
(Int -> TypeSpecifier -> ShowS)
-> (TypeSpecifier -> String)
-> ([TypeSpecifier] -> ShowS)
-> Show TypeSpecifier
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TypeSpecifier -> ShowS
showsPrec :: Int -> TypeSpecifier -> ShowS
$cshow :: TypeSpecifier -> String
show :: TypeSpecifier -> String
$cshowList :: [TypeSpecifier] -> ShowS
showList :: [TypeSpecifier] -> ShowS
Show, TypeSpecifier -> TypeSpecifier -> Bool
(TypeSpecifier -> TypeSpecifier -> Bool)
-> (TypeSpecifier -> TypeSpecifier -> Bool) -> Eq TypeSpecifier
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TypeSpecifier -> TypeSpecifier -> Bool
== :: TypeSpecifier -> TypeSpecifier -> Bool
$c/= :: TypeSpecifier -> TypeSpecifier -> Bool
/= :: TypeSpecifier -> TypeSpecifier -> Bool
Eq)

data InvariantQualifier = Invariant
  deriving (Int -> InvariantQualifier -> ShowS
[InvariantQualifier] -> ShowS
InvariantQualifier -> String
(Int -> InvariantQualifier -> ShowS)
-> (InvariantQualifier -> String)
-> ([InvariantQualifier] -> ShowS)
-> Show InvariantQualifier
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> InvariantQualifier -> ShowS
showsPrec :: Int -> InvariantQualifier -> ShowS
$cshow :: InvariantQualifier -> String
show :: InvariantQualifier -> String
$cshowList :: [InvariantQualifier] -> ShowS
showList :: [InvariantQualifier] -> ShowS
Show, InvariantQualifier -> InvariantQualifier -> Bool
(InvariantQualifier -> InvariantQualifier -> Bool)
-> (InvariantQualifier -> InvariantQualifier -> Bool)
-> Eq InvariantQualifier
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: InvariantQualifier -> InvariantQualifier -> Bool
== :: InvariantQualifier -> InvariantQualifier -> Bool
$c/= :: InvariantQualifier -> InvariantQualifier -> Bool
/= :: InvariantQualifier -> InvariantQualifier -> Bool
Eq)

data InterpolationQualifier =
    Smooth
  | Flat
  | NoPerspective
  deriving (Int -> InterpolationQualifier -> ShowS
[InterpolationQualifier] -> ShowS
InterpolationQualifier -> String
(Int -> InterpolationQualifier -> ShowS)
-> (InterpolationQualifier -> String)
-> ([InterpolationQualifier] -> ShowS)
-> Show InterpolationQualifier
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> InterpolationQualifier -> ShowS
showsPrec :: Int -> InterpolationQualifier -> ShowS
$cshow :: InterpolationQualifier -> String
show :: InterpolationQualifier -> String
$cshowList :: [InterpolationQualifier] -> ShowS
showList :: [InterpolationQualifier] -> ShowS
Show, InterpolationQualifier -> InterpolationQualifier -> Bool
(InterpolationQualifier -> InterpolationQualifier -> Bool)
-> (InterpolationQualifier -> InterpolationQualifier -> Bool)
-> Eq InterpolationQualifier
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: InterpolationQualifier -> InterpolationQualifier -> Bool
== :: InterpolationQualifier -> InterpolationQualifier -> Bool
$c/= :: InterpolationQualifier -> InterpolationQualifier -> Bool
/= :: InterpolationQualifier -> InterpolationQualifier -> Bool
Eq)

data LayoutQualifier = Layout [LayoutQualifierId]
  deriving (Int -> LayoutQualifier -> ShowS
[LayoutQualifier] -> ShowS
LayoutQualifier -> String
(Int -> LayoutQualifier -> ShowS)
-> (LayoutQualifier -> String)
-> ([LayoutQualifier] -> ShowS)
-> Show LayoutQualifier
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LayoutQualifier -> ShowS
showsPrec :: Int -> LayoutQualifier -> ShowS
$cshow :: LayoutQualifier -> String
show :: LayoutQualifier -> String
$cshowList :: [LayoutQualifier] -> ShowS
showList :: [LayoutQualifier] -> ShowS
Show, LayoutQualifier -> LayoutQualifier -> Bool
(LayoutQualifier -> LayoutQualifier -> Bool)
-> (LayoutQualifier -> LayoutQualifier -> Bool)
-> Eq LayoutQualifier
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LayoutQualifier -> LayoutQualifier -> Bool
== :: LayoutQualifier -> LayoutQualifier -> Bool
$c/= :: LayoutQualifier -> LayoutQualifier -> Bool
/= :: LayoutQualifier -> LayoutQualifier -> Bool
Eq)

data LayoutQualifierId = LayoutQualId String (Maybe Expr) -- TODO Expr should be IntConstant
  deriving (Int -> LayoutQualifierId -> ShowS
[LayoutQualifierId] -> ShowS
LayoutQualifierId -> String
(Int -> LayoutQualifierId -> ShowS)
-> (LayoutQualifierId -> String)
-> ([LayoutQualifierId] -> ShowS)
-> Show LayoutQualifierId
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LayoutQualifierId -> ShowS
showsPrec :: Int -> LayoutQualifierId -> ShowS
$cshow :: LayoutQualifierId -> String
show :: LayoutQualifierId -> String
$cshowList :: [LayoutQualifierId] -> ShowS
showList :: [LayoutQualifierId] -> ShowS
Show, LayoutQualifierId -> LayoutQualifierId -> Bool
(LayoutQualifierId -> LayoutQualifierId -> Bool)
-> (LayoutQualifierId -> LayoutQualifierId -> Bool)
-> Eq LayoutQualifierId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LayoutQualifierId -> LayoutQualifierId -> Bool
== :: LayoutQualifierId -> LayoutQualifierId -> Bool
$c/= :: LayoutQualifierId -> LayoutQualifierId -> Bool
/= :: LayoutQualifierId -> LayoutQualifierId -> Bool
Eq)

data Statement =
  -- declaration statement
    DeclarationStatement Declaration
  -- jump statement
  | Continue
  | Break
  | Return (Maybe Expr)
  | Discard -- fragment shader only
  -- compound statement
  | CompoundStatement Compound
  -- expression statement
  | ExpressionStatement (Maybe Expr)
  -- selection statement
  | SelectionStatement Expr Statement (Maybe Statement)
  -- switch statement
  | SwitchStatement Expr [Statement]
  | CaseLabel CaseLabel
  -- iteration statement
  | While Condition Statement -- no new scope
  | DoWhile Statement Expr
  | For (Either (Maybe Expr) Declaration) (Maybe Condition) (Maybe Expr) Statement
    -- 1st stmt: expression or declaration, 2nd: no new scope
  deriving (Int -> Statement -> ShowS
[Statement] -> ShowS
Statement -> String
(Int -> Statement -> ShowS)
-> (Statement -> String)
-> ([Statement] -> ShowS)
-> Show Statement
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Statement -> ShowS
showsPrec :: Int -> Statement -> ShowS
$cshow :: Statement -> String
show :: Statement -> String
$cshowList :: [Statement] -> ShowS
showList :: [Statement] -> ShowS
Show, Statement -> Statement -> Bool
(Statement -> Statement -> Bool)
-> (Statement -> Statement -> Bool) -> Eq Statement
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Statement -> Statement -> Bool
== :: Statement -> Statement -> Bool
$c/= :: Statement -> Statement -> Bool
/= :: Statement -> Statement -> Bool
Eq)

data Compound = Compound [Statement]
  deriving (Int -> Compound -> ShowS
[Compound] -> ShowS
Compound -> String
(Int -> Compound -> ShowS)
-> (Compound -> String) -> ([Compound] -> ShowS) -> Show Compound
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Compound -> ShowS
showsPrec :: Int -> Compound -> ShowS
$cshow :: Compound -> String
show :: Compound -> String
$cshowList :: [Compound] -> ShowS
showList :: [Compound] -> ShowS
Show, Compound -> Compound -> Bool
(Compound -> Compound -> Bool)
-> (Compound -> Compound -> Bool) -> Eq Compound
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Compound -> Compound -> Bool
== :: Compound -> Compound -> Bool
$c/= :: Compound -> Compound -> Bool
/= :: Compound -> Compound -> Bool
Eq)

data Condition =
    Condition Expr
  | InitializedCondition FullType String Expr -- assignment expression
  deriving (Int -> Condition -> ShowS
[Condition] -> ShowS
Condition -> String
(Int -> Condition -> ShowS)
-> (Condition -> String)
-> ([Condition] -> ShowS)
-> Show Condition
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Condition -> ShowS
showsPrec :: Int -> Condition -> ShowS
$cshow :: Condition -> String
show :: Condition -> String
$cshowList :: [Condition] -> ShowS
showList :: [Condition] -> ShowS
Show, Condition -> Condition -> Bool
(Condition -> Condition -> Bool)
-> (Condition -> Condition -> Bool) -> Eq Condition
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Condition -> Condition -> Bool
== :: Condition -> Condition -> Bool
$c/= :: Condition -> Condition -> Bool
/= :: Condition -> Condition -> Bool
Eq)

data CaseLabel = Case Expr | Default
  deriving (Int -> CaseLabel -> ShowS
[CaseLabel] -> ShowS
CaseLabel -> String
(Int -> CaseLabel -> ShowS)
-> (CaseLabel -> String)
-> ([CaseLabel] -> ShowS)
-> Show CaseLabel
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CaseLabel -> ShowS
showsPrec :: Int -> CaseLabel -> ShowS
$cshow :: CaseLabel -> String
show :: CaseLabel -> String
$cshowList :: [CaseLabel] -> ShowS
showList :: [CaseLabel] -> ShowS
Show, CaseLabel -> CaseLabel -> Bool
(CaseLabel -> CaseLabel -> Bool)
-> (CaseLabel -> CaseLabel -> Bool) -> Eq CaseLabel
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CaseLabel -> CaseLabel -> Bool
== :: CaseLabel -> CaseLabel -> Bool
$c/= :: CaseLabel -> CaseLabel -> Bool
/= :: CaseLabel -> CaseLabel -> Bool
Eq)

data StorageQualifier =
    Const
  | Attribute -- vertex only
  | Varying
  | CentroidVarying
  | In
  | Out
  | CentroidIn
  | CentroidOut
  | Uniform
  deriving (Int -> StorageQualifier -> ShowS
[StorageQualifier] -> ShowS
StorageQualifier -> String
(Int -> StorageQualifier -> ShowS)
-> (StorageQualifier -> String)
-> ([StorageQualifier] -> ShowS)
-> Show StorageQualifier
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> StorageQualifier -> ShowS
showsPrec :: Int -> StorageQualifier -> ShowS
$cshow :: StorageQualifier -> String
show :: StorageQualifier -> String
$cshowList :: [StorageQualifier] -> ShowS
showList :: [StorageQualifier] -> ShowS
Show, StorageQualifier -> StorageQualifier -> Bool
(StorageQualifier -> StorageQualifier -> Bool)
-> (StorageQualifier -> StorageQualifier -> Bool)
-> Eq StorageQualifier
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StorageQualifier -> StorageQualifier -> Bool
== :: StorageQualifier -> StorageQualifier -> Bool
$c/= :: StorageQualifier -> StorageQualifier -> Bool
/= :: StorageQualifier -> StorageQualifier -> Bool
Eq)

data TypeSpecifierNoPrecision = TypeSpecNoPrecision TypeSpecifierNonArray (Maybe (Maybe Expr)) -- constant expression
  deriving (Int -> TypeSpecifierNoPrecision -> ShowS
[TypeSpecifierNoPrecision] -> ShowS
TypeSpecifierNoPrecision -> String
(Int -> TypeSpecifierNoPrecision -> ShowS)
-> (TypeSpecifierNoPrecision -> String)
-> ([TypeSpecifierNoPrecision] -> ShowS)
-> Show TypeSpecifierNoPrecision
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TypeSpecifierNoPrecision -> ShowS
showsPrec :: Int -> TypeSpecifierNoPrecision -> ShowS
$cshow :: TypeSpecifierNoPrecision -> String
show :: TypeSpecifierNoPrecision -> String
$cshowList :: [TypeSpecifierNoPrecision] -> ShowS
showList :: [TypeSpecifierNoPrecision] -> ShowS
Show, TypeSpecifierNoPrecision -> TypeSpecifierNoPrecision -> Bool
(TypeSpecifierNoPrecision -> TypeSpecifierNoPrecision -> Bool)
-> (TypeSpecifierNoPrecision -> TypeSpecifierNoPrecision -> Bool)
-> Eq TypeSpecifierNoPrecision
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TypeSpecifierNoPrecision -> TypeSpecifierNoPrecision -> Bool
== :: TypeSpecifierNoPrecision -> TypeSpecifierNoPrecision -> Bool
$c/= :: TypeSpecifierNoPrecision -> TypeSpecifierNoPrecision -> Bool
/= :: TypeSpecifierNoPrecision -> TypeSpecifierNoPrecision -> Bool
Eq)

data TypeSpecifierNonArray =
    Void
  | Float
  | Int
  | UInt
  | Bool
  | Vec2
  | Vec3
  | Vec4
  | BVec2
  | BVec3
  | BVec4
  | IVec2
  | IVec3
  | IVec4
  | UVec2
  | UVec3
  | UVec4
  | Mat2
  | Mat3
  | Mat4
  | Mat2x2
  | Mat2x3
  | Mat2x4
  | Mat3x2
  | Mat3x3
  | Mat3x4
  | Mat4x2
  | Mat4x3
  | Mat4x4
  | Sampler1D
  | Sampler2D
  | Sampler3D
  | SamplerCube
  | Sampler1DShadow
  | Sampler2DShadow
  | SamplerCubeShadow
  | Sampler1DArray
  | Sampler2DArray
  | Sampler1DArrayShadow
  | Sampler2DArrayShadow
  | ISampler1D
  | ISampler2D
  | ISampler3D
  | ISamplerCube
  | ISampler1DArray
  | ISampler2DArray
  | USampler1D
  | USampler2D
  | USampler3D
  | USamplerCube
  | USampler1DArray
  | USampler2DArray
  | Sampler2DRect
  | Sampler2DRectShadow
  | ISampler2DRect
  | USampler2DRect
  | SamplerBuffer
  | ISamplerBuffer
  | USamplerBuffer
  | Sampler2DMS
  | ISampler2DMS
  | USampler2DMS
  | Sampler2DMSArray
  | ISampler2DMSArray
  | USampler2DMSArray
  | StructSpecifier (Maybe String) [Field]
  | TypeName String -- TODO user-defined type, should verify if it is declared
  deriving (Int -> TypeSpecifierNonArray -> ShowS
[TypeSpecifierNonArray] -> ShowS
TypeSpecifierNonArray -> String
(Int -> TypeSpecifierNonArray -> ShowS)
-> (TypeSpecifierNonArray -> String)
-> ([TypeSpecifierNonArray] -> ShowS)
-> Show TypeSpecifierNonArray
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TypeSpecifierNonArray -> ShowS
showsPrec :: Int -> TypeSpecifierNonArray -> ShowS
$cshow :: TypeSpecifierNonArray -> String
show :: TypeSpecifierNonArray -> String
$cshowList :: [TypeSpecifierNonArray] -> ShowS
showList :: [TypeSpecifierNonArray] -> ShowS
Show, TypeSpecifierNonArray -> TypeSpecifierNonArray -> Bool
(TypeSpecifierNonArray -> TypeSpecifierNonArray -> Bool)
-> (TypeSpecifierNonArray -> TypeSpecifierNonArray -> Bool)
-> Eq TypeSpecifierNonArray
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TypeSpecifierNonArray -> TypeSpecifierNonArray -> Bool
== :: TypeSpecifierNonArray -> TypeSpecifierNonArray -> Bool
$c/= :: TypeSpecifierNonArray -> TypeSpecifierNonArray -> Bool
/= :: TypeSpecifierNonArray -> TypeSpecifierNonArray -> Bool
Eq)

data PrecisionQualifier = HighP | MediumP | LowP
  deriving (Int -> PrecisionQualifier -> ShowS
[PrecisionQualifier] -> ShowS
PrecisionQualifier -> String
(Int -> PrecisionQualifier -> ShowS)
-> (PrecisionQualifier -> String)
-> ([PrecisionQualifier] -> ShowS)
-> Show PrecisionQualifier
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PrecisionQualifier -> ShowS
showsPrec :: Int -> PrecisionQualifier -> ShowS
$cshow :: PrecisionQualifier -> String
show :: PrecisionQualifier -> String
$cshowList :: [PrecisionQualifier] -> ShowS
showList :: [PrecisionQualifier] -> ShowS
Show, PrecisionQualifier -> PrecisionQualifier -> Bool
(PrecisionQualifier -> PrecisionQualifier -> Bool)
-> (PrecisionQualifier -> PrecisionQualifier -> Bool)
-> Eq PrecisionQualifier
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PrecisionQualifier -> PrecisionQualifier -> Bool
== :: PrecisionQualifier -> PrecisionQualifier -> Bool
$c/= :: PrecisionQualifier -> PrecisionQualifier -> Bool
/= :: PrecisionQualifier -> PrecisionQualifier -> Bool
Eq)

-- TODO The type qualifier can be present only when there is one or more declarators.
-- There other restrictions, see 4.1.8.
data Field = Field (Maybe TypeQualifier) TypeSpecifier [StructDeclarator]
  deriving (Int -> Field -> ShowS
[Field] -> ShowS
Field -> String
(Int -> Field -> ShowS)
-> (Field -> String) -> ([Field] -> ShowS) -> Show Field
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Field -> ShowS
showsPrec :: Int -> Field -> ShowS
$cshow :: Field -> String
show :: Field -> String
$cshowList :: [Field] -> ShowS
showList :: [Field] -> ShowS
Show, Field -> Field -> Bool
(Field -> Field -> Bool) -> (Field -> Field -> Bool) -> Eq Field
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Field -> Field -> Bool
== :: Field -> Field -> Bool
$c/= :: Field -> Field -> Bool
/= :: Field -> Field -> Bool
Eq)

data StructDeclarator = StructDeclarator String (Maybe (Maybe Expr)) -- constant expression
  deriving (Int -> StructDeclarator -> ShowS
[StructDeclarator] -> ShowS
StructDeclarator -> String
(Int -> StructDeclarator -> ShowS)
-> (StructDeclarator -> String)
-> ([StructDeclarator] -> ShowS)
-> Show StructDeclarator
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> StructDeclarator -> ShowS
showsPrec :: Int -> StructDeclarator -> ShowS
$cshow :: StructDeclarator -> String
show :: StructDeclarator -> String
$cshowList :: [StructDeclarator] -> ShowS
showList :: [StructDeclarator] -> ShowS
Show, StructDeclarator -> StructDeclarator -> Bool
(StructDeclarator -> StructDeclarator -> Bool)
-> (StructDeclarator -> StructDeclarator -> Bool)
-> Eq StructDeclarator
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StructDeclarator -> StructDeclarator -> Bool
== :: StructDeclarator -> StructDeclarator -> Bool
$c/= :: StructDeclarator -> StructDeclarator -> Bool
/= :: StructDeclarator -> StructDeclarator -> Bool
Eq)

data Expr =
  -- primaryExpression
    Variable String
  | IntConstant IntConstantKind Integer
  | FloatConstant Float
  | BoolConstant Bool
  -- postfixExpression
  | Bracket Expr Expr
  | FieldSelection Expr String
  | MethodCall Expr FunctionIdentifier Parameters
  | FunctionCall FunctionIdentifier Parameters
  | PostInc Expr
  | PostDec Expr
  | PreInc Expr
  | PreDec Expr
  -- unary expression
  | UnaryPlus Expr
  | UnaryNegate Expr
  | UnaryNot Expr
  | UnaryOneComplement Expr
  -- binary expression
  | Mul Expr Expr
  | Div Expr Expr
  | Mod Expr Expr
  | Add Expr Expr
  | Sub Expr Expr
  | LeftShift Expr Expr
  | RightShift Expr Expr
  | Lt Expr Expr
  | Gt Expr Expr
  | Lte Expr Expr
  | Gte Expr Expr
  | Equ Expr Expr
  | Neq Expr Expr
  | BitAnd Expr Expr
  | BitXor Expr Expr
  | BitOr Expr Expr
  | And Expr Expr
  | Or Expr Expr
  | Selection Expr Expr Expr -- ternary _ ? _ : _ operator
  -- assignment, the left Expr should be unary expression
  | Equal Expr Expr
  | MulAssign Expr Expr
  | DivAssign Expr Expr
  | ModAssign Expr Expr
  | AddAssign Expr Expr
  | SubAssign Expr Expr
  | LeftAssign Expr Expr
  | RightAssign Expr Expr
  | AndAssign Expr Expr
  | XorAssign Expr Expr
  | OrAssign Expr Expr
  -- sequence
  | Sequence Expr Expr
  deriving (Int -> Expr -> ShowS
[Expr] -> ShowS
Expr -> String
(Int -> Expr -> ShowS)
-> (Expr -> String) -> ([Expr] -> ShowS) -> Show Expr
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Expr -> ShowS
showsPrec :: Int -> Expr -> ShowS
$cshow :: Expr -> String
show :: Expr -> String
$cshowList :: [Expr] -> ShowS
showList :: [Expr] -> ShowS
Show, Expr -> Expr -> Bool
(Expr -> Expr -> Bool) -> (Expr -> Expr -> Bool) -> Eq Expr
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Expr -> Expr -> Bool
== :: Expr -> Expr -> Bool
$c/= :: Expr -> Expr -> Bool
/= :: Expr -> Expr -> Bool
Eq)

data IntConstantKind = Hexadecimal | Octal | Decimal
  deriving (Int -> IntConstantKind -> ShowS
[IntConstantKind] -> ShowS
IntConstantKind -> String
(Int -> IntConstantKind -> ShowS)
-> (IntConstantKind -> String)
-> ([IntConstantKind] -> ShowS)
-> Show IntConstantKind
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> IntConstantKind -> ShowS
showsPrec :: Int -> IntConstantKind -> ShowS
$cshow :: IntConstantKind -> String
show :: IntConstantKind -> String
$cshowList :: [IntConstantKind] -> ShowS
showList :: [IntConstantKind] -> ShowS
Show, IntConstantKind -> IntConstantKind -> Bool
(IntConstantKind -> IntConstantKind -> Bool)
-> (IntConstantKind -> IntConstantKind -> Bool)
-> Eq IntConstantKind
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IntConstantKind -> IntConstantKind -> Bool
== :: IntConstantKind -> IntConstantKind -> Bool
$c/= :: IntConstantKind -> IntConstantKind -> Bool
/= :: IntConstantKind -> IntConstantKind -> Bool
Eq)

data Parameters = ParamVoid | Params [Expr]
  deriving (Int -> Parameters -> ShowS
[Parameters] -> ShowS
Parameters -> String
(Int -> Parameters -> ShowS)
-> (Parameters -> String)
-> ([Parameters] -> ShowS)
-> Show Parameters
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Parameters -> ShowS
showsPrec :: Int -> Parameters -> ShowS
$cshow :: Parameters -> String
show :: Parameters -> String
$cshowList :: [Parameters] -> ShowS
showList :: [Parameters] -> ShowS
Show, Parameters -> Parameters -> Bool
(Parameters -> Parameters -> Bool)
-> (Parameters -> Parameters -> Bool) -> Eq Parameters
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Parameters -> Parameters -> Bool
== :: Parameters -> Parameters -> Bool
$c/= :: Parameters -> Parameters -> Bool
/= :: Parameters -> Parameters -> Bool
Eq)

data ParameterQualifier = InParameter | OutParameter | InOutParameter
  deriving (Int -> ParameterQualifier -> ShowS
[ParameterQualifier] -> ShowS
ParameterQualifier -> String
(Int -> ParameterQualifier -> ShowS)
-> (ParameterQualifier -> String)
-> ([ParameterQualifier] -> ShowS)
-> Show ParameterQualifier
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ParameterQualifier -> ShowS
showsPrec :: Int -> ParameterQualifier -> ShowS
$cshow :: ParameterQualifier -> String
show :: ParameterQualifier -> String
$cshowList :: [ParameterQualifier] -> ShowS
showList :: [ParameterQualifier] -> ShowS
Show, ParameterQualifier -> ParameterQualifier -> Bool
(ParameterQualifier -> ParameterQualifier -> Bool)
-> (ParameterQualifier -> ParameterQualifier -> Bool)
-> Eq ParameterQualifier
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ParameterQualifier -> ParameterQualifier -> Bool
== :: ParameterQualifier -> ParameterQualifier -> Bool
$c/= :: ParameterQualifier -> ParameterQualifier -> Bool
/= :: ParameterQualifier -> ParameterQualifier -> Bool
Eq)

data ParameterTypeQualifier = ConstParameter
  deriving (Int -> ParameterTypeQualifier -> ShowS
[ParameterTypeQualifier] -> ShowS
ParameterTypeQualifier -> String
(Int -> ParameterTypeQualifier -> ShowS)
-> (ParameterTypeQualifier -> String)
-> ([ParameterTypeQualifier] -> ShowS)
-> Show ParameterTypeQualifier
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ParameterTypeQualifier -> ShowS
showsPrec :: Int -> ParameterTypeQualifier -> ShowS
$cshow :: ParameterTypeQualifier -> String
show :: ParameterTypeQualifier -> String
$cshowList :: [ParameterTypeQualifier] -> ShowS
showList :: [ParameterTypeQualifier] -> ShowS
Show, ParameterTypeQualifier -> ParameterTypeQualifier -> Bool
(ParameterTypeQualifier -> ParameterTypeQualifier -> Bool)
-> (ParameterTypeQualifier -> ParameterTypeQualifier -> Bool)
-> Eq ParameterTypeQualifier
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ParameterTypeQualifier -> ParameterTypeQualifier -> Bool
== :: ParameterTypeQualifier -> ParameterTypeQualifier -> Bool
$c/= :: ParameterTypeQualifier -> ParameterTypeQualifier -> Bool
/= :: ParameterTypeQualifier -> ParameterTypeQualifier -> Bool
Eq)

data FunctionIdentifier =
    -- TODO could be refine (I think a precision qualifier is not permitted,
    -- nor a complete struct definition)
    FuncIdTypeSpec TypeSpecifier
  | FuncId String
  deriving (Int -> FunctionIdentifier -> ShowS
[FunctionIdentifier] -> ShowS
FunctionIdentifier -> String
(Int -> FunctionIdentifier -> ShowS)
-> (FunctionIdentifier -> String)
-> ([FunctionIdentifier] -> ShowS)
-> Show FunctionIdentifier
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FunctionIdentifier -> ShowS
showsPrec :: Int -> FunctionIdentifier -> ShowS
$cshow :: FunctionIdentifier -> String
show :: FunctionIdentifier -> String
$cshowList :: [FunctionIdentifier] -> ShowS
showList :: [FunctionIdentifier] -> ShowS
Show, FunctionIdentifier -> FunctionIdentifier -> Bool
(FunctionIdentifier -> FunctionIdentifier -> Bool)
-> (FunctionIdentifier -> FunctionIdentifier -> Bool)
-> Eq FunctionIdentifier
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: FunctionIdentifier -> FunctionIdentifier -> Bool
== :: FunctionIdentifier -> FunctionIdentifier -> Bool
$c/= :: FunctionIdentifier -> FunctionIdentifier -> Bool
/= :: FunctionIdentifier -> FunctionIdentifier -> Bool
Eq)