{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveAnyClass #-}
module Language.Rust.Syntax.Token (
  Token(..),
  spaceNeeded,
  Space(..),
  Delim(..),
  LitTok(..),
  AttrStyle(..),
) where
import GHC.Generics                ( Generic )
import Control.DeepSeq             ( NFData )
import Data.Data                   ( Data )
import Data.Maybe                  ( fromMaybe )
import Data.Typeable               ( Typeable )
import Language.Rust.Data.Ident    ( Ident(name), Name )
import Language.Rust.Data.Position ( Span )
import Language.Rust.Syntax.AST    ( Nonterminal, AttrStyle(..) )
data Token
  
  = Equal                 
  | Less                  
  | Greater               
  | Ampersand             
  | Pipe                  
  | Exclamation           
  | Tilde                 
  | Plus                  
  | Minus                 
  | Star                  
  | Slash                 
  | Percent               
  | Caret                 
  
  
  | GreaterEqual          
  | GreaterGreaterEqual   
  | AmpersandAmpersand    
  | PipePipe              
  | LessLess              
  | GreaterGreater        
  | EqualEqual            
  | NotEqual              
  | LessEqual             
  | LessLessEqual         
  | MinusEqual            
  | AmpersandEqual        
  | PipeEqual             
  | PlusEqual             
  | StarEqual             
  | SlashEqual            
  | CaretEqual            
  | PercentEqual          
  
  
  | At                    
  | Dot                   
  | DotDot                
  | DotDotEqual           
  | DotDotDot             
  | Comma                 
  | Semicolon             
  | Colon                 
  | ModSep                
  | RArrow                
  | LArrow                
  | FatArrow              
  | Pound                 
  | Dollar                
  | Question              
  
  
  | OpenDelim !Delim      
  | CloseDelim !Delim     
  
  
  | LiteralTok LitTok (Maybe Name) 
  
  
  | IdentTok Ident        
  | LifetimeTok Ident     
  | Space Space Name      
  | Doc String !AttrStyle !Bool
  
  | Shebang               
  | Eof                   
  
  
  | Interpolated (Nonterminal Span) 
  deriving (Eq, Ord, Data, Typeable, Generic, NFData)
data Space
  = Whitespace  
  | Comment     
  deriving (Eq, Ord, Show, Enum, Bounded, Data, Typeable, Generic, NFData)
data Delim
  = Paren   
  | Bracket 
  | Brace   
  | NoDelim 
  deriving (Eq, Ord, Enum, Bounded, Show, Data, Typeable, Generic, NFData)
data LitTok
  = ByteTok Name            
  | CharTok Name            
  | IntegerTok Name         
  | FloatTok Name           
  | StrTok Name             
  | StrRawTok Name !Int     
  | ByteStrTok Name         
  | ByteStrRawTok Name !Int 
  deriving (Eq, Ord, Show, Data, Typeable, Generic, NFData)
spaceNeeded :: Token -> Token -> Bool
spaceNeeded Greater Equal = True
spaceNeeded Greater EqualEqual = True
spaceNeeded Greater FatArrow = True
spaceNeeded Greater GreaterEqual = True
spaceNeeded GreaterGreater Equal = True
spaceNeeded GreaterGreater EqualEqual = True 
spaceNeeded GreaterGreater FatArrow = True
spaceNeeded Ampersand Ampersand = True
spaceNeeded Ampersand AmpersandAmpersand = True
spaceNeeded Ampersand AmpersandEqual = True
spaceNeeded Pipe Pipe = True
spaceNeeded Pipe PipePipe = True
spaceNeeded Pipe PipeEqual = True
spaceNeeded Less Less = True
spaceNeeded Less LessLess = True
spaceNeeded Less LessLessEqual = True
spaceNeeded Less LArrow = True
spaceNeeded Greater Greater = True
spaceNeeded Greater GreaterGreater = True
spaceNeeded Greater GreaterGreaterEqual = True
spaceNeeded Equal Equal = True
spaceNeeded Equal EqualEqual = True
spaceNeeded Equal FatArrow = True
spaceNeeded Exclamation Equal = True
spaceNeeded Exclamation EqualEqual = True
spaceNeeded Exclamation FatArrow = True
spaceNeeded Less Equal = True
spaceNeeded Less EqualEqual = True
spaceNeeded Less FatArrow = True
spaceNeeded Less LessEqual = True
spaceNeeded LessLess Equal = True
spaceNeeded LessLess EqualEqual = True
spaceNeeded LessLess FatArrow = True
spaceNeeded Minus Equal = True
spaceNeeded Minus EqualEqual = True
spaceNeeded Minus FatArrow = True
spaceNeeded Ampersand Equal = True
spaceNeeded Ampersand EqualEqual = True
spaceNeeded Ampersand FatArrow = True
spaceNeeded Pipe Equal = True
spaceNeeded Pipe EqualEqual = True
spaceNeeded Pipe FatArrow = True
spaceNeeded Plus Equal = True
spaceNeeded Plus EqualEqual = True
spaceNeeded Plus FatArrow = True
spaceNeeded Star Equal = True
spaceNeeded Star EqualEqual = True
spaceNeeded Star FatArrow = True
spaceNeeded Slash Equal = True
spaceNeeded Slash EqualEqual = True
spaceNeeded Slash FatArrow = True
spaceNeeded Caret Equal = True
spaceNeeded Caret EqualEqual = True
spaceNeeded Caret FatArrow = True
spaceNeeded Percent Equal = True
spaceNeeded Percent EqualEqual = True
spaceNeeded Percent FatArrow = True
spaceNeeded Dot Dot = True
spaceNeeded Dot DotDot = True
spaceNeeded Dot DotDotDot = True
spaceNeeded DotDot Dot = True
spaceNeeded DotDot DotDot = True
spaceNeeded DotDot DotDotDot = True
spaceNeeded DotDot Equal = True
spaceNeeded DotDot EqualEqual = True
spaceNeeded DotDot FatArrow = True
spaceNeeded Colon Colon = True
spaceNeeded Colon ModSep = True
spaceNeeded Minus Greater = True
spaceNeeded Minus GreaterGreater = True
spaceNeeded Minus GreaterEqual = True
spaceNeeded Minus GreaterGreaterEqual = True
spaceNeeded Less Minus = True
spaceNeeded Less MinusEqual = True
spaceNeeded Less RArrow = True
spaceNeeded Equal Greater = True
spaceNeeded Equal GreaterGreater = True
spaceNeeded Equal GreaterEqual = True
spaceNeeded Equal GreaterGreaterEqual = True
spaceNeeded LiteralTok{} IdentTok{} = True 
spaceNeeded IdentTok{} IdentTok{} = True
spaceNeeded Pound Exclamation = True
spaceNeeded Pound NotEqual = True
spaceNeeded _ _ = False
instance Show Token where
  
  show Equal = "="
  show Less = "<"
  show Greater = ">"
  show Ampersand = "&"
  show Pipe = "|"
  show Exclamation = "!"
  show Tilde = "~"
  show Plus = "+"
  show Minus = "-"
  show Star = "*"
  show Slash = "/"
  show Percent = "%"
  
  show GreaterEqual = ">="
  show GreaterGreaterEqual = ">>="
  show AmpersandAmpersand = "&&"
  show PipePipe = "||"
  show LessLess = "<<"
  show GreaterGreater = ">>"
  show EqualEqual = "=="
  show NotEqual = "!="
  show LessEqual = "<="
  show LessLessEqual = "<<="
  show MinusEqual = "-="
  show AmpersandEqual = "&="
  show PipeEqual = "|="
  show PlusEqual = "+="
  show StarEqual = "*="
  show SlashEqual = "/="
  show CaretEqual = "^="
  show PercentEqual = "%="
  show Caret = "^"
  
  show At = "@"
  show Dot = "."
  show DotDot = ".."
  show DotDotDot = "..."
  show DotDotEqual = "..="
  show Comma = ","
  show Semicolon = ";"
  show Colon = ":"
  show ModSep = "::"
  show RArrow = "->"
  show LArrow = "<-"
  show FatArrow = "=>"
  show Pound = "#"
  show Dollar = "$"
  show Question = "?"
  
  show (OpenDelim Paren) = "("
  show (OpenDelim Bracket) = "["
  show (OpenDelim Brace) = "{"
  show (OpenDelim NoDelim) = ""
  show (CloseDelim Paren) = ")"
  show (CloseDelim Bracket) = "]"
  show (CloseDelim Brace) = "}"
  show (CloseDelim NoDelim) = ""
  
  show (LiteralTok (ByteTok n) s) = "b'" ++ n ++ "'" ++ fromMaybe "" s
  show (LiteralTok (CharTok n) s) = "'"  ++ n ++ "'" ++ fromMaybe "" s
  show (LiteralTok (IntegerTok n) s) = n ++ fromMaybe "" s
  show (LiteralTok (FloatTok n) s) = n ++ fromMaybe "" s
  show (LiteralTok (StrTok n) s) = "\"" ++ n ++ "\"" ++ fromMaybe "" s
  show (LiteralTok (StrRawTok n i) s) = "r" ++ replicate i '#' ++ "\"" ++ n ++ "\"" ++ replicate i '#' ++ fromMaybe "" s
  show (LiteralTok (ByteStrTok n) s) = "b\"" ++ n ++ "\"" ++ fromMaybe "" s
  show (LiteralTok (ByteStrRawTok n i) s) = "br" ++ replicate i '#' ++ "\"" ++ n ++ "\"" ++ replicate i '#' ++ fromMaybe "" s
  
  show (IdentTok i) = name i
  show (LifetimeTok l) = "'" ++ show l
  show (Space Whitespace _) = "<whitespace>"
  show (Space Comment n) = "/*" ++ show n ++ " */"
  show (Doc d Inner True) = "/*!" ++ d ++ "*/"
  show (Doc d Outer True) = "/**" ++ d ++ "*/"
  show (Doc d Inner False) = "//!" ++ d
  show (Doc d Outer False) = "///" ++ d
  show Shebang = "#!"
  show Eof = "<EOF>"
  
  show Interpolated{} = "<Interpolated>"