    module Language.GLSL.Parser where

    import Prelude hiding (break, exponent)

    import Text.ParserCombinators.Parsec hiding (State, parse)
    import Text.ParserCombinators.Parsec.Expr

    import Language.GLSL.Syntax

    ----------------------------------------------------------------------
    -- Parser state, hold a symbol table.
    ----------------------------------------------------------------------

    data S = S

    type P a = GenParser Char S a

    ----------------------------------------------------------------------
    -- Reserved words
    ----------------------------------------------------------------------

    -- List of keywords.
    keywords :: [String]
    keywords :: [[Char]]
    keywords = [[[Char]]] -> [[Char]]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[[Char]]] -> [[Char]]) -> [[[Char]]] -> [[Char]]
    forall a b. (a -> b) -> a -> b
    $ ([Char] -> [[Char]]) -> [[Char]] -> [[[Char]]]
    forall a b. (a -> b) -> [a] -> [b]
    map [Char] -> [[Char]]
    words ([[Char]] -> [[[Char]]]) -> [[Char]] -> [[[Char]]]
    forall a b. (a -> b) -> a -> b
    $
      [ [Char]
    "attribute const uniform varying"
      , [Char]
    "layout"
      , [Char]
    "centroid flat smooth noperspective"
      , [Char]
    "break continue do for while switch case default"
      , [Char]
    "if else"
      , [Char]
    "in out inout"
      , [Char]
    "float int void bool true false"
      , [Char]
    "invariant"
      , [Char]
    "discard return"
      , [Char]
    "mat2 mat3 mat4"
      , [Char]
    "mat2x2 mat2x3 mat2x4"
      , [Char]
    "mat3x2 mat3x3 mat3x4"
      , [Char]
    "mat4x2 mat4x3 mat4x4"
      , [Char]
    "vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4"
      , [Char]
    "uint uvec2 uvec3 uvec4"
      , [Char]
    "lowp mediump highp precision"
      , [Char]
    "sampler1D sampler2D sampler3D samplerCube"
      , [Char]
    "sampler1DShadow sampler2DShadow samplerCubeShadow"
      , [Char]
    "sampler1DArray sampler2DArray"
      , [Char]
    "sampler1DArrayShadow sampler2DArrayShadow"
      , [Char]
    "isampler1D isampler2D isampler3D isamplerCube"
      , [Char]
    "isampler1DArray isampler2DArray"
      , [Char]
    "usampler1D usampler2D usampler3D usamplerCube"
      , [Char]
    "usampler1DArray usampler2DArray"
      , [Char]
    "sampler2DRect sampler2DRectShadow isampler2DRect usampler2DRect"
      , [Char]
    "samplerBuffer isamplerBuffer usamplerBuffer"
      , [Char]
    "sampler2DMS isampler2DMS usampler2DMS"
      , [Char]
    "sampler2DMSArray isampler2DMSArray usampler2DMSArray"
      , [Char]
    "struct"
      ]

    -- List of keywords reserved for future use.
    reservedWords :: [String]
    reservedWords :: [[Char]]
    reservedWords = [[[Char]]] -> [[Char]]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[[Char]]] -> [[Char]]) -> [[[Char]]] -> [[Char]]
    forall a b. (a -> b) -> a -> b
    $ ([Char] -> [[Char]]) -> [[Char]] -> [[[Char]]]
    forall a b. (a -> b) -> [a] -> [b]
    map [Char] -> [[Char]]
    words ([[Char]] -> [[[Char]]]) -> [[Char]] -> [[[Char]]]
    forall a b. (a -> b) -> a -> b
    $
      [ [Char]
    "common partition active"
      , [Char]
    "asm"
      , [Char]
    "class union enum typedef template this packed"
      , [Char]
    "goto"
      , [Char]
    "inline noinline volatile public static extern external interface"
      , [Char]
    "long short double half fixed unsigned superp"
      , [Char]
    "input output"
      , [Char]
    "hvec2 hvec3 hvec4 dvec2 dvec3 dvec4 fvec2 fvec3 fvec4"
      , [Char]
    "sampler3DRect"
      , [Char]
    "filter"
      , [Char]
    "image1D image2D image3D imageCube"
      , [Char]
    "iimage1D iimage2D iimage3D iimageCube"
      , [Char]
    "uimage1D uimage2D uimage3D uimageCube"
      , [Char]
    "image1DArray image2DArray"
      , [Char]
    "iimage1DArray iimage2DArray uimage1DArray uimage2DArray"
      , [Char]
    "image1DShadow image2DShadow"
      , [Char]
    "image1DArrayShadow image2DArrayShadow"
      , [Char]
    "imageBuffer iimageBuffer uimageBuffer"
      , [Char]
    "sizeof cast"
      , [Char]
    "namespace using"
      , [Char]
    "row_major"
      ]

    ----------------------------------------------------------------------
    -- Convenience parsers
    ----------------------------------------------------------------------

    comment :: P ()
    comment :: P ()
    comment = do
      _ <- Char -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '/'
      _ <- choice
        [ do _ <- char '*'
             manyTill anyChar (try $ string "*/")
        , do _ <- char '/'
             manyTill anyChar ((newline >> return ()) <|> eof)
        ]
      return ()

    blank :: P ()
    blank :: P ()
    blank = P () -> P ()
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try P ()
    comment P () -> P () -> P ()
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> (ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
    space ParsecT [Char] S Identity Char -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> () -> P ()
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ())

    -- Acts like p and discards any following space character.
    lexeme :: P a -> P a
    lexeme :: forall a. P a -> P a
    lexeme P a
    p = do
      x <- P a
    p
      skipMany blank
      return x

    parse :: [Char] -> Either ParseError TranslationUnit
    parse :: [Char] -> Either ParseError TranslationUnit
    parse =
      GenParser Char S TranslationUnit
    -> S -> [Char] -> [Char] -> Either ParseError TranslationUnit
    forall tok st a.
    GenParser tok st a -> st -> [Char] -> [tok] -> Either ParseError a
    runParser (do {P () -> P ()
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
    skipMany P ()
    blank ; r <- GenParser Char S TranslationUnit
    translationUnit ; eof ; return r})
        S
    S [Char]
    "GLSL"

    ----------------------------------------------------------------------
    -- Lexical elements (tokens)
    ----------------------------------------------------------------------

    semicolon :: P ()
    semicolon :: P ()
    semicolon = P () -> P ()
    forall a. P a -> P a
    lexeme (P () -> P ()) -> P () -> P ()
    forall a b. (a -> b) -> a -> b
    $ Char -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    ';' ParsecT [Char] S Identity Char -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> () -> P ()
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    comma :: P ()
    comma :: P ()
    comma = P () -> P ()
    forall a. P a -> P a
    lexeme (P () -> P ()) -> P () -> P ()
    forall a b. (a -> b) -> a -> b
    $ Char -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    ',' ParsecT [Char] S Identity Char -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> () -> P ()
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    colon :: P ()
    colon :: P ()
    colon = P () -> P ()
    forall a. P a -> P a
    lexeme (P () -> P ()) -> P () -> P ()
    forall a b. (a -> b) -> a -> b
    $ Char -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    ':' ParsecT [Char] S Identity Char -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> () -> P ()
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    lbrace :: P ()
    lbrace :: P ()
    lbrace = P () -> P ()
    forall a. P a -> P a
    lexeme (P () -> P ()) -> P () -> P ()
    forall a b. (a -> b) -> a -> b
    $ Char -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '{' ParsecT [Char] S Identity Char -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> () -> P ()
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    rbrace :: P ()
    rbrace :: P ()
    rbrace = P () -> P ()
    forall a. P a -> P a
    lexeme (P () -> P ()) -> P () -> P ()
    forall a b. (a -> b) -> a -> b
    $ Char -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '}' ParsecT [Char] S Identity Char -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> () -> P ()
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    lbracket :: P ()
    lbracket :: P ()
    lbracket = P () -> P ()
    forall a. P a -> P a
    lexeme (P () -> P ()) -> P () -> P ()
    forall a b. (a -> b) -> a -> b
    $ Char -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '[' ParsecT [Char] S Identity Char -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> () -> P ()
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    rbracket :: P ()
    rbracket :: P ()
    rbracket = P () -> P ()
    forall a. P a -> P a
    lexeme (P () -> P ()) -> P () -> P ()
    forall a b. (a -> b) -> a -> b
    $ Char -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    ']' ParsecT [Char] S Identity Char -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> () -> P ()
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    lparen :: P ()
    lparen :: P ()
    lparen = P () -> P ()
    forall a. P a -> P a
    lexeme (P () -> P ()) -> P () -> P ()
    forall a b. (a -> b) -> a -> b
    $ Char -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '(' ParsecT [Char] S Identity Char -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> () -> P ()
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    rparen :: P ()
    rparen :: P ()
    rparen = P () -> P ()
    forall a. P a -> P a
    lexeme (P () -> P ()) -> P () -> P ()
    forall a b. (a -> b) -> a -> b
    $ Char -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    ')' ParsecT [Char] S Identity Char -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> () -> P ()
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    -- Try to parse a given string, making sure it is not a
    -- prefix of an identifier.
    keyword :: String -> P ()
    keyword :: [Char] -> P ()
    keyword [Char]
    w = P () -> P ()
    forall a. P a -> P a
    lexeme (P () -> P ()) -> P () -> P ()
    forall a b. (a -> b) -> a -> b
    $ P () -> P ()
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try ([Char] -> ParsecT [Char] S Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    w ParsecT [Char] S Identity [Char] -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> ParsecT [Char] S Identity Char -> P ()
    forall s (m :: * -> *) t a u.
    (Stream s m t, Show a) =>
    ParsecT s u m a -> ParsecT s u m ()
    notFollowedBy ParsecT [Char] S Identity Char
    identifierTail)

    -- Parses and returns an identifier.
    -- TODO an identifier can't start with "gl_" unless
    -- it is to redeclare a predeclared "gl_" identifier.
    identifier :: P String
    identifier :: ParsecT [Char] S Identity [Char]
    identifier = ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall a. P a -> P a
    lexeme (ParsecT [Char] S Identity [Char]
     -> ParsecT [Char] S Identity [Char])
    -> ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall a b. (a -> b) -> a -> b
    $ do
      h <- ParsecT [Char] S Identity Char
    identifierHead
      t <- many identifierTail
      check (h:t)
      where check :: [Char] -> m [Char]
    check [Char]
    i | [Char]
    i [Char] -> [[Char]] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [[Char]]
    reservedWords = [Char] -> m [Char]
    forall a. [Char] -> m a
    forall (m :: * -> *) a. MonadFail m => [Char] -> m a
    fail ([Char] -> m [Char]) -> [Char] -> m [Char]
    forall a b. (a -> b) -> a -> b
    $
              [Char]
    i [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " is reserved"
                    | [Char]
    i [Char] -> [[Char]] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [[Char]]
    keywords = [Char] -> m [Char]
    forall a. [Char] -> m a
    forall (m :: * -> *) a. MonadFail m => [Char] -> m a
    fail ([Char] -> m [Char]) -> [Char] -> m [Char]
    forall a b. (a -> b) -> a -> b
    $
              [Char]
    i [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " is a keyword"
                    | Bool
    otherwise = [Char] -> [Char] -> m [Char]
    forall {m :: * -> *}. MonadFail m => [Char] -> [Char] -> m [Char]
    checkUnderscore [Char]
    i [Char]
    i
            checkUnderscore :: [Char] -> [Char] -> m [Char]
    checkUnderscore [Char]
    i (Char
    '_':Char
    '_':[Char]
    _) = [Char] -> m [Char]
    forall a. [Char] -> m a
    forall (m :: * -> *) a. MonadFail m => [Char] -> m a
    fail ([Char] -> m [Char]) -> [Char] -> m [Char]
    forall a b. (a -> b) -> a -> b
    $
              [Char]
    i [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " is reserved (two consecutive underscores)"
            checkUnderscore [Char]
    i (Char
    _:[Char]
    cs) = [Char] -> [Char] -> m [Char]
    checkUnderscore [Char]
    i [Char]
    cs
            checkUnderscore [Char]
    i [] = [Char] -> m [Char]
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return [Char]
    i

    -- TODO the size of the int should fit its type.
    intConstant :: P Expr
    intConstant :: P Expr
    intConstant = [P Expr] -> P Expr
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ P Expr
    hexadecimal
      , P Expr
    octal
      , P ()
    badOctal P () -> P Expr -> P Expr
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> [Char] -> P Expr
    forall a. [Char] -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. MonadFail m => [Char] -> m a
    fail [Char]
    "Invalid octal number"
      , P Expr
    decimal
      ]

    floatingConstant :: P Expr
    floatingConstant :: P Expr
    floatingConstant = [P Expr] -> P Expr
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ P Expr
    floatExponent
      , P Expr
    floatPoint
      , P Expr
    pointFloat
      ]

    -- Try to parse a given string, and allow identifier characters
    -- (or anything else) to directly follow.
    operator :: String -> P String
    operator :: [Char] -> ParsecT [Char] S Identity [Char]
    operator = ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall a. P a -> P a
    lexeme (ParsecT [Char] S Identity [Char]
     -> ParsecT [Char] S Identity [Char])
    -> ([Char] -> ParsecT [Char] S Identity [Char])
    -> [Char]
    -> ParsecT [Char] S Identity [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (ParsecT [Char] S Identity [Char]
     -> ParsecT [Char] S Identity [Char])
    -> ([Char] -> ParsecT [Char] S Identity [Char])
    -> [Char]
    -> ParsecT [Char] S Identity [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> ParsecT [Char] S Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string

    ----------------------------------------------------------------------
    -- Lexical elements helpers
    ----------------------------------------------------------------------

    identifierHead :: P Char
    identifierHead :: ParsecT [Char] S Identity Char
    identifierHead = ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
    letter ParsecT [Char] S Identity Char
    -> ParsecT [Char] S Identity Char -> ParsecT [Char] S Identity Char
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> Char -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '_'

    identifierTail :: P Char
    identifierTail :: ParsecT [Char] S Identity Char
    identifierTail = ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
    alphaNum ParsecT [Char] S Identity Char
    -> ParsecT [Char] S Identity Char -> ParsecT [Char] S Identity Char
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> Char -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '_'

    hexadecimal :: P Expr
    hexadecimal :: P Expr
    hexadecimal = P Expr -> P Expr
    forall a. P a -> P a
    lexeme (P Expr -> P Expr) -> P Expr -> P Expr
    forall a b. (a -> b) -> a -> b
    $ P Expr -> P Expr
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (P Expr -> P Expr) -> P Expr -> P Expr
    forall a b. (a -> b) -> a -> b
    $ do
      _ <- Char -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '0'
      _ <- oneOf "Xx"
      d <- many1 hexDigit
      m <- optionMaybe $ oneOf "Uu" -- TODO
      return $ IntConstant Hexadecimal $ read ("0x" ++ d)

    octal :: P Expr
    octal :: P Expr
    octal = P Expr -> P Expr
    forall a. P a -> P a
    lexeme (P Expr -> P Expr) -> P Expr -> P Expr
    forall a b. (a -> b) -> a -> b
    $ P Expr -> P Expr
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (P Expr -> P Expr) -> P Expr -> P Expr
    forall a b. (a -> b) -> a -> b
    $ do
      _ <- Char -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '0'
      d <- many1 octDigit
      m <- optionMaybe $ oneOf "Uu" -- TODO
      return $ IntConstant Octal $ read  ("0o" ++ d)

    badOctal :: P ()
    badOctal :: P ()
    badOctal = P () -> P ()
    forall a. P a -> P a
    lexeme (P () -> P ()) -> P () -> P ()
    forall a b. (a -> b) -> a -> b
    $ P () -> P ()
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try  (P () -> P ()) -> P () -> P ()
    forall a b. (a -> b) -> a -> b
    $ Char -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '0' ParsecT [Char] S Identity Char
    -> ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> ParsecT [Char] S Identity Char -> ParsecT [Char] S Identity [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many1 ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
    hexDigit ParsecT [Char] S Identity [Char] -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> () -> P ()
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    decimal :: P Expr
    decimal :: P Expr
    decimal = P Expr -> P Expr
    forall a. P a -> P a
    lexeme (P Expr -> P Expr) -> P Expr -> P Expr
    forall a b. (a -> b) -> a -> b
    $ P Expr -> P Expr
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (P Expr -> P Expr) -> P Expr -> P Expr
    forall a b. (a -> b) -> a -> b
    $ do
      d <- ParsecT [Char] S Identity Char -> ParsecT [Char] S Identity [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many1 ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
    digit
      notFollowedBy (char '.' <|> (exponent >> return ' '))
      m <- optionMaybe $ oneOf "Uu" -- TODO
      return $ IntConstant Decimal $ read d

    floatExponent :: P Expr
    floatExponent :: P Expr
    floatExponent = P Expr -> P Expr
    forall a. P a -> P a
    lexeme (P Expr -> P Expr) -> P Expr -> P Expr
    forall a b. (a -> b) -> a -> b
    $ P Expr -> P Expr
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (P Expr -> P Expr) -> P Expr -> P Expr
    forall a b. (a -> b) -> a -> b
    $ do
      d <- ParsecT [Char] S Identity Char -> ParsecT [Char] S Identity [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many1 ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
    digit
      e <- exponent
      m <- optionMaybe $ oneOf "Ff" -- TODO
      return $ FloatConstant $ read $ d ++ e

    floatPoint :: P Expr
    floatPoint :: P Expr
    floatPoint = P Expr -> P Expr
    forall a. P a -> P a
    lexeme (P Expr -> P Expr) -> P Expr -> P Expr
    forall a b. (a -> b) -> a -> b
    $ P Expr -> P Expr
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (P Expr -> P Expr) -> P Expr -> P Expr
    forall a b. (a -> b) -> a -> b
    $ do
      d <- ParsecT [Char] S Identity Char -> ParsecT [Char] S Identity [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many1 ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
    digit
      _ <- char '.'
      d' <- many digit
      let d'' = if [Char] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Char]
    d' then [Char]
    "0" else [Char]
    d'
      e <- optionMaybe exponent
      m <- optionMaybe $ oneOf "Ff" -- TODO
      return $ FloatConstant $ read $ d ++ "." ++ d'' ++ maybe "" id e

    pointFloat :: P Expr
    pointFloat :: P Expr
    pointFloat = P Expr -> P Expr
    forall a. P a -> P a
    lexeme (P Expr -> P Expr) -> P Expr -> P Expr
    forall a b. (a -> b) -> a -> b
    $ P Expr -> P Expr
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (P Expr -> P Expr) -> P Expr -> P Expr
    forall a b. (a -> b) -> a -> b
    $ do
      _ <- Char -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '.'
      d <- many1 digit
      e <- optionMaybe exponent
      m <- optionMaybe $ oneOf "Ff"
      return $ FloatConstant $ read $ "0." ++ d ++ maybe "" id e

    exponent :: P String
    exponent :: ParsecT [Char] S Identity [Char]
    exponent = ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall a. P a -> P a
    lexeme (ParsecT [Char] S Identity [Char]
     -> ParsecT [Char] S Identity [Char])
    -> ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall a b. (a -> b) -> a -> b
    $ ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (ParsecT [Char] S Identity [Char]
     -> ParsecT [Char] S Identity [Char])
    -> ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall a b. (a -> b) -> a -> b
    $ do
      _ <- [Char] -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m Char
    oneOf [Char]
    "Ee"
      s <- optionMaybe (oneOf "+-")
      d <- many1 digit
      return $ "e" ++ maybe "" (:[]) s ++ d

    ----------------------------------------------------------------------
    -- Tables for buildExpressionParser
    ----------------------------------------------------------------------

    infixLeft :: String -> (a -> a -> a) -> Operator Char S a
    infixLeft :: forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixLeft [Char]
    s a -> a -> a
    r = GenParser Char S (a -> a -> a) -> Assoc -> Operator Char S a
    forall tok st a.
    GenParser tok st (a -> a -> a) -> Assoc -> Operator tok st a
    Infix (ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall a. P a -> P a
    lexeme (ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (ParsecT [Char] S Identity [Char]
     -> ParsecT [Char] S Identity [Char])
    -> ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall a b. (a -> b) -> a -> b
    $ [Char] -> ParsecT [Char] S Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    s) ParsecT [Char] S Identity [Char]
    -> GenParser Char S (a -> a -> a) -> GenParser Char S (a -> a -> a)
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> (a -> a -> a) -> GenParser Char S (a -> a -> a)
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return a -> a -> a
    r) Assoc
    AssocLeft

    infixLeft' :: String -> (a -> a -> a) -> Operator Char S a
    infixLeft' :: forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixLeft' [Char]
    s a -> a -> a
    r = GenParser Char S (a -> a -> a) -> Assoc -> Operator Char S a
    forall tok st a.
    GenParser tok st (a -> a -> a) -> Assoc -> Operator tok st a
    Infix (P () -> P ()
    forall a. P a -> P a
    lexeme (P () -> P ()
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (P () -> P ()) -> P () -> P ()
    forall a b. (a -> b) -> a -> b
    $ [Char] -> ParsecT [Char] S Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    s ParsecT [Char] S Identity [Char] -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> ParsecT [Char] S Identity Char -> P ()
    forall s (m :: * -> *) t a u.
    (Stream s m t, Show a) =>
    ParsecT s u m a -> ParsecT s u m ()
    notFollowedBy (Char -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '=')) P ()
    -> GenParser Char S (a -> a -> a) -> GenParser Char S (a -> a -> a)
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> (a -> a -> a) -> GenParser Char S (a -> a -> a)
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return a -> a -> a
    r) Assoc
    AssocLeft

    infixLeft'' :: Char -> (a -> a -> a) -> Operator Char S a
    infixLeft'' :: forall a. Char -> (a -> a -> a) -> Operator Char S a
    infixLeft'' Char
    c a -> a -> a
    r = GenParser Char S (a -> a -> a) -> Assoc -> Operator Char S a
    forall tok st a.
    GenParser tok st (a -> a -> a) -> Assoc -> Operator tok st a
    Infix (P () -> P ()
    forall a. P a -> P a
    lexeme (P () -> P ()
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (P () -> P ()) -> P () -> P ()
    forall a b. (a -> b) -> a -> b
    $ Char -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    c ParsecT [Char] S Identity Char -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> ParsecT [Char] S Identity Char -> P ()
    forall s (m :: * -> *) t a u.
    (Stream s m t, Show a) =>
    ParsecT s u m a -> ParsecT s u m ()
    notFollowedBy ([Char] -> ParsecT [Char] S Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m Char
    oneOf (Char
    cChar -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    :[Char]
    "="))) P ()
    -> GenParser Char S (a -> a -> a) -> GenParser Char S (a -> a -> a)
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> (a -> a -> a) -> GenParser Char S (a -> a -> a)
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return a -> a -> a
    r) Assoc
    AssocLeft

    infixRight :: String -> (a -> a -> a) -> Operator Char S a
    infixRight :: forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixRight [Char]
    s a -> a -> a
    r = GenParser Char S (a -> a -> a) -> Assoc -> Operator Char S a
    forall tok st a.
    GenParser tok st (a -> a -> a) -> Assoc -> Operator tok st a
    Infix (ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall a. P a -> P a
    lexeme (ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (ParsecT [Char] S Identity [Char]
     -> ParsecT [Char] S Identity [Char])
    -> ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall a b. (a -> b) -> a -> b
    $ [Char] -> ParsecT [Char] S Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    s) ParsecT [Char] S Identity [Char]
    -> GenParser Char S (a -> a -> a) -> GenParser Char S (a -> a -> a)
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> (a -> a -> a) -> GenParser Char S (a -> a -> a)
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return a -> a -> a
    r) Assoc
    AssocRight

    conditionalTable :: [[Operator Char S Expr]]
    conditionalTable :: [[Operator Char S Expr]]
    conditionalTable =
      [ [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixLeft' [Char]
    "*" Expr -> Expr -> Expr
    Mul, [Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixLeft' [Char]
    "/" Expr -> Expr -> Expr
    Div, [Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixLeft' [Char]
    "%" Expr -> Expr -> Expr
    Mod]
      , [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixLeft' [Char]
    "+" Expr -> Expr -> Expr
    Add, [Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixLeft' [Char]
    "-" Expr -> Expr -> Expr
    Sub]
      , [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixLeft' [Char]
    "<<" Expr -> Expr -> Expr
    LeftShift, [Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixLeft' [Char]
    ">>" Expr -> Expr -> Expr
    RightShift]
      , [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixLeft' [Char]
    "<" Expr -> Expr -> Expr
    Lt, [Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixLeft' [Char]
    ">" Expr -> Expr -> Expr
    Gt
        ,[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixLeft [Char]
    "<=" Expr -> Expr -> Expr
    Lte, [Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixLeft [Char]
    ">=" Expr -> Expr -> Expr
    Gte]
      , [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixLeft [Char]
    "==" Expr -> Expr -> Expr
    Equ, [Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixLeft [Char]
    "!=" Expr -> Expr -> Expr
    Neq]
      , [Char -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. Char -> (a -> a -> a) -> Operator Char S a
    infixLeft'' Char
    '&' Expr -> Expr -> Expr
    BitAnd]
      , [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixLeft' [Char]
    "^" Expr -> Expr -> Expr
    BitXor]
      , [Char -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. Char -> (a -> a -> a) -> Operator Char S a
    infixLeft'' Char
    '|' Expr -> Expr -> Expr
    BitOr]
      , [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixLeft [Char]
    "&&" Expr -> Expr -> Expr
    And]
      , [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixLeft [Char]
    "||" Expr -> Expr -> Expr
    Or]
      ]

    assignmentTable :: [[Operator Char S Expr]]
    assignmentTable :: [[Operator Char S Expr]]
    assignmentTable =
      [ [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixRight [Char]
    "=" Expr -> Expr -> Expr
    Equal]
      , [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixRight [Char]
    "+=" Expr -> Expr -> Expr
    AddAssign]
      , [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixRight [Char]
    "-=" Expr -> Expr -> Expr
    SubAssign]
      , [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixRight [Char]
    "*=" Expr -> Expr -> Expr
    MulAssign]
      , [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixRight [Char]
    "/=" Expr -> Expr -> Expr
    DivAssign]
      , [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixRight [Char]
    "%=" Expr -> Expr -> Expr
    ModAssign]
      , [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixRight [Char]
    "<<=" Expr -> Expr -> Expr
    LeftAssign]
      , [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixRight [Char]
    ">>=" Expr -> Expr -> Expr
    RightAssign]
      , [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixRight [Char]
    "&=" Expr -> Expr -> Expr
    AndAssign]
      , [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixRight [Char]
    "^=" Expr -> Expr -> Expr
    XorAssign]
      , [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixRight [Char]
    "|=" Expr -> Expr -> Expr
    OrAssign]
      ]

    expressionTable :: [[Operator Char S Expr]]
    expressionTable :: [[Operator Char S Expr]]
    expressionTable =
      [ [[Char] -> (Expr -> Expr -> Expr) -> Operator Char S Expr
    forall a. [Char] -> (a -> a -> a) -> Operator Char S a
    infixLeft [Char]
    "," Expr -> Expr -> Expr
    Sequence]
      ]

    ----------------------------------------------------------------------
    -- Grammar
    ----------------------------------------------------------------------

    primaryExpression :: P Expr
    primaryExpression :: P Expr
    primaryExpression = [P Expr] -> P Expr
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ [Char] -> Expr
    Variable ([Char] -> Expr) -> ParsecT [Char] S Identity [Char] -> P Expr
    forall a b.
    (a -> b)
    -> ParsecT [Char] S Identity a -> ParsecT [Char] S Identity b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try ParsecT [Char] S Identity [Char]
    identifier
      -- int constant
      , P Expr
    intConstant
      -- uint constant
      -- float constant
      , P Expr
    floatingConstant
      -- bool constant
      , [Char] -> P ()
    keyword [Char]
    "true" P () -> P Expr -> P Expr
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Expr -> P Expr
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Bool -> Expr
    BoolConstant Bool
    True)
      , [Char] -> P ()
    keyword [Char]
    "false" P () -> P Expr -> P Expr
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Expr -> P Expr
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Bool -> Expr
    BoolConstant Bool
    False)
      -- expression within parentheses
      , P () -> P () -> P Expr -> P Expr
    forall s (m :: * -> *) t u open close a.
    Stream s m t =>
    ParsecT s u m open
    -> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
    between P ()
    lparen P ()
    rparen P Expr
    expression
      ]

    postfixExpression :: P Expr
    postfixExpression :: P Expr
    postfixExpression = do
      e <- P Expr -> P Expr
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (P (FunctionIdentifier, Parameters)
    functionCallGeneric P (FunctionIdentifier, Parameters)
    -> ((FunctionIdentifier, Parameters) -> P Expr) -> P Expr
    forall a b.
    ParsecT [Char] S Identity a
    -> (a -> ParsecT [Char] S Identity b)
    -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \(FunctionIdentifier
    i,Parameters
    p) -> Expr -> P Expr
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (FunctionIdentifier -> Parameters -> Expr
    FunctionCall FunctionIdentifier
    i Parameters
    p))
           P Expr -> P Expr -> P Expr
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> P Expr
    primaryExpression
      p <- many $ choice
        [ between lbracket rbracket integerExpression >>= return . flip Bracket
        , dotFunctionCallGeneric
        , dotFieldSelection
        , operator "++" >> return PostInc
        , operator "--" >> return PostDec
        ]
      return $ foldl (flip ($)) e p

    dotFunctionCallGeneric :: P (Expr -> Expr)
    dotFunctionCallGeneric :: ParsecT [Char] S Identity (Expr -> Expr)
    dotFunctionCallGeneric =
      P (FunctionIdentifier, Parameters)
    -> P (FunctionIdentifier, Parameters)
    forall a. P a -> P a
    lexeme (P (FunctionIdentifier, Parameters)
    -> P (FunctionIdentifier, Parameters)
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (P (FunctionIdentifier, Parameters)
     -> P (FunctionIdentifier, Parameters))
    -> P (FunctionIdentifier, Parameters)
    -> P (FunctionIdentifier, Parameters)
    forall a b. (a -> b) -> a -> b
    $ [Char] -> ParsecT [Char] S Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "." ParsecT [Char] S Identity [Char]
    -> P (FunctionIdentifier, Parameters)
    -> P (FunctionIdentifier, Parameters)
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> P (FunctionIdentifier, Parameters)
    functionCallGeneric) P (FunctionIdentifier, Parameters)
    -> ((FunctionIdentifier, Parameters)
        -> ParsecT [Char] S Identity (Expr -> Expr))
    -> ParsecT [Char] S Identity (Expr -> Expr)
    forall a b.
    ParsecT [Char] S Identity a
    -> (a -> ParsecT [Char] S Identity b)
    -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \(FunctionIdentifier
    i,Parameters
    p) -> (Expr -> Expr) -> ParsecT [Char] S Identity (Expr -> Expr)
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (\Expr
    e -> Expr -> FunctionIdentifier -> Parameters -> Expr
    MethodCall Expr
    e FunctionIdentifier
    i Parameters
    p)

    dotFieldSelection :: P (Expr -> Expr)
    dotFieldSelection :: ParsecT [Char] S Identity (Expr -> Expr)
    dotFieldSelection =
      ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall a. P a -> P a
    lexeme (ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (ParsecT [Char] S Identity [Char]
     -> ParsecT [Char] S Identity [Char])
    -> ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall a b. (a -> b) -> a -> b
    $ [Char] -> ParsecT [Char] S Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "." ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> ParsecT [Char] S Identity [Char]
    identifier) ParsecT [Char] S Identity [Char]
    -> ([Char] -> ParsecT [Char] S Identity (Expr -> Expr))
    -> ParsecT [Char] S Identity (Expr -> Expr)
    forall a b.
    ParsecT [Char] S Identity a
    -> (a -> ParsecT [Char] S Identity b)
    -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (Expr -> Expr) -> ParsecT [Char] S Identity (Expr -> Expr)
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((Expr -> Expr) -> ParsecT [Char] S Identity (Expr -> Expr))
    -> ([Char] -> Expr -> Expr)
    -> [Char]
    -> ParsecT [Char] S Identity (Expr -> Expr)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Expr -> [Char] -> Expr) -> [Char] -> Expr -> Expr
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip Expr -> [Char] -> Expr
    FieldSelection

    integerExpression :: P Expr
    integerExpression :: P Expr
    integerExpression = P Expr
    expression

    -- Those productions are pushed inside postfixExpression.
    -- functionCall = functionCallOrMethod
    -- functionCallOrMethod = functionCallGeneric <|> postfixExpression DOT functionCallGeneric

    functionCallGeneric :: P (FunctionIdentifier, Parameters)
    functionCallGeneric :: P (FunctionIdentifier, Parameters)
    functionCallGeneric = do
      i <- P FunctionIdentifier
    functionCallHeader
      p <- choice
        [ keyword "void" >> return ParamVoid
        , assignmentExpression `sepBy` comma >>= return . Params
        ]
      rparen
      return (i, p)

    -- Those productions are pushed inside functionCallGeneric.
    -- functionCallHeaderNoParameters = undefined
    -- functionCallHeaderWithParameters = undefined

    functionCallHeader :: P FunctionIdentifier
    functionCallHeader :: P FunctionIdentifier
    functionCallHeader = do
      i <- P FunctionIdentifier
    functionIdentifier
      lparen
      return i

    functionIdentifier :: P FunctionIdentifier
    functionIdentifier :: P FunctionIdentifier
    functionIdentifier = [P FunctionIdentifier] -> P FunctionIdentifier
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try ParsecT [Char] S Identity [Char]
    identifier ParsecT [Char] S Identity [Char]
    -> ([Char] -> P FunctionIdentifier) -> P FunctionIdentifier
    forall a b.
    ParsecT [Char] S Identity a
    -> (a -> ParsecT [Char] S Identity b)
    -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= FunctionIdentifier -> P FunctionIdentifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (FunctionIdentifier -> P FunctionIdentifier)
    -> ([Char] -> FunctionIdentifier) -> [Char] -> P FunctionIdentifier
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> FunctionIdentifier
    FuncId
      , P TypeSpecifier
    typeSpecifier P TypeSpecifier
    -> (TypeSpecifier -> P FunctionIdentifier) -> P FunctionIdentifier
    forall a b.
    ParsecT [Char] S Identity a
    -> (a -> ParsecT [Char] S Identity b)
    -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= FunctionIdentifier -> P FunctionIdentifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (FunctionIdentifier -> P FunctionIdentifier)
    -> (TypeSpecifier -> FunctionIdentifier)
    -> TypeSpecifier
    -> P FunctionIdentifier
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . TypeSpecifier -> FunctionIdentifier
    FuncIdTypeSpec -- TODO if the 'identifier' is declared as a type, should be this case
      -- no need for fieldSelection
      ]

    unaryExpression :: P Expr
    unaryExpression :: P Expr
    unaryExpression = do
      p <- ParsecT [Char] S Identity (Expr -> Expr)
    -> ParsecT [Char] S Identity [Expr -> Expr]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many (ParsecT [Char] S Identity (Expr -> Expr)
     -> ParsecT [Char] S Identity [Expr -> Expr])
    -> ParsecT [Char] S Identity (Expr -> Expr)
    -> ParsecT [Char] S Identity [Expr -> Expr]
    forall a b. (a -> b) -> a -> b
    $ [ParsecT [Char] S Identity (Expr -> Expr)]
    -> ParsecT [Char] S Identity (Expr -> Expr)
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
        [ [Char] -> ParsecT [Char] S Identity [Char]
    operator [Char]
    "++" ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity (Expr -> Expr)
    -> ParsecT [Char] S Identity (Expr -> Expr)
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> (Expr -> Expr) -> ParsecT [Char] S Identity (Expr -> Expr)
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Expr -> Expr
    PreInc
        , [Char] -> ParsecT [Char] S Identity [Char]
    operator [Char]
    "--" ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity (Expr -> Expr)
    -> ParsecT [Char] S Identity (Expr -> Expr)
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> (Expr -> Expr) -> ParsecT [Char] S Identity (Expr -> Expr)
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Expr -> Expr
    PreDec
        , [Char] -> ParsecT [Char] S Identity [Char]
    operator [Char]
    "+" ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity (Expr -> Expr)
    -> ParsecT [Char] S Identity (Expr -> Expr)
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> (Expr -> Expr) -> ParsecT [Char] S Identity (Expr -> Expr)
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Expr -> Expr
    UnaryPlus
        , [Char] -> ParsecT [Char] S Identity [Char]
    operator [Char]
    "-" ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity (Expr -> Expr)
    -> ParsecT [Char] S Identity (Expr -> Expr)
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> (Expr -> Expr) -> ParsecT [Char] S Identity (Expr -> Expr)
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Expr -> Expr
    UnaryNegate
        , [Char] -> ParsecT [Char] S Identity [Char]
    operator [Char]
    "!" ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity (Expr -> Expr)
    -> ParsecT [Char] S Identity (Expr -> Expr)
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> (Expr -> Expr) -> ParsecT [Char] S Identity (Expr -> Expr)
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Expr -> Expr
    UnaryNot
        , [Char] -> ParsecT [Char] S Identity [Char]
    operator [Char]
    "~" ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity (Expr -> Expr)
    -> ParsecT [Char] S Identity (Expr -> Expr)
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> (Expr -> Expr) -> ParsecT [Char] S Identity (Expr -> Expr)
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Expr -> Expr
    UnaryOneComplement
        ]
      e <- postfixExpression
      return $ foldr ($) e p

    -- inside unaryExpression
    -- unaryOperator = choice

    -- implemented throught buildExpressionParser
    -- multiplicativeExpression = undefined
    -- additiveExpression = undefined
    -- shiftExpression = undefined
    -- relationalExpression = undefined
    -- equalityExpression = undefined
    -- andExpression = undefined
    -- exclusiveOrExpression = undefined
    -- inclusiveOrExpression = undefined
    -- logicalAndExpression = undefined
    -- logicalXorExpression = undefined
    -- logicalOrExpression = undefined

    conditionalExpression :: P Expr
    conditionalExpression :: P Expr
    conditionalExpression = do
      loe <- [[Operator Char S Expr]] -> P Expr -> P Expr
    forall tok st a.
    OperatorTable tok st a -> GenParser tok st a -> GenParser tok st a
    buildExpressionParser [[Operator Char S Expr]]
    conditionalTable P Expr
    unaryExpression
      ter <- optionMaybe $ do
        _ <- lexeme (string "?")
        e <- expression
        _ <- lexeme (string ":")
        a <- assignmentExpression
        return (e, a)
      case ter of
        Maybe (Expr, Expr)
    Nothing -> Expr -> P Expr
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Expr
    loe
        Just (Expr
    e, Expr
    a) -> Expr -> P Expr
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Expr -> P Expr) -> Expr -> P Expr
    forall a b. (a -> b) -> a -> b
    $ Expr -> Expr -> Expr -> Expr
    Selection Expr
    loe Expr
    e Expr
    a

    assignmentExpression :: P Expr
    assignmentExpression :: P Expr
    assignmentExpression = [[Operator Char S Expr]] -> P Expr -> P Expr
    forall tok st a.
    OperatorTable tok st a -> GenParser tok st a -> GenParser tok st a
    buildExpressionParser [[Operator Char S Expr]]
    assignmentTable P Expr
    conditionalExpression

    expression :: P Expr
    expression :: P Expr
    expression = [[Operator Char S Expr]] -> P Expr -> P Expr
    forall tok st a.
    OperatorTable tok st a -> GenParser tok st a -> GenParser tok st a
    buildExpressionParser [[Operator Char S Expr]]
    expressionTable P Expr
    assignmentExpression

    constantExpression :: P Expr
    constantExpression :: P Expr
    constantExpression = P Expr
    conditionalExpression

    -- The GLSL grammar include here function definition but we don't
    -- do this here because they should occur only at top level (page 28).
    -- Function definitions are handled in externalDefinition instead.
    declaration :: P Declaration
    declaration :: P Declaration
    declaration = [P Declaration] -> P Declaration
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ P Declaration -> P Declaration
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (P Declaration -> P Declaration) -> P Declaration -> P Declaration
    forall a b. (a -> b) -> a -> b
    $ do
           t <- P FullType
    fullySpecifiedType
           l <- idecl `sepBy` comma
           semicolon
           return $ InitDeclaration (TypeDeclarator t) l
      , do [Char] -> P ()
    keyword [Char]
    "invariant"
           i <- ParsecT [Char] S Identity InitDeclarator
    idecl ParsecT [Char] S Identity InitDeclarator
    -> P () -> ParsecT [Char] S Identity [InitDeclarator]
    forall s (m :: * -> *) t u a end.
    Stream s m t =>
    ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
    `sepBy` P ()
    comma
           semicolon
           return $ InitDeclaration InvariantDeclarator i
      , do [Char] -> P ()
    keyword [Char]
    "precision"
           q <- P PrecisionQualifier
    precisionQualifier
           s <- typeSpecifierNoPrecision
           semicolon
           return $ Precision q s
      , do q <- P TypeQualifier
    typeQualifier
           choice
             [ semicolon >> return (TQ q)
             , do i <- identifier
                  lbrace
                  s <- structDeclarationList
                  rbrace
                  m <- optionMaybe $ do
                    j <- identifier
                    n <- optionMaybe $ between lbracket rbracket $ optionMaybe constantExpression
                    return (j,n)
                  semicolon
                  return $ Block q i s m
             ]
      ]
      where idecl :: ParsecT [Char] S Identity InitDeclarator
    idecl = do
              i <- ParsecT [Char] S Identity [Char]
    identifier
              m <- optionMaybe $ between lbracket rbracket $
                optionMaybe constantExpression
              j <- optionMaybe $ lexeme (string "=") >> initializer
              return $ InitDecl i m j

    functionPrototype :: P FunctionPrototype
    functionPrototype :: P FunctionPrototype
    functionPrototype = do
      (t, i, p) <- P (FullType, [Char], [ParameterDeclaration])
    functionDeclarator
      rparen
      return $ FuncProt t i p

    functionDeclarator :: P (FullType, String, [ParameterDeclaration])
    functionDeclarator :: P (FullType, [Char], [ParameterDeclaration])
    functionDeclarator = do
      (t, i) <- P (FullType, [Char])
    functionHeader
      p <- parameterDeclaration `sepBy` comma
      return (t, i, p)

    -- inside functionDeclarator
    -- functionHeaderWithParameters = undefined

    functionHeader :: P (FullType, String)
    functionHeader :: P (FullType, [Char])
    functionHeader = do
      t <- P FullType
    fullySpecifiedType
      i <- identifier
      lparen
      return (t, i)

    -- inside parameterDeclaration
    -- parameterDeclarator = undefined

    -- expanding parameterDeclarator and parameterTypeSpecifier, the rule is:
    -- parameterDeclaration:
    --   parameterTypeQualifier [parameterQualifier] typeSpecifier identifier[[e]]
    --                          [parameterQualifier] typeSpecifier identifier[[e]]
    --   parameterTypeQualifier [parameterQualifier] typeSpecifier
    --                          [parameterQualifier] typeSpecifier
    -- which is simply
    --   [parameterTypeQualifier] [parameterQualifier] typeSpecifier [identifier[[e]]]
    parameterDeclaration :: P ParameterDeclaration
    parameterDeclaration :: P ParameterDeclaration
    parameterDeclaration = do
      tq <- ParsecT [Char] S Identity ParameterTypeQualifier
    -> ParsecT [Char] S Identity (Maybe ParameterTypeQualifier)
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    ParsecT s u m a -> ParsecT s u m (Maybe a)
    optionMaybe ParsecT [Char] S Identity ParameterTypeQualifier
    parameterTypeQualifier
      q <- optionMaybe parameterQualifier
      s <- typeSpecifier
      m <- optionMaybe $ do
        i <- identifier
        b <- optionMaybe $ between lbracket rbracket constantExpression -- FIXME can't the bracket be empty, i.e. a[] ?
        return (i,b)
      return $ ParameterDeclaration tq q s m

    parameterQualifier :: P ParameterQualifier
    parameterQualifier :: ParsecT [Char] S Identity ParameterQualifier
    parameterQualifier = [ParsecT [Char] S Identity ParameterQualifier]
    -> ParsecT [Char] S Identity ParameterQualifier
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      -- "empty" case handled in the caller
      [ (ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (ParsecT [Char] S Identity [Char]
     -> ParsecT [Char] S Identity [Char])
    -> ([Char] -> ParsecT [Char] S Identity [Char])
    -> [Char]
    -> ParsecT [Char] S Identity [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall a. P a -> P a
    lexeme (ParsecT [Char] S Identity [Char]
     -> ParsecT [Char] S Identity [Char])
    -> ([Char] -> ParsecT [Char] S Identity [Char])
    -> [Char]
    -> ParsecT [Char] S Identity [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> ParsecT [Char] S Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string) [Char]
    "inout" ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity ParameterQualifier
    -> ParsecT [Char] S Identity ParameterQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> ParameterQualifier -> ParsecT [Char] S Identity ParameterQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ParameterQualifier
    InOutParameter
      , (ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (ParsecT [Char] S Identity [Char]
     -> ParsecT [Char] S Identity [Char])
    -> ([Char] -> ParsecT [Char] S Identity [Char])
    -> [Char]
    -> ParsecT [Char] S Identity [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall a. P a -> P a
    lexeme (ParsecT [Char] S Identity [Char]
     -> ParsecT [Char] S Identity [Char])
    -> ([Char] -> ParsecT [Char] S Identity [Char])
    -> [Char]
    -> ParsecT [Char] S Identity [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> ParsecT [Char] S Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string) [Char]
    "in" ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity ParameterQualifier
    -> ParsecT [Char] S Identity ParameterQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> ParameterQualifier -> ParsecT [Char] S Identity ParameterQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ParameterQualifier
    InParameter
      , (ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (ParsecT [Char] S Identity [Char]
     -> ParsecT [Char] S Identity [Char])
    -> ([Char] -> ParsecT [Char] S Identity [Char])
    -> [Char]
    -> ParsecT [Char] S Identity [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity [Char]
    forall a. P a -> P a
    lexeme (ParsecT [Char] S Identity [Char]
     -> ParsecT [Char] S Identity [Char])
    -> ([Char] -> ParsecT [Char] S Identity [Char])
    -> [Char]
    -> ParsecT [Char] S Identity [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> ParsecT [Char] S Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string) [Char]
    "out" ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity ParameterQualifier
    -> ParsecT [Char] S Identity ParameterQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> ParameterQualifier -> ParsecT [Char] S Identity ParameterQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ParameterQualifier
    OutParameter
      ]

    -- inside parameterDeclaration
    -- parameterTypeSpecifier = typeSpecifier

    -- FIXME not correct w.r.t. the specs.
    -- The specs allow
    --   int
    --   int, foo
    --   invariant foo, bar[]
    -- and disallow
    --   invariant bar[]

    -- It is not used, it is inside declaration.
    -- initDeclaratorList = undefined

    -- inside initDeclaratorList
    -- singleDeclaration = undefined

    fullySpecifiedType :: P FullType
    fullySpecifiedType :: P FullType
    fullySpecifiedType = [P FullType] -> P FullType
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ P TypeSpecifier -> P TypeSpecifier
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try P TypeSpecifier
    typeSpecifier P TypeSpecifier -> (TypeSpecifier -> P FullType) -> P FullType
    forall a b.
    ParsecT [Char] S Identity a
    -> (a -> ParsecT [Char] S Identity b)
    -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= FullType -> P FullType
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (FullType -> P FullType)
    -> (TypeSpecifier -> FullType) -> TypeSpecifier -> P FullType
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Maybe TypeQualifier -> TypeSpecifier -> FullType
    FullType Maybe TypeQualifier
    forall a. Maybe a
    Nothing
      , do q <- P TypeQualifier
    typeQualifier
           s <- typeSpecifier
           return $ FullType (Just q) s
      ]

    invariantQualifier :: P InvariantQualifier
    invariantQualifier :: P InvariantQualifier
    invariantQualifier = [Char] -> P ()
    keyword [Char]
    "invariant" P () -> P InvariantQualifier -> P InvariantQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> InvariantQualifier -> P InvariantQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return InvariantQualifier
    Invariant

    interpolationQualifier :: P InterpolationQualifier
    interpolationQualifier :: P InterpolationQualifier
    interpolationQualifier = [P InterpolationQualifier] -> P InterpolationQualifier
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ [Char] -> P ()
    keyword [Char]
    "smooth" P () -> P InterpolationQualifier -> P InterpolationQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> InterpolationQualifier -> P InterpolationQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return InterpolationQualifier
    Smooth
      , [Char] -> P ()
    keyword [Char]
    "flat" P () -> P InterpolationQualifier -> P InterpolationQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> InterpolationQualifier -> P InterpolationQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return InterpolationQualifier
    Flat
      , [Char] -> P ()
    keyword [Char]
    "noperspective" P () -> P InterpolationQualifier -> P InterpolationQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> InterpolationQualifier -> P InterpolationQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return InterpolationQualifier
    NoPerspective
      ]

    layoutQualifier :: P LayoutQualifier
    layoutQualifier :: P LayoutQualifier
    layoutQualifier = do
      [Char] -> P ()
    keyword [Char]
    "layout"
      P ()
    lparen
      q <- P LayoutQualifierId
    layoutQualifierId P LayoutQualifierId
    -> P () -> ParsecT [Char] S Identity [LayoutQualifierId]
    forall s (m :: * -> *) t u a end.
    Stream s m t =>
    ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
    `sepBy` P ()
    comma
      rparen
      return $ Layout q

    -- implemented directly in layoutQualifier
    -- layoutQualifierIdList = undefined

    layoutQualifierId :: P LayoutQualifierId
    layoutQualifierId :: P LayoutQualifierId
    layoutQualifierId = do
      i <- ParsecT [Char] S Identity [Char]
    identifier
      c <- optionMaybe $ lexeme (string "=") >> intConstant
      return $ LayoutQualId i c

    parameterTypeQualifier :: P ParameterTypeQualifier
    parameterTypeQualifier :: ParsecT [Char] S Identity ParameterTypeQualifier
    parameterTypeQualifier = [Char] -> P ()
    keyword [Char]
    "const" P ()
    -> ParsecT [Char] S Identity ParameterTypeQualifier
    -> ParsecT [Char] S Identity ParameterTypeQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> ParameterTypeQualifier
    -> ParsecT [Char] S Identity ParameterTypeQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ParameterTypeQualifier
    ConstParameter

    -- sto
    -- lay [sto]
    -- int [sto]
    -- inv [sto]
    -- inv int sto
    typeQualifier :: P TypeQualifier
    typeQualifier :: P TypeQualifier
    typeQualifier = [P TypeQualifier] -> P TypeQualifier
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ do s <- P StorageQualifier
    storageQualifier
           return $ TypeQualSto s
      , do l <- P LayoutQualifier
    layoutQualifier
           s <- optionMaybe storageQualifier
           return $ TypeQualLay l s
      , do i <- P InterpolationQualifier
    interpolationQualifier
           s <- optionMaybe storageQualifier
           return $ TypeQualInt i s
      , do i <- P InvariantQualifier
    invariantQualifier
           choice
             [ do j <- interpolationQualifier
                  s <- storageQualifier
                  return $ TypeQualInv3 i j s
             , do s <- optionMaybe storageQualifier
                  return $ TypeQualInv i s
             ]
      ]

    -- TODO see 4.3 for restrictions
    storageQualifier :: P StorageQualifier
    storageQualifier :: P StorageQualifier
    storageQualifier = [P StorageQualifier] -> P StorageQualifier
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ [Char] -> P ()
    keyword [Char]
    "const" P () -> P StorageQualifier -> P StorageQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> StorageQualifier -> P StorageQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return StorageQualifier
    Const
      , [Char] -> P ()
    keyword [Char]
    "attribute" P () -> P StorageQualifier -> P StorageQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> StorageQualifier -> P StorageQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return StorageQualifier
    Attribute -- TODO vertex only, is deprecated
      , [Char] -> P ()
    keyword [Char]
    "varying" P () -> P StorageQualifier -> P StorageQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> StorageQualifier -> P StorageQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return StorageQualifier
    Varying -- deprecated
      , [Char] -> P ()
    keyword [Char]
    "in" P () -> P StorageQualifier -> P StorageQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> StorageQualifier -> P StorageQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return StorageQualifier
    In
      , [Char] -> P ()
    keyword [Char]
    "out" P () -> P StorageQualifier -> P StorageQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> StorageQualifier -> P StorageQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return StorageQualifier
    Out
      , [Char] -> P ()
    keyword [Char]
    "centroid" P () -> P StorageQualifier -> P StorageQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> ([P StorageQualifier] -> P StorageQualifier
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
        [ [Char] -> P ()
    keyword [Char]
    "varying" P () -> P StorageQualifier -> P StorageQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> StorageQualifier -> P StorageQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return StorageQualifier
    CentroidVarying -- deprecated
        , [Char] -> P ()
    keyword [Char]
    "in" P () -> P StorageQualifier -> P StorageQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> StorageQualifier -> P StorageQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return StorageQualifier
    CentroidIn
        , [Char] -> P ()
    keyword [Char]
    "out" P () -> P StorageQualifier -> P StorageQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> StorageQualifier -> P StorageQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return StorageQualifier
    CentroidOut
        ])
      , [Char] -> P ()
    keyword [Char]
    "uniform" P () -> P StorageQualifier -> P StorageQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> StorageQualifier -> P StorageQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return StorageQualifier
    Uniform
      ]

    typeSpecifier :: P TypeSpecifier
    typeSpecifier :: P TypeSpecifier
    typeSpecifier = [P TypeSpecifier] -> P TypeSpecifier
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ do q <- P PrecisionQualifier -> P PrecisionQualifier
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try P PrecisionQualifier
    precisionQualifier
           s <- typeSpecifierNoPrecision
           return $ TypeSpec (Just q) s
      , P TypeSpecifierNoPrecision
    typeSpecifierNoPrecision P TypeSpecifierNoPrecision
    -> (TypeSpecifierNoPrecision -> P TypeSpecifier) -> P TypeSpecifier
    forall a b.
    ParsecT [Char] S Identity a
    -> (a -> ParsecT [Char] S Identity b)
    -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= TypeSpecifier -> P TypeSpecifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TypeSpecifier -> P TypeSpecifier)
    -> (TypeSpecifierNoPrecision -> TypeSpecifier)
    -> TypeSpecifierNoPrecision
    -> P TypeSpecifier
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Maybe PrecisionQualifier
    -> TypeSpecifierNoPrecision -> TypeSpecifier
    TypeSpec Maybe PrecisionQualifier
    forall a. Maybe a
    Nothing
      ]

    typeSpecifierNoPrecision :: P TypeSpecifierNoPrecision
    typeSpecifierNoPrecision :: P TypeSpecifierNoPrecision
    typeSpecifierNoPrecision = do
      s <- P TypeSpecifierNonArray
    typeSpecifierNonArray
      choice
        [ try (lbracket >> rbracket) >> return (TypeSpecNoPrecision s (Just Nothing))
        , lbracket >> constantExpression >>= \Expr
    c -> P ()
    rbracket P () -> P TypeSpecifierNoPrecision -> P TypeSpecifierNoPrecision
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNoPrecision -> P TypeSpecifierNoPrecision
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TypeSpecifierNonArray
    -> Maybe (Maybe Expr) -> TypeSpecifierNoPrecision
    TypeSpecNoPrecision TypeSpecifierNonArray
    s (Maybe Expr -> Maybe (Maybe Expr)
    forall a. a -> Maybe a
    Just (Maybe Expr -> Maybe (Maybe Expr))
    -> Maybe Expr -> Maybe (Maybe Expr)
    forall a b. (a -> b) -> a -> b
    $ Expr -> Maybe Expr
    forall a. a -> Maybe a
    Just Expr
    c))
        , return $ TypeSpecNoPrecision s Nothing
        ]

    -- Basic types, structs, and user-defined types.
    typeSpecifierNonArray :: P TypeSpecifierNonArray
    typeSpecifierNonArray :: P TypeSpecifierNonArray
    typeSpecifierNonArray = [P TypeSpecifierNonArray] -> P TypeSpecifierNonArray
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ [Char] -> P ()
    keyword [Char]
    "void" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Void
      , [Char] -> P ()
    keyword [Char]
    "float" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Float
      , [Char] -> P ()
    keyword [Char]
    "int" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Int
      , [Char] -> P ()
    keyword [Char]
    "uint" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    UInt
      , [Char] -> P ()
    keyword [Char]
    "bool" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Bool
      , [Char] -> P ()
    keyword [Char]
    "vec2" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Vec2
      , [Char] -> P ()
    keyword [Char]
    "vec3" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Vec3
      , [Char] -> P ()
    keyword [Char]
    "vec4" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Vec4
      , [Char] -> P ()
    keyword [Char]
    "bvec2" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    BVec2
      , [Char] -> P ()
    keyword [Char]
    "bvec3" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    BVec3
      , [Char] -> P ()
    keyword [Char]
    "bvec4" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    BVec4
      , [Char] -> P ()
    keyword [Char]
    "ivec2" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    IVec2
      , [Char] -> P ()
    keyword [Char]
    "ivec3" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    IVec3
      , [Char] -> P ()
    keyword [Char]
    "ivec4" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    IVec4
      , [Char] -> P ()
    keyword [Char]
    "uvec2" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    UVec2
      , [Char] -> P ()
    keyword [Char]
    "uvec3" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    UVec3
      , [Char] -> P ()
    keyword [Char]
    "uvec4" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    UVec4
      , [Char] -> P ()
    keyword [Char]
    "mat2" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Mat2
      , [Char] -> P ()
    keyword [Char]
    "mat3" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Mat3
      , [Char] -> P ()
    keyword [Char]
    "mat4" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Mat4
      , [Char] -> P ()
    keyword [Char]
    "mat2x2" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Mat2x2
      , [Char] -> P ()
    keyword [Char]
    "mat2x3" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Mat2x3
      , [Char] -> P ()
    keyword [Char]
    "mat2x4" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Mat2x4
      , [Char] -> P ()
    keyword [Char]
    "mat3x2" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Mat3x2
      , [Char] -> P ()
    keyword [Char]
    "mat3x3" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Mat3x3
      , [Char] -> P ()
    keyword [Char]
    "mat3x4" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Mat3x4
      , [Char] -> P ()
    keyword [Char]
    "mat4x2" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Mat4x2
      , [Char] -> P ()
    keyword [Char]
    "mat4x3" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Mat4x3
      , [Char] -> P ()
    keyword [Char]
    "mat4x4" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Mat4x4
      , [Char] -> P ()
    keyword [Char]
    "sampler1D" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Sampler1D
      , [Char] -> P ()
    keyword [Char]
    "sampler2D" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Sampler2D
      , [Char] -> P ()
    keyword [Char]
    "sampler3D" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Sampler3D
      , [Char] -> P ()
    keyword [Char]
    "samplerCube" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    SamplerCube
      , [Char] -> P ()
    keyword [Char]
    "sampler1DShadow" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Sampler1DShadow
      , [Char] -> P ()
    keyword [Char]
    "sampler2DShadow" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Sampler2DShadow
      , [Char] -> P ()
    keyword [Char]
    "samplerCubeShadow" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    SamplerCubeShadow
      , [Char] -> P ()
    keyword [Char]
    "sampler1DArray" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Sampler1DArray
      , [Char] -> P ()
    keyword [Char]
    "sampler2DArray" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Sampler2DArray
      , [Char] -> P ()
    keyword [Char]
    "sampler1DArrayShadow" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Sampler1DArrayShadow
      , [Char] -> P ()
    keyword [Char]
    "sampler2DArrayShadow" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Sampler2DArrayShadow
      , [Char] -> P ()
    keyword [Char]
    "isampler1D" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    ISampler1D
      , [Char] -> P ()
    keyword [Char]
    "isampler2D" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    ISampler2D
      , [Char] -> P ()
    keyword [Char]
    "isampler3D" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    ISampler3D
      , [Char] -> P ()
    keyword [Char]
    "isamplerCube" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    ISamplerCube
      , [Char] -> P ()
    keyword [Char]
    "isampler1DArray" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    ISampler1DArray
      , [Char] -> P ()
    keyword [Char]
    "isampler2DArray" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    ISampler2DArray
      , [Char] -> P ()
    keyword [Char]
    "usampler1D" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    USampler1D
      , [Char] -> P ()
    keyword [Char]
    "usampler2D" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    USampler2D
      , [Char] -> P ()
    keyword [Char]
    "usampler3D" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    USampler3D
      , [Char] -> P ()
    keyword [Char]
    "usamplerCube" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    USamplerCube
      , [Char] -> P ()
    keyword [Char]
    "usampler1DArray" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    USampler1DArray
      , [Char] -> P ()
    keyword [Char]
    "usampler2DArray" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    USampler2DArray
      , [Char] -> P ()
    keyword [Char]
    "sampler2DRect" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Sampler2DRect
      , [Char] -> P ()
    keyword [Char]
    "sampler2DRectShadow" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Sampler2DRectShadow
      , [Char] -> P ()
    keyword [Char]
    "isampler2DRect" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    ISampler2DRect
      , [Char] -> P ()
    keyword [Char]
    "usampler2DRect" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    USampler2DRect
      , [Char] -> P ()
    keyword [Char]
    "samplerBuffer" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    SamplerBuffer
      , [Char] -> P ()
    keyword [Char]
    "isamplerBuffer" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    ISamplerBuffer
      , [Char] -> P ()
    keyword [Char]
    "usamplerBuffer" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    USamplerBuffer
      , [Char] -> P ()
    keyword [Char]
    "sampler2DMS" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Sampler2DMS
      , [Char] -> P ()
    keyword [Char]
    "isampler2DMS" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    ISampler2DMS
      , [Char] -> P ()
    keyword [Char]
    "usampler2DMS" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    USampler2DMS
      , [Char] -> P ()
    keyword [Char]
    "sampler2DMSArray" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    Sampler2DMSArray
      , [Char] -> P ()
    keyword [Char]
    "isampler2DMSArray" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    ISampler2DMSArray
      , [Char] -> P ()
    keyword [Char]
    "usampler2DMSArray" P () -> P TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return TypeSpecifierNonArray
    USampler2DMSArray
      , P TypeSpecifierNonArray
    structSpecifier
      , ParsecT [Char] S Identity [Char]
    identifier ParsecT [Char] S Identity [Char]
    -> ([Char] -> P TypeSpecifierNonArray) -> P TypeSpecifierNonArray
    forall a b.
    ParsecT [Char] S Identity a
    -> (a -> ParsecT [Char] S Identity b)
    -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= TypeSpecifierNonArray -> P TypeSpecifierNonArray
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TypeSpecifierNonArray -> P TypeSpecifierNonArray)
    -> ([Char] -> TypeSpecifierNonArray)
    -> [Char]
    -> P TypeSpecifierNonArray
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> TypeSpecifierNonArray
    TypeName -- verify if it is declared
      ]

    precisionQualifier :: P PrecisionQualifier
    precisionQualifier :: P PrecisionQualifier
    precisionQualifier = [P PrecisionQualifier] -> P PrecisionQualifier
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ [Char] -> P ()
    keyword [Char]
    "highp" P () -> P PrecisionQualifier -> P PrecisionQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> PrecisionQualifier -> P PrecisionQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return PrecisionQualifier
    HighP
      , [Char] -> P ()
    keyword [Char]
    "mediump" P () -> P PrecisionQualifier -> P PrecisionQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> PrecisionQualifier -> P PrecisionQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return PrecisionQualifier
    MediumP
      , [Char] -> P ()
    keyword [Char]
    "lowp" P () -> P PrecisionQualifier -> P PrecisionQualifier
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> PrecisionQualifier -> P PrecisionQualifier
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return PrecisionQualifier
    LowP
      ]

    structSpecifier :: P TypeSpecifierNonArray
    structSpecifier :: P TypeSpecifierNonArray
    structSpecifier = do
      [Char] -> P ()
    keyword [Char]
    "struct"
      i <- ParsecT [Char] S Identity [Char]
    -> ParsecT [Char] S Identity (Maybe [Char])
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    ParsecT s u m a -> ParsecT s u m (Maybe a)
    optionMaybe ParsecT [Char] S Identity [Char]
    identifier
      lbrace
      d <- structDeclarationList
      rbrace
      return $ StructSpecifier i d

    structDeclarationList :: P [Field]
    structDeclarationList :: P [Field]
    structDeclarationList = ParsecT [Char] S Identity Field -> P [Field]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many1 ParsecT [Char] S Identity Field
    structDeclaration

    structDeclaration :: P Field
    structDeclaration :: ParsecT [Char] S Identity Field
    structDeclaration = do
      q <- P TypeQualifier -> ParsecT [Char] S Identity (Maybe TypeQualifier)
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    ParsecT s u m a -> ParsecT s u m (Maybe a)
    optionMaybe P TypeQualifier
    typeQualifier
      s <- typeSpecifier
      l <- structDeclaratorList
      semicolon
      return $ Field q s l

    structDeclaratorList :: P [StructDeclarator]
    structDeclaratorList :: P [StructDeclarator]
    structDeclaratorList = P StructDeclarator
    structDeclarator P StructDeclarator -> P () -> P [StructDeclarator]
    forall s (m :: * -> *) t u a end.
    Stream s m t =>
    ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
    `sepBy` P ()
    comma

    structDeclarator :: P StructDeclarator
    structDeclarator :: P StructDeclarator
    structDeclarator = do
      i <- ParsecT [Char] S Identity [Char]
    identifier
      choice
        [ do lbracket
             e <- optionMaybe constantExpression
             rbracket
             return $ StructDeclarator i (Just e)
        , return $ StructDeclarator i Nothing
        ]

    initializer :: P Expr
    initializer :: P Expr
    initializer = P Expr
    assignmentExpression

    declarationStatement :: P Declaration
    declarationStatement :: P Declaration
    declarationStatement = P Declaration
    declaration

    statement :: P Statement
    statement :: P Statement
    statement = Compound -> Statement
    CompoundStatement (Compound -> Statement)
    -> ParsecT [Char] S Identity Compound -> P Statement
    forall a b.
    (a -> b)
    -> ParsecT [Char] S Identity a -> ParsecT [Char] S Identity b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` ParsecT [Char] S Identity Compound
    compoundStatement
      P Statement -> P Statement -> P Statement
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> P Statement
    simpleStatement

    simpleStatement :: P Statement
    simpleStatement :: P Statement
    simpleStatement = [P Statement] -> P Statement
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ P Declaration
    declarationStatement P Declaration -> (Declaration -> P Statement) -> P Statement
    forall a b.
    ParsecT [Char] S Identity a
    -> (a -> ParsecT [Char] S Identity b)
    -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Statement -> P Statement
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Statement -> P Statement)
    -> (Declaration -> Statement) -> Declaration -> P Statement
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Declaration -> Statement
    DeclarationStatement
      , ParsecT [Char] S Identity (Maybe Expr)
    expressionStatement ParsecT [Char] S Identity (Maybe Expr)
    -> (Maybe Expr -> P Statement) -> P Statement
    forall a b.
    ParsecT [Char] S Identity a
    -> (a -> ParsecT [Char] S Identity b)
    -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Statement -> P Statement
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Statement -> P Statement)
    -> (Maybe Expr -> Statement) -> Maybe Expr -> P Statement
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Maybe Expr -> Statement
    ExpressionStatement
      , P Statement
    selectionStatement
      , P Statement
    switchStatement
      , P CaseLabel
    caseLabel P CaseLabel -> (CaseLabel -> P Statement) -> P Statement
    forall a b.
    ParsecT [Char] S Identity a
    -> (a -> ParsecT [Char] S Identity b)
    -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Statement -> P Statement
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Statement -> P Statement)
    -> (CaseLabel -> Statement) -> CaseLabel -> P Statement
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CaseLabel -> Statement
    CaseLabel
      , P Statement
    iterationStatement
      , P Statement
    jumpStatement
      ]

    compoundStatement :: P Compound
    compoundStatement :: ParsecT [Char] S Identity Compound
    compoundStatement = [ParsecT [Char] S Identity Compound]
    -> ParsecT [Char] S Identity Compound
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ P () -> P ()
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (P ()
    lbrace P () -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> P ()
    rbrace) P ()
    -> ParsecT [Char] S Identity Compound
    -> ParsecT [Char] S Identity Compound
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Compound -> ParsecT [Char] S Identity Compound
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([Statement] -> Compound
    Compound [])
      , P ()
    -> P ()
    -> ParsecT [Char] S Identity [Statement]
    -> ParsecT [Char] S Identity [Statement]
    forall s (m :: * -> *) t u open close a.
    Stream s m t =>
    ParsecT s u m open
    -> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
    between P ()
    lbrace P ()
    rbrace ParsecT [Char] S Identity [Statement]
    statementList ParsecT [Char] S Identity [Statement]
    -> ([Statement] -> ParsecT [Char] S Identity Compound)
    -> ParsecT [Char] S Identity Compound
    forall a b.
    ParsecT [Char] S Identity a
    -> (a -> ParsecT [Char] S Identity b)
    -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Compound -> ParsecT [Char] S Identity Compound
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Compound -> ParsecT [Char] S Identity Compound)
    -> ([Statement] -> Compound)
    -> [Statement]
    -> ParsecT [Char] S Identity Compound
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Statement] -> Compound
    Compound
      ]

    statementNoNewScope :: P Statement
    statementNoNewScope :: P Statement
    statementNoNewScope = Compound -> Statement
    CompoundStatement (Compound -> Statement)
    -> ParsecT [Char] S Identity Compound -> P Statement
    forall a b.
    (a -> b)
    -> ParsecT [Char] S Identity a -> ParsecT [Char] S Identity b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` ParsecT [Char] S Identity Compound
    compoundStatementNoNewScope
      P Statement -> P Statement -> P Statement
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> P Statement
    simpleStatement

    compoundStatementNoNewScope :: P Compound
    compoundStatementNoNewScope :: ParsecT [Char] S Identity Compound
    compoundStatementNoNewScope = ParsecT [Char] S Identity Compound
    compoundStatement

    statementList :: P [Statement]
    statementList :: ParsecT [Char] S Identity [Statement]
    statementList = P Statement -> ParsecT [Char] S Identity [Statement]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many1 P Statement
    statement

    expressionStatement :: P (Maybe Expr)
    expressionStatement :: ParsecT [Char] S Identity (Maybe Expr)
    expressionStatement = [ParsecT [Char] S Identity (Maybe Expr)]
    -> ParsecT [Char] S Identity (Maybe Expr)
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ P ()
    semicolon P ()
    -> ParsecT [Char] S Identity (Maybe Expr)
    -> ParsecT [Char] S Identity (Maybe Expr)
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Maybe Expr -> ParsecT [Char] S Identity (Maybe Expr)
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe Expr
    forall a. Maybe a
    Nothing
      , P Expr
    expression P Expr
    -> (Expr -> ParsecT [Char] S Identity (Maybe Expr))
    -> ParsecT [Char] S Identity (Maybe Expr)
    forall a b.
    ParsecT [Char] S Identity a
    -> (a -> ParsecT [Char] S Identity b)
    -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \Expr
    e -> P ()
    semicolon P ()
    -> ParsecT [Char] S Identity (Maybe Expr)
    -> ParsecT [Char] S Identity (Maybe Expr)
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Maybe Expr -> ParsecT [Char] S Identity (Maybe Expr)
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Expr -> Maybe Expr
    forall a. a -> Maybe a
    Just Expr
    e)
      ]

    selectionStatement :: P Statement
    selectionStatement :: P Statement
    selectionStatement = do
      [Char] -> P ()
    keyword [Char]
    "if"
      P ()
    lparen
      c <- P Expr
    expression
      rparen
      t <- statement
      f <- optionMaybe (keyword "else" >> statement)
      return $ SelectionStatement c t f

    -- inside selectionStatement
    -- selectionRestStatement = undefined

    condition :: P Condition
    condition :: P Condition
    condition = [P Condition] -> P Condition
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ P Expr
    expression P Expr -> (Expr -> P Condition) -> P Condition
    forall a b.
    ParsecT [Char] S Identity a
    -> (a -> ParsecT [Char] S Identity b)
    -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Condition -> P Condition
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Condition -> P Condition)
    -> (Expr -> Condition) -> Expr -> P Condition
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Expr -> Condition
    Condition
      , do t <- P FullType
    fullySpecifiedType
           i <- identifier
           _ <- lexeme (string "=")
           j <- initializer
           return $ InitializedCondition t i j
      ]

    switchStatement :: P Statement
    switchStatement :: P Statement
    switchStatement = do
      [Char] -> P ()
    keyword [Char]
    "switch"
      P ()
    lparen
      e <- P Expr
    expression
      rparen
      lbrace
      l <- switchStatementList
      rbrace
      return $ SwitchStatement e l

    switchStatementList :: P [Statement]
    switchStatementList :: ParsecT [Char] S Identity [Statement]
    switchStatementList = P Statement -> ParsecT [Char] S Identity [Statement]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many P Statement
    statement

    caseLabel :: P CaseLabel
    caseLabel :: P CaseLabel
    caseLabel = [P CaseLabel] -> P CaseLabel
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ [Char] -> P ()
    keyword [Char]
    "case" P () -> P Expr -> P Expr
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> P Expr
    expression P Expr -> (Expr -> P CaseLabel) -> P CaseLabel
    forall a b.
    ParsecT [Char] S Identity a
    -> (a -> ParsecT [Char] S Identity b)
    -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \Expr
    e -> P ()
    colon P () -> P CaseLabel -> P CaseLabel
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> CaseLabel -> P CaseLabel
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Expr -> CaseLabel
    Case Expr
    e)
      , [Char] -> P ()
    keyword [Char]
    "default" P () -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> P ()
    colon P () -> P CaseLabel -> P CaseLabel
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> CaseLabel -> P CaseLabel
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return CaseLabel
    Default
      ]

    iterationStatement :: P Statement
    iterationStatement :: P Statement
    iterationStatement = [P Statement] -> P Statement
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ do [Char] -> P ()
    keyword [Char]
    "while"
           P ()
    lparen
           c <- P Condition
    condition
           rparen
           s <- statementNoNewScope
           return $ While c s
      , do [Char] -> P ()
    keyword [Char]
    "do"
           s <- P Statement
    statement
           keyword "while"
           lparen
           e <- expression
           rparen
           semicolon
           return $ DoWhile s e
      , do [Char] -> P ()
    keyword [Char]
    "for"
           P ()
    lparen
           i <- P (Either (Maybe Expr) Declaration)
    forInitStatement
           c <- optionMaybe condition
           semicolon
           e <- optionMaybe expression
           rparen
           s <- statementNoNewScope
           return $ For i c e s
      ]

    forInitStatement :: P (Either (Maybe Expr) Declaration)
    forInitStatement :: P (Either (Maybe Expr) Declaration)
    forInitStatement = (ParsecT [Char] S Identity (Maybe Expr)
    expressionStatement ParsecT [Char] S Identity (Maybe Expr)
    -> (Maybe Expr -> P (Either (Maybe Expr) Declaration))
    -> P (Either (Maybe Expr) Declaration)
    forall a b.
    ParsecT [Char] S Identity a
    -> (a -> ParsecT [Char] S Identity b)
    -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Either (Maybe Expr) Declaration
    -> P (Either (Maybe Expr) Declaration)
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either (Maybe Expr) Declaration
     -> P (Either (Maybe Expr) Declaration))
    -> (Maybe Expr -> Either (Maybe Expr) Declaration)
    -> Maybe Expr
    -> P (Either (Maybe Expr) Declaration)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Maybe Expr -> Either (Maybe Expr) Declaration
    forall a b. a -> Either a b
    Left)
      P (Either (Maybe Expr) Declaration)
    -> P (Either (Maybe Expr) Declaration)
    -> P (Either (Maybe Expr) Declaration)
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> (P Declaration
    declarationStatement P Declaration
    -> (Declaration -> P (Either (Maybe Expr) Declaration))
    -> P (Either (Maybe Expr) Declaration)
    forall a b.
    ParsecT [Char] S Identity a
    -> (a -> ParsecT [Char] S Identity b)
    -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Either (Maybe Expr) Declaration
    -> P (Either (Maybe Expr) Declaration)
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either (Maybe Expr) Declaration
     -> P (Either (Maybe Expr) Declaration))
    -> (Declaration -> Either (Maybe Expr) Declaration)
    -> Declaration
    -> P (Either (Maybe Expr) Declaration)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Declaration -> Either (Maybe Expr) Declaration
    forall a b. b -> Either a b
    Right)

    -- inside iterationStatement
    -- conditionOp = undefined

    -- inside iterationStatement
    -- forRestStatement = undefined

    jumpStatement :: P Statement
    jumpStatement :: P Statement
    jumpStatement = [P Statement] -> P Statement
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ [Char] -> P ()
    keyword [Char]
    "continue" P () -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> P ()
    semicolon P () -> P Statement -> P Statement
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Statement -> P Statement
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Statement
    Continue
      , [Char] -> P ()
    keyword [Char]
    "break" P () -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> P ()
    semicolon P () -> P Statement -> P Statement
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Statement -> P Statement
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Statement
    Break
      , P () -> P ()
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try ([Char] -> P ()
    keyword [Char]
    "return" P () -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> P ()
    semicolon) P () -> P Statement -> P Statement
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Statement -> P Statement
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe Expr -> Statement
    Return Maybe Expr
    forall a. Maybe a
    Nothing)
      , [Char] -> P ()
    keyword [Char]
    "return" P () -> P Expr -> P Expr
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> P Expr
    expression P Expr -> (Expr -> P Statement) -> P Statement
    forall a b.
    ParsecT [Char] S Identity a
    -> (a -> ParsecT [Char] S Identity b)
    -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \Expr
    e -> P ()
    semicolon P () -> P Statement -> P Statement
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Statement -> P Statement
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe Expr -> Statement
    Return (Maybe Expr -> Statement) -> Maybe Expr -> Statement
    forall a b. (a -> b) -> a -> b
    $ Expr -> Maybe Expr
    forall a. a -> Maybe a
    Just Expr
    e)
      , [Char] -> P ()
    keyword [Char]
    "discard" P () -> P () -> P ()
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> P ()
    semicolon P () -> P Statement -> P Statement
    forall a b.
    ParsecT [Char] S Identity a
    -> ParsecT [Char] S Identity b -> ParsecT [Char] S Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Statement -> P Statement
    forall a. a -> ParsecT [Char] S Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Statement
    Discard
      ]

    translationUnit :: P TranslationUnit
    translationUnit :: GenParser Char S TranslationUnit
    translationUnit = [ExternalDeclaration] -> TranslationUnit
    TranslationUnit ([ExternalDeclaration] -> TranslationUnit)
    -> ParsecT [Char] S Identity [ExternalDeclaration]
    -> GenParser Char S TranslationUnit
    forall a b.
    (a -> b)
    -> ParsecT [Char] S Identity a -> ParsecT [Char] S Identity b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` ParsecT [Char] S Identity ExternalDeclaration
    -> ParsecT [Char] S Identity [ExternalDeclaration]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many1 ParsecT [Char] S Identity ExternalDeclaration
    externalDeclaration

    externalDeclaration :: P ExternalDeclaration
    externalDeclaration :: ParsecT [Char] S Identity ExternalDeclaration
    externalDeclaration = [ParsecT [Char] S Identity ExternalDeclaration]
    -> ParsecT [Char] S Identity ExternalDeclaration
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ do p <- P FunctionPrototype -> P FunctionPrototype
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try P FunctionPrototype
    functionPrototype
           choice
             [ semicolon >> return (FunctionDeclaration p)
             , compoundStatementNoNewScope >>= return . FunctionDefinition p
             ]
      , Declaration -> ExternalDeclaration
    Declaration (Declaration -> ExternalDeclaration)
    -> P Declaration -> ParsecT [Char] S Identity ExternalDeclaration
    forall a b.
    (a -> b)
    -> ParsecT [Char] S Identity a -> ParsecT [Char] S Identity b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` P Declaration
    declaration
      ]

    -- inside externalDeclaration, used only in tests
    functionDefinition :: P ExternalDeclaration
    functionDefinition :: ParsecT [Char] S Identity ExternalDeclaration
    functionDefinition = do
      fp <- P FunctionPrototype
    functionPrototype
      cs <- compoundStatementNoNewScope
      return $ FunctionDefinition fp cs