module Language.Go.Token where

import Language.Go.SrcLocation

data Token
  = IdentifierToken { tokenLiteral :: !String, tokenSpan :: !SrcSpan }

  -- Literals
  | IntToken { tokenLiteral :: !String, tokenSpan :: !SrcSpan }
  | FloatToken { tokenLiteral :: !String, tokenSpan :: !SrcSpan }
  | ImaginaryToken { tokenLiteral :: !String, tokenSpan :: !SrcSpan }
  | RuneToken { tokenLiteral :: !String, tokenSpan :: !SrcSpan }
  | StringToken { tokenLiteral :: !String, tokenSpan :: !SrcSpan }

  -- Keywords
  | BreakToken { tokenSpan :: !SrcSpan }
  | CaseToken { tokenSpan :: !SrcSpan }
  | ChanToken { tokenSpan :: !SrcSpan }
  | ConstToken { tokenSpan :: !SrcSpan }
  | ContinueToken { tokenSpan :: !SrcSpan }
  | DefaultToken { tokenSpan :: !SrcSpan }
  | DeferToken { tokenSpan :: !SrcSpan }
  | ElseToken { tokenSpan :: !SrcSpan }
  | FallthroughToken { tokenSpan :: !SrcSpan }
  | ForToken { tokenSpan :: !SrcSpan }
  | FuncToken { tokenSpan :: !SrcSpan }
  | GoToken { tokenSpan :: !SrcSpan }
  | GotoToken { tokenSpan :: !SrcSpan }
  | IfToken { tokenSpan :: !SrcSpan }
  | ImportToken { tokenSpan :: !SrcSpan }
  | InterfaceToken { tokenSpan :: !SrcSpan }
  | MapToken { tokenSpan :: !SrcSpan }
  | PackageToken { tokenSpan :: !SrcSpan }
  | RangeToken { tokenSpan :: !SrcSpan }
  | ReturnToken { tokenSpan :: !SrcSpan }
  | SelectToken { tokenSpan :: !SrcSpan }
  | StructToken { tokenSpan :: !SrcSpan }
  | SwitchToken { tokenSpan :: !SrcSpan }
  | TypeToken { tokenSpan :: !SrcSpan }
  | VarToken { tokenSpan :: !SrcSpan }

  -- Operators and delimiters
  | PlusToken { tokenSpan :: !SrcSpan }  -- '+'
  | MinusToken { tokenSpan :: !SrcSpan }  -- '-'
  | MultToken { tokenSpan :: !SrcSpan }  -- '*'
  | DivToken { tokenSpan :: !SrcSpan }  -- '/'
  | ModuloToken { tokenSpan :: !SrcSpan }  -- '%'
  | BinaryAndToken { tokenSpan :: !SrcSpan }  -- '&'
  | BinaryOrToken { tokenSpan :: !SrcSpan }  -- '|'
  | BinaryXorToken { tokenSpan :: !SrcSpan }  -- '^'
  | BinaryShiftLeftToken { tokenSpan :: !SrcSpan }  -- '<<'
  | BinaryShiftRightToken { tokenSpan :: !SrcSpan }  -- '>>'
  | BinaryAndNotToken { tokenSpan :: !SrcSpan }  -- '&^'
  | AndToken { tokenSpan :: !SrcSpan }  -- '&&'
  | OrToken { tokenSpan :: !SrcSpan }  -- '||'
  | ArrowToken { tokenSpan :: !SrcSpan }  -- '<-'
  | IncToken { tokenSpan :: !SrcSpan }  -- '++'
  | DecToken { tokenSpan :: !SrcSpan }  -- '--'
  | EqualityToken { tokenSpan :: !SrcSpan }  -- '=='
  | LessThanToken { tokenSpan :: !SrcSpan }  -- '<'
  | GreaterThanToken { tokenSpan :: !SrcSpan }  -- '>'
  | AssignToken { tokenSpan :: !SrcSpan }  -- '='
  | NotToken { tokenSpan :: !SrcSpan }  -- '!'
  | NotEqualsToken { tokenSpan :: !SrcSpan }  -- '!='
  | LessThanEqualsToken { tokenSpan :: !SrcSpan }  -- '<='
  | GreaterThanEqualsToken { tokenSpan :: !SrcSpan }  -- '>='
  | DefineToken { tokenSpan :: !SrcSpan }  -- ':='
  | EllipsisToken { tokenSpan :: !SrcSpan }  -- '...'
  | LeftRoundBracketToken { tokenSpan :: !SrcSpan }  -- '('
  | RightRoundBracketToken { tokenSpan :: !SrcSpan }  -- ')'
  | LeftSquareBracketToken { tokenSpan :: !SrcSpan }  -- '['
  | RightSquareBracketToken { tokenSpan :: !SrcSpan }  -- ']'
  | LeftCurlyBracketToken { tokenSpan :: !SrcSpan }  -- '{'
  | RightCurlyBracketToken { tokenSpan :: !SrcSpan }  -- '}'
  | CommaToken { tokenSpan :: !SrcSpan }  -- ','
  | DotToken { tokenSpan :: !SrcSpan }  -- '.'
  | SemicolonToken { tokenSpan :: !SrcSpan }  -- ';'
  | ColonToken { tokenSpan :: !SrcSpan }  -- ':'
  | PlusAssignToken { tokenSpan :: !SrcSpan }  -- '+='
  | MinusAssignToken { tokenSpan :: !SrcSpan }  -- '-='
  | MultAssignToken { tokenSpan :: !SrcSpan }  -- '*='
  | DivAssignToken { tokenSpan :: !SrcSpan }  -- '/='
  | ModuloAssignToken { tokenSpan :: !SrcSpan }  -- '%='
  | BinaryAndAssignToken { tokenSpan :: !SrcSpan }  -- '&='
  | BinaryOrAssignToken { tokenSpan :: !SrcSpan }  -- '|='
  | BinaryXorAssignToken { tokenSpan :: !SrcSpan }  -- '^='
  | BinaryShiftLeftAssignToken { tokenSpan :: !SrcSpan }  -- '<<='
  | BinaryShiftRightAssignToken { tokenSpan :: !SrcSpan }  -- '>>='
  | BinaryAndNotAssignToken { tokenSpan :: !SrcSpan }  -- '&^='

  deriving (Eq, Ord, Show)
