    --  C -> Haskell Compiler: Lexer for C Header Files
    --
    --  Author : Manuel M T Chakravarty, Duncan Coutts
    --  Created: 24 May 2005
    --
    --  Version $Revision: 1.1.2.1 $ from $Date: 2005/06/14 00:16:14 $
    --
    --  Copyright (c) [1999..2004] Manuel M T Chakravarty
    --  Copyright (c) 2005 Duncan Coutts
    --
    --  This file is free software; you can redistribute it and/or modify
    --  it under the terms of the GNU General Public License as published by
    --  the Free Software Foundation; either version 2 of the License, or
    --  (at your option) any later version.
    --
    --  This file is distributed in the hope that it will be useful,
    --  but WITHOUT ANY WARRANTY; without even the implied warranty of
    --  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    --  GNU General Public License for more details.
    --
    --- DESCRIPTION ---------------------------------------------------------------
    --
    --  C Tokens for the C lexer.
    --

    module CTokens (CToken(..), GnuCTok(..)) where

    import Position  (Position(..), Pos(posOf))
    import Idents    (Ident, identToLexeme)

    -- token definition
    -- ----------------

    -- possible tokens (EXPORTED)
    --
    data CToken = CTokLParen   !Position            -- `('
                | CTokRParen   !Position            -- `)'
                | CTokLBracket !Position            -- `['
                | CTokRBracket !Position            -- `]'
                | CTokArrow    !Position            -- `->'
                | CTokDot      !Position            -- `.'
                | CTokExclam   !Position            -- `!'
                | CTokTilde    !Position            -- `~'
                | CTokInc      !Position            -- `++'
                | CTokDec      !Position            -- `--'
                | CTokPlus     !Position            -- `+'
                | CTokMinus    !Position            -- `-'
                | CTokStar     !Position            -- `*'
                | CTokSlash    !Position            -- `/'
                | CTokPercent  !Position            -- `%'
                | CTokAmper    !Position            -- `&'
                | CTokShiftL   !Position            -- `<<'
                | CTokShiftR   !Position            -- `>>'
                | CTokLess     !Position            -- `<'
                | CTokLessEq   !Position            -- `<='
                | CTokHigh     !Position            -- `>'
                | CTokHighEq   !Position            -- `>='
                | CTokEqual    !Position            -- `=='
                | CTokUnequal  !Position            -- `!='
                | CTokHat      !Position            -- `^'
                | CTokBar      !Position            -- `|'
                | CTokAnd      !Position            -- `&&'
                | CTokOr       !Position            -- `||'
                | CTokQuest    !Position            -- `?'
                | CTokColon    !Position            -- `:'
                | CTokAssign   !Position            -- `='
                | CTokPlusAss  !Position            -- `+='
                | CTokMinusAss !Position            -- `-='
                | CTokStarAss  !Position            -- `*='
                | CTokSlashAss !Position            -- `/='
                | CTokPercAss  !Position            -- `%='
                | CTokAmpAss   !Position            -- `&='
                | CTokHatAss   !Position            -- `^='
                | CTokBarAss   !Position            -- `|='
                | CTokSLAss    !Position            -- `<<='
                | CTokSRAss    !Position            -- `>>='
                | CTokComma    !Position            -- `,'
                | CTokSemic    !Position            -- `;'
                | CTokLBrace   !Position            -- `{'
                | CTokRBrace   !Position            --
                | CTokEllipsis !Position            -- `...'
                | CTokAlignof  !Position            -- `alignof'
                                                    -- (or `__alignof',
                                                    -- `__alignof__')
                | CTokAsm      !Position            -- `asm'
                                                    -- (or `__asm',
                                                    -- `__asm__')
                | CTokAuto     !Position            -- `auto'
                | CTokBreak    !Position            -- `break'
                | CTokBool     !Position            -- `_Bool'
                | CTokCase     !Position            -- `case'
                | CTokChar     !Position            -- `char'
                | CTokConst    !Position            -- `const'
                                                    -- (or `__const', `__const__')
                | CTokContinue !Position            -- `continue'
                | CTokComplex  !Position            -- `_Complex'
                | CTokDefault  !Position            -- `default'
                | CTokDo       !Position            -- `do'
                | CTokDouble   !Position            -- `double'
                | CTokElse     !Position            -- `else'
                | CTokEnum     !Position            -- `enum'
                | CTokExtern   !Position            -- `extern'
                | CTokFloat    !Position            -- `float'
                | CTokFloat128 !Position            -- `__float128'
                | CTokFor      !Position            -- `for'
                | CTokGoto     !Position            -- `goto'
                | CTokIf       !Position            -- `if'
                | CTokInline   !Position            -- `inline'
                                                    -- (or `__inline',
                                                    -- `__inline__')
                | CTokInt      !Position            -- `int'
                | CTokLong     !Position            -- `long'
                | CTokLabel    !Position            -- `__label__'
                | CTokRegister !Position            -- `register'
                | CTokRestrict !Position            -- `restrict'
                                                    -- (or `__restrict',
                                                    -- `__restrict__')
                | CTokReturn   !Position            -- `return'
                | CTokShort    !Position            -- `short'
                | CTokSigned   !Position            -- `signed'
                                                    -- (or `__signed',
                                                    -- `__signed__')
                | CTokSizeof   !Position            -- `sizeof'
                | CTokStatic   !Position            -- `static'
                | CTokStruct   !Position            -- `struct'
                | CTokSwitch   !Position            -- `switch'
                | CTokTypedef  !Position            -- `typedef'
                | CTokTypeof   !Position            -- `typeof'
                | CTokThread   !Position            -- `__thread'
                | CTokUnion    !Position            -- `union'
                | CTokUnsigned !Position            -- `unsigned'
                | CTokVoid     !Position            -- `void'
                | CTokVolatile !Position            -- `volatile'
                                                    -- (or `__volatile',
                                                    -- `__volatile__')
                | CTokWhile    !Position            -- `while'
                | CTokCLit     !Position !Char      -- character constant
                | CTokILit     !Position !Integer   -- integer constant
                | CTokFLit     !Position String     -- float constant
                | CTokSLit     !Position String     -- string constant (no escapes)
                | CTokIdent    !Position !Ident     -- identifier

                  -- not generated here, but in `CParser.parseCHeader'
                | CTokTyIdent  !Position !Ident     -- `typedef-name' identifier
                | CTokGnuC !GnuCTok !Position       -- special GNU C tokens
                | CTokEof                           -- end of file

    -- special tokens used in GNU C extensions to ANSI C
    --
    data GnuCTok = GnuCAttrTok              -- `__attribute__'
                 | GnuCExtTok               -- `__extension__'
                 | GnuCVaArg                -- `__builtin_va_arg'
                 | GnuCOffsetof             -- `__builtin_offsetof'
                 | GnuCTyCompat             -- `__builtin_types_compatible_p'

    instance Pos CToken where
      posOf (CTokLParen   pos  ) = pos
      posOf (CTokRParen   pos  ) = pos
      posOf (CTokLBracket pos  ) = pos
      posOf (CTokRBracket pos  ) = pos
      posOf (CTokArrow    pos  ) = pos
      posOf (CTokDot      pos  ) = pos
      posOf (CTokExclam   pos  ) = pos
      posOf (CTokTilde    pos  ) = pos
      posOf (CTokInc      pos  ) = pos
      posOf (CTokDec      pos  ) = pos
      posOf (CTokPlus     pos  ) = pos
      posOf (CTokMinus    pos  ) = pos
      posOf (CTokStar     pos  ) = pos
      posOf (CTokSlash    pos  ) = pos
      posOf (CTokPercent  pos  ) = pos
      posOf (CTokAmper    pos  ) = pos
      posOf (CTokShiftL   pos  ) = pos
      posOf (CTokShiftR   pos  ) = pos
      posOf (CTokLess     pos  ) = pos
      posOf (CTokLessEq   pos  ) = pos
      posOf (CTokHigh     pos  ) = pos
      posOf (CTokHighEq   pos  ) = pos
      posOf (CTokEqual    pos  ) = pos
      posOf (CTokUnequal  pos  ) = pos
      posOf (CTokHat      pos  ) = pos
      posOf (CTokBar      pos  ) = pos
      posOf (CTokAnd      pos  ) = pos
      posOf (CTokOr       pos  ) = pos
      posOf (CTokQuest    pos  ) = pos
      posOf (CTokColon    pos  ) = pos
      posOf (CTokAssign   pos  ) = pos
      posOf (CTokPlusAss  pos  ) = pos
      posOf (CTokMinusAss pos  ) = pos
      posOf (CTokStarAss  pos  ) = pos
      posOf (CTokSlashAss pos  ) = pos
      posOf (CTokPercAss  pos  ) = pos
      posOf (CTokAmpAss   pos  ) = pos
      posOf (CTokHatAss   pos  ) = pos
      posOf (CTokBarAss   pos  ) = pos
      posOf (CTokSLAss    pos  ) = pos
      posOf (CTokSRAss    pos  ) = pos
      posOf (CTokComma    pos  ) = pos
      posOf (CTokSemic    pos  ) = pos
      posOf (CTokLBrace   pos  ) = pos
      posOf (CTokRBrace   pos  ) = pos
      posOf (CTokEllipsis pos  ) = pos
      posOf (CTokAlignof  pos  ) = pos
      posOf (CTokAsm      pos  ) = pos
      posOf (CTokAuto     pos  ) = pos
      posOf (CTokBreak    pos  ) = pos
      posOf (CTokBool     pos  ) = pos
      posOf (CTokCase     pos  ) = pos
      posOf (CTokChar     pos  ) = pos
      posOf (CTokConst    pos  ) = pos
      posOf (CTokContinue pos  ) = pos
      posOf (CTokComplex  pos  ) = pos
      posOf (CTokDefault  pos  ) = pos
      posOf (CTokDo       pos  ) = pos
      posOf (CTokDouble   pos  ) = pos
      posOf (CTokElse     pos  ) = pos
      posOf (CTokEnum     pos  ) = pos
      posOf (CTokExtern   pos  ) = pos
      posOf (CTokFloat    pos  ) = pos
      posOf (CTokFloat128 pos  ) = pos
      posOf (CTokFor      pos  ) = pos
      posOf (CTokGoto     pos  ) = pos
      posOf (CTokInt      pos  ) = pos
      posOf (CTokInline   pos  ) = pos
      posOf (CTokIf       pos  ) = pos
      posOf (CTokLong     pos  ) = pos
      posOf (CTokLabel    pos  ) = pos
      posOf (CTokRegister pos  ) = pos
      posOf (CTokRestrict pos  ) = pos
      posOf (CTokReturn   pos  ) = pos
      posOf (CTokShort    pos  ) = pos
      posOf (CTokSigned   pos  ) = pos
      posOf (CTokSizeof   pos  ) = pos
      posOf (CTokStatic   pos  ) = pos
      posOf (CTokStruct   pos  ) = pos
      posOf (CTokSwitch   pos  ) = pos
      posOf (CTokTypedef  pos  ) = pos
      posOf (CTokTypeof   pos  ) = pos
      posOf (CTokThread   pos  ) = pos
      posOf (CTokUnion    pos  ) = pos
      posOf (CTokUnsigned pos  ) = pos
      posOf (CTokVoid     pos  ) = pos
      posOf (CTokVolatile pos  ) = pos
      posOf (CTokWhile    pos  ) = pos
      posOf (CTokCLit     pos _) = pos
      posOf (CTokILit     pos _) = pos
      posOf (CTokFLit     pos _) = pos
      posOf (CTokSLit     pos _) = pos
      posOf (CTokIdent    pos _) = pos
      posOf (CTokTyIdent  pos _) = pos
      posOf (CTokGnuC   _ pos  ) = pos

    instance Show CToken where
      showsPrec _ (CTokLParen   _  ) = showString "("
      showsPrec _ (CTokRParen   _  ) = showString ")"
      showsPrec _ (CTokLBracket _  ) = showString "["
      showsPrec _ (CTokRBracket _  ) = showString "]"
      showsPrec _ (CTokArrow    _  ) = showString "->"
      showsPrec _ (CTokDot      _  ) = showString "."
      showsPrec _ (CTokExclam   _  ) = showString "!"
      showsPrec _ (CTokTilde    _  ) = showString "~"
      showsPrec _ (CTokInc      _  ) = showString "++"
      showsPrec _ (CTokDec      _  ) = showString "--"
      showsPrec _ (CTokPlus     _  ) = showString "+"
      showsPrec _ (CTokMinus    _  ) = showString "-"
      showsPrec _ (CTokStar     _  ) = showString "*"
      showsPrec _ (CTokSlash    _  ) = showString "/"
      showsPrec _ (CTokPercent  _  ) = showString "%"
      showsPrec _ (CTokAmper    _  ) = showString "&"
      showsPrec _ (CTokShiftL   _  ) = showString "<<"
      showsPrec _ (CTokShiftR   _  ) = showString ">>"
      showsPrec _ (CTokLess     _  ) = showString "<"
      showsPrec _ (CTokLessEq   _  ) = showString "<="
      showsPrec _ (CTokHigh     _  ) = showString ">"
      showsPrec _ (CTokHighEq   _  ) = showString ">="
      showsPrec _ (CTokEqual    _  ) = showString "=="
      showsPrec _ (CTokUnequal  _  ) = showString "!="
      showsPrec _ (CTokHat      _  ) = showString "^"
      showsPrec _ (CTokBar      _  ) = showString "|"
      showsPrec _ (CTokAnd      _  ) = showString "&&"
      showsPrec _ (CTokOr       _  ) = showString "||"
      showsPrec _ (CTokQuest    _  ) = showString "?"
      showsPrec _ (CTokColon    _  ) = showString ":"
      showsPrec _ (CTokAssign   _  ) = showString "="
      showsPrec _ (CTokPlusAss  _  ) = showString "+="
      showsPrec _ (CTokMinusAss _  ) = showString "-="
      showsPrec _ (CTokStarAss  _  ) = showString "*="
      showsPrec _ (CTokSlashAss _  ) = showString "/="
      showsPrec _ (CTokPercAss  _  ) = showString "%="
      showsPrec _ (CTokAmpAss   _  ) = showString "&="
      showsPrec _ (CTokHatAss   _  ) = showString "^="
      showsPrec _ (CTokBarAss   _  ) = showString "|="
      showsPrec _ (CTokSLAss    _  ) = showString "<<="
      showsPrec _ (CTokSRAss    _  ) = showString ">>="
      showsPrec _ (CTokComma    _  ) = showString ","
      showsPrec _ (CTokSemic    _  ) = showString ";"
      showsPrec _ (CTokLBrace   _  ) = showString "{"
      showsPrec _ (CTokRBrace   _  ) = showString "}"
      showsPrec _ (CTokEllipsis _  ) = showString "..."
      showsPrec _ (CTokAlignof  _  ) = showString "alignof"
      showsPrec _ (CTokAsm      _  ) = showString "asm"
      showsPrec _ (CTokAuto     _  ) = showString "auto"
      showsPrec _ (CTokBreak    _  ) = showString "break"
      showsPrec _ (CTokCase     _  ) = showString "case"
      showsPrec _ (CTokChar     _  ) = showString "char"
      showsPrec _ (CTokConst    _  ) = showString "const"
      showsPrec _ (CTokContinue _  ) = showString "continue"
      showsPrec _ (CTokDefault  _  ) = showString "default"
      showsPrec _ (CTokDouble   _  ) = showString "double"
      showsPrec _ (CTokDo       _  ) = showString "do"
      showsPrec _ (CTokElse     _  ) = showString "else"
      showsPrec _ (CTokEnum     _  ) = showString "enum"
      showsPrec _ (CTokExtern   _  ) = showString "extern"
      showsPrec _ (CTokFloat    _  ) = showString "float"
      showsPrec _ (CTokFloat128 _  ) = showString "__float128"
      showsPrec _ (CTokFor      _  ) = showString "for"
      showsPrec _ (CTokGoto     _  ) = showString "goto"
      showsPrec _ (CTokIf       _  ) = showString "if"
      showsPrec _ (CTokInline   _  ) = showString "inline"
      showsPrec _ (CTokInt      _  ) = showString "int"
      showsPrec _ (CTokLong     _  ) = showString "long"
      showsPrec _ (CTokLabel    _  ) = showString "__label__"
      showsPrec _ (CTokRegister _  ) = showString "register"
      showsPrec _ (CTokRestrict _  ) = showString "restrict"
      showsPrec _ (CTokReturn   _  ) = showString "return"
      showsPrec _ (CTokShort    _  ) = showString "short"
      showsPrec _ (CTokSigned   _  ) = showString "signed"
      showsPrec _ (CTokSizeof   _  ) = showString "sizeof"
      showsPrec _ (CTokStatic   _  ) = showString "static"
      showsPrec _ (CTokStruct   _  ) = showString "struct"
      showsPrec _ (CTokSwitch   _  ) = showString "switch"
      showsPrec _ (CTokTypedef  _  ) = showString "typedef"
      showsPrec _ (CTokTypeof   _  ) = showString "typeof"
      showsPrec _ (CTokThread   _  ) = showString "__thread"
      showsPrec _ (CTokUnion    _  ) = showString "union"
      showsPrec _ (CTokUnsigned _  ) = showString "unsigned"
      showsPrec _ (CTokVoid     _  ) = showString "void"
      showsPrec _ (CTokVolatile _  ) = showString "volatile"
      showsPrec _ (CTokWhile    _  ) = showString "while"
      showsPrec _ (CTokCLit     _ c) = showChar c
      showsPrec _ (CTokILit     _ i) = (showString . show) i
      showsPrec _ (CTokFLit     _ s) = showString s
      showsPrec _ (CTokSLit     _ s) = showString s
      showsPrec _ (CTokIdent    _ i) = (showString . identToLexeme) i
      showsPrec _ (CTokTyIdent  _ i) = (showString . identToLexeme) i
      showsPrec _ (CTokGnuC GnuCAttrTok _) = showString "__attribute__"
      showsPrec _ (CTokGnuC GnuCExtTok  _) = showString "__extension__"
      showsPrec _ (CTokGnuC GnuCVaArg    _) = showString "__builtin_va_arg"
      showsPrec _ (CTokGnuC GnuCOffsetof _) = showString "__builtin_offsetof"
      showsPrec _ (CTokGnuC GnuCTyCompat _) = showString "__builtin_types_compatible_p"