{-| Module : Language.Rust.Syntax.Token Description : Token definitions Copyright : (c) Alec Theriault, 2017-2018 License : BSD-style Maintainer : alec.theriault@gmail.com Stability : experimental Portability : GHC Contains roughly the same stuff as @syntax::parse::token@ - data definitions for tokens. -} {-# 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(..) ) -- | A general token (based on @syntax::parse::token::Token@). -- -- Unlike its @libsyntax@ counterpart, 'Token' has folded in @syntax::parse::token::BinOpToken@ -- and @syntax::parse::token::BinOpEqToken@ as regular tokens. data Token -- Single character expression-operator symbols. = Equal -- ^ @=@ token | Less -- ^ @<@ token | Greater -- ^ @>@ token | Ampersand -- ^ @&@ token | Pipe -- ^ @|@ token | Exclamation -- ^ @!@ token | Tilde -- ^ @~@ token | Plus -- ^ @+@ token | Minus -- ^ @-@ token | Star -- ^ @*@ token | Slash -- ^ @/@ token | Percent -- ^ @%@ token | Caret -- ^ @^@ token -- Multi character expression-operator symbols | GreaterEqual -- ^ @>=@ token | GreaterGreaterEqual -- ^ @>>=@ token | AmpersandAmpersand -- ^ @&&@ token | PipePipe -- ^ @||@ token | LessLess -- ^ @<<@ token | GreaterGreater -- ^ @>>@ token | EqualEqual -- ^ @==@ token | NotEqual -- ^ @!=@ token | LessEqual -- ^ @<=@ token | LessLessEqual -- ^ @<<=@ token | MinusEqual -- ^ @-=@ token | AmpersandEqual -- ^ @&=@ token | PipeEqual -- ^ @|=@ token | PlusEqual -- ^ @+=@ token | StarEqual -- ^ @*=@ token | SlashEqual -- ^ @/=@ token | CaretEqual -- ^ @^=@ token | PercentEqual -- ^ @%=@ token -- Structural symbols | At -- ^ @\@@ token | Dot -- ^ @.@ token | DotDot -- ^ @..@ token | DotDotEqual -- ^ @..=@ token | DotDotDot -- ^ @...@ token | Comma -- ^ @,@ token | Semicolon -- ^ @;@ token | Colon -- ^ @:@ token | ModSep -- ^ @::@ token | RArrow -- ^ @->@ token | LArrow -- ^ @<-@ token | FatArrow -- ^ @=>@ token | Pound -- ^ @#@ token | Dollar -- ^ @$@ token | Question -- ^ @?@ token -- Embedded code | EmbeddedCode String -- ^ @${@ ... @}@ token containing embedded code | EmbeddedIdent String -- ^ @${@ ... @}@ token containing embedded code -- Delimiters | OpenDelim !Delim -- ^ One of @(@, @[@, @{@ | CloseDelim !Delim -- ^ One of @)@, @]@, @}@ -- Literals | LiteralTok LitTok (Maybe Name) -- ^ a literal token with an optional suffix (something like @i32@) -- Name components | IdentTok Ident -- ^ an arbitrary identifier (something like @x@ or @foo@ or @and_then@) | LifetimeTok Ident -- ^ a lifetime (something like @\'a@ or @\'static@) | Space Space Name -- ^ whitespace | Doc String !AttrStyle !Bool -- ^ doc comment with its contents, whether it is outer/inner, and whether it is inline or not | Shebang -- ^ @#!@ shebang token | Eof -- ^ end of file token -- NOT PRODUCED IN TOKENIZATION!! | Interpolated (Nonterminal Span) -- ^ can be expanded into several tokens in macro-expansion deriving (Eq, Ord, Data, Typeable, Generic, NFData) -- | Rust is whitespace independent. Short of providing space between tokens, whitespace is all the -- same to the parser. data Space = Whitespace -- ^ usual white space: @[\\ \\t\\n\\f\\v\\r]+@ | Comment -- ^ comment (either inline or not) deriving (Eq, Ord, Show, Enum, Bounded, Data, Typeable, Generic, NFData) -- TODO: BANISH NoDelim! (or rather: distinguish DelimToken from Delim, as rustc does) -- | A delimiter token (@syntax::parse::token::DelimToken@). data Delim = Paren -- ^ round parenthesis: @(@ or @)@ | Bracket -- ^ square bracket: @[@ or @]@ | Brace -- ^ curly brace: @{@ or @}@ | NoDelim -- ^ empty delimiter deriving (Eq, Ord, Enum, Bounded, Show, Data, Typeable, Generic, NFData) -- | A literal token (@syntax::parse::token::Lit@) data LitTok = ByteTok Name -- ^ byte | CharTok Name -- ^ character | IntegerTok Name -- ^ integral literal (could have type @i32@, @int@, @u128@, etc.) | FloatTok Name -- ^ floating point literal (could have type @f32@, @f64@, etc.) | StrTok Name -- ^ string literal | StrRawTok Name !Int -- ^ raw string literal and the number of @#@ marks around it | ByteStrTok Name -- ^ byte string literal | ByteStrRawTok Name !Int -- ^ raw byte string literal and the number of @#@ marks around it deriving (Eq, Ord, Show, Data, Typeable, Generic, NFData) -- | Check whether a space is needed between two tokens to avoid confusion. spaceNeeded :: Token -> Token -> Bool -- conflicts with 'GreaterEqual' spaceNeeded Greater Equal = True spaceNeeded Greater EqualEqual = True spaceNeeded Greater FatArrow = True -- conflicts with 'GreaterGreaterEqual' spaceNeeded Greater GreaterEqual = True spaceNeeded GreaterGreater Equal = True spaceNeeded GreaterGreater EqualEqual = True spaceNeeded GreaterGreater FatArrow = True -- conflicts with 'AmpersandAmpersand' spaceNeeded Ampersand Ampersand = True spaceNeeded Ampersand AmpersandAmpersand = True spaceNeeded Ampersand AmpersandEqual = True -- conflicts with 'PipePipe' spaceNeeded Pipe Pipe = True spaceNeeded Pipe PipePipe = True spaceNeeded Pipe PipeEqual = True -- conflicts with 'LessLess' spaceNeeded Less Less = True spaceNeeded Less LessLess = True spaceNeeded Less LessLessEqual = True spaceNeeded Less LArrow = True -- conflicts with 'GreaterGreater' spaceNeeded Greater Greater = True spaceNeeded Greater GreaterGreater = True spaceNeeded Greater GreaterGreaterEqual = True -- conflicts with 'EqualEqual' spaceNeeded Equal Equal = True spaceNeeded Equal EqualEqual = True spaceNeeded Equal FatArrow = True -- conflicts with 'NotEqual' spaceNeeded Exclamation Equal = True spaceNeeded Exclamation EqualEqual = True spaceNeeded Exclamation FatArrow = True -- conflicts with 'LessEqual' spaceNeeded Less Equal = True spaceNeeded Less EqualEqual = True spaceNeeded Less FatArrow = True -- conflicts with 'LessLessEqual' spaceNeeded Less LessEqual = True spaceNeeded LessLess Equal = True spaceNeeded LessLess EqualEqual = True spaceNeeded LessLess FatArrow = True -- conflicts with 'MinusEqual' spaceNeeded Minus Equal = True spaceNeeded Minus EqualEqual = True spaceNeeded Minus FatArrow = True -- conflicts with 'AmpersandEqual' spaceNeeded Ampersand Equal = True spaceNeeded Ampersand EqualEqual = True spaceNeeded Ampersand FatArrow = True -- conflicts with 'PipeEqual' spaceNeeded Pipe Equal = True spaceNeeded Pipe EqualEqual = True spaceNeeded Pipe FatArrow = True -- conflicts with 'PlusEqual' spaceNeeded Plus Equal = True spaceNeeded Plus EqualEqual = True spaceNeeded Plus FatArrow = True -- conflicts with 'StarEqual' spaceNeeded Star Equal = True spaceNeeded Star EqualEqual = True spaceNeeded Star FatArrow = True -- conflicts with 'SlashEqual' spaceNeeded Slash Equal = True spaceNeeded Slash EqualEqual = True spaceNeeded Slash FatArrow = True -- conflicts with 'CaretEqual' spaceNeeded Caret Equal = True spaceNeeded Caret EqualEqual = True spaceNeeded Caret FatArrow = True -- conflicts with 'PercentEqual' spaceNeeded Percent Equal = True spaceNeeded Percent EqualEqual = True spaceNeeded Percent FatArrow = True -- conflicts with 'DotDot' spaceNeeded Dot Dot = True spaceNeeded Dot DotDot = True spaceNeeded Dot DotDotDot = True -- conflicts with 'DotDotDot' spaceNeeded DotDot Dot = True spaceNeeded DotDot DotDot = True spaceNeeded DotDot DotDotDot = True -- conflicts with 'DotDotEqual' spaceNeeded DotDot Equal = True spaceNeeded DotDot EqualEqual = True spaceNeeded DotDot FatArrow = True -- conflicts with 'ModSep' spaceNeeded Colon Colon = True spaceNeeded Colon ModSep = True -- conflicts with 'RArrow' spaceNeeded Minus Greater = True spaceNeeded Minus GreaterGreater = True spaceNeeded Minus GreaterEqual = True spaceNeeded Minus GreaterGreaterEqual = True -- conflicts with 'LArrow' spaceNeeded Less Minus = True spaceNeeded Less MinusEqual = True spaceNeeded Less RArrow = True -- conflicts with 'FatArrow' spaceNeeded Equal Greater = True spaceNeeded Equal GreaterGreater = True spaceNeeded Equal GreaterEqual = True spaceNeeded Equal GreaterGreaterEqual = True -- conflicts with 'LiteralTok' spaceNeeded LiteralTok{} IdentTok{} = True -- conflicts with 'IdentTok' spaceNeeded IdentTok{} IdentTok{} = True -- conflicts with 'Shebang' spaceNeeded Pound Exclamation = True spaceNeeded Pound NotEqual = True -- there are no other conflicts spaceNeeded _ _ = False -- | This instance is only for error messages and debugging purposes. instance Show Token where -- Single character expression-operator symbols. show Equal = "=" show Less = "<" show Greater = ">" show Ampersand = "&" show Pipe = "|" show Exclamation = "!" show Tilde = "~" show Plus = "+" show Minus = "-" show Star = "*" show Slash = "/" show Percent = "%" -- Multi character eexpression-operator symbols 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 = "^" -- Structural symbols 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 = "?" -- Embedded code show (EmbeddedCode s) = "${e|" ++ s ++ "|}" show (EmbeddedIdent s) = "${i|" ++ s ++ "|}" -- Delimiters, eg. @{@, @${@, @]@, @(@ show (OpenDelim Paren) = "(" show (OpenDelim Bracket) = "[" show (OpenDelim Brace) = "{" show (OpenDelim NoDelim) = "" show (CloseDelim Paren) = ")" show (CloseDelim Bracket) = "]" show (CloseDelim Brace) = "}" show (CloseDelim NoDelim) = "" -- Literals 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 -- Name components show (IdentTok i) = show $ name i show (LifetimeTok l) = "'" ++ show l show (Space 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 = "" -- Macro related show Interpolated{} = ""