// SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2020 The Gleam contributors use num_bigint::BigInt; use std::fmt; use ecow::EcoString; use crate::parse::LiteralFloatValue; #[derive(Clone, Debug, PartialEq, Eq)] pub enum Token { Name { name: EcoString, }, UpName { name: EcoString, }, DiscardName { name: EcoString, }, Int { value: EcoString, int_value: BigInt, }, Float { value: EcoString, float_value: LiteralFloatValue, }, String { value: EcoString, }, CommentDoc { content: EcoString, }, // Groupings LeftParen, // ( RightParen, // ) LeftSquare, // [ RightSquare, // ] LeftBrace, // { RightBrace, // } // Int Operators Plus, Minus, Star, Slash, Less, Greater, LessEqual, GreaterEqual, Percent, // Float Operators PlusDot, // '+.' MinusDot, // '-.' StarDot, // '*.' SlashDot, // '/.' LessDot, // '<.' GreaterDot, // '>.' LessEqualDot, // '<=.' GreaterEqualDot, // '>=.' // String Operators Concatenate, // '<>' // Other Punctuation Colon, Comma, Hash, // '#' Bang, // '!' Equal, EqualEqual, // '==' NotEqual, // '!=' Vbar, // '|' VbarVbar, // '||' AmperAmper, // '&&' LtLt, // '<<' GtGt, // '>>' Pipe, // '|>' Dot, // '.' RArrow, // '->' LArrow, // '<-' DotDot, // '..' At, // '@' EndOfFile, // Extra CommentNormal, CommentModule, NewLine, // Keywords (alphabetically): As, Assert, Auto, Case, Const, Delegate, Derive, Echo, Else, Fn, If, Implement, Import, Let, Macro, Opaque, Panic, Pub, Test, Todo, Type, Use, } impl Token { pub fn guard_precedence(&self) -> Option { match self { Self::VbarVbar => Some(1), Self::AmperAmper => Some(2), Self::EqualEqual | Self::NotEqual => Some(3), Self::Less | Self::LessEqual | Self::LessDot | Self::LessEqualDot | Self::GreaterEqual | Self::Greater | Self::GreaterEqualDot | Self::GreaterDot => Some(4), Self::Concatenate => Some(5), Self::Plus | Self::PlusDot | Self::Minus | Self::MinusDot => Some(6), Self::Star | Self::StarDot | Self::Slash | Self::SlashDot | Self::Percent => Some(7), Self::Name { .. } | Self::UpName { .. } | Self::DiscardName { .. } | Self::Int { .. } | Self::Float { .. } | Self::String { .. } | Self::CommentDoc { .. } | Self::LeftParen | Self::RightParen | Self::LeftSquare | Self::RightSquare | Self::LeftBrace | Self::RightBrace | Self::Colon | Self::Comma | Self::Hash | Self::Bang | Self::Equal | Self::Vbar | Self::LtLt | Self::GtGt | Self::Pipe | Self::Dot | Self::RArrow | Self::LArrow | Self::DotDot | Self::At | Self::EndOfFile | Self::CommentNormal | Self::CommentModule | Self::NewLine | Self::As | Self::Assert | Self::Auto | Self::Case | Self::Const | Self::Delegate | Self::Derive | Self::Echo | Self::Else | Self::Fn | Self::If | Self::Implement | Self::Import | Self::Let | Self::Macro | Self::Opaque | Self::Panic | Self::Pub | Self::Test | Self::Todo | Self::Type | Self::Use => None, } } pub fn is_reserved_word(&self) -> bool { match self { Token::As | Token::Assert | Token::Case | Token::Const | Token::Fn | Token::If | Token::Import | Token::Let | Token::Opaque | Token::Pub | Token::Todo | Token::Type | Token::Use | Token::Auto | Token::Delegate | Token::Derive | Token::Echo | Token::Else | Token::Implement | Token::Macro | Token::Panic | Token::Test => true, Token::Name { .. } | Token::UpName { .. } | Token::DiscardName { .. } | Token::Int { .. } | Token::Float { .. } | Token::String { .. } | Token::CommentDoc { .. } | Token::LeftParen | Token::RightParen | Token::LeftSquare | Token::RightSquare | Token::LeftBrace | Token::RightBrace | Token::Plus | Token::Minus | Token::Star | Token::Slash | Token::Less | Token::Greater | Token::LessEqual | Token::GreaterEqual | Token::Percent | Token::PlusDot | Token::MinusDot | Token::StarDot | Token::SlashDot | Token::LessDot | Token::GreaterDot | Token::LessEqualDot | Token::GreaterEqualDot | Token::Concatenate | Token::Colon | Token::Comma | Token::Hash | Token::Bang | Token::Equal | Token::EqualEqual | Token::NotEqual | Token::Vbar | Token::VbarVbar | Token::AmperAmper | Token::LtLt | Token::GtGt | Token::Pipe | Token::Dot | Token::RArrow | Token::LArrow | Token::DotDot | Token::At | Token::EndOfFile | Token::CommentNormal | Token::CommentModule | Token::NewLine => false, } } } impl fmt::Display for Token { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let s = match self { Token::Name { name } | Token::UpName { name } | Token::DiscardName { name } => { name.as_str() } Token::Int { value, int_value: _, } | Token::Float { value, float_value: _, } | Token::String { value } => value.as_str(), Token::AmperAmper => "&&", Token::As => "as", Token::Assert => "assert", Token::At => "@", Token::Auto => "auto", Token::Bang => "!", Token::Case => "case", Token::Colon => ":", Token::Comma => ",", Token::CommentDoc { .. } => "///", Token::CommentModule => "////", Token::CommentNormal => "//", Token::Const => "const", Token::Delegate => "delegate", Token::Derive => "derive", Token::Dot => ".", Token::DotDot => "..", Token::Echo => "echo", Token::Else => "else", Token::NewLine => "NEWLINE", Token::EndOfFile => "EOF", Token::Equal => "=", Token::EqualEqual => "==", Token::Fn => "fn", Token::Greater => ">", Token::GreaterDot => ">.", Token::GreaterEqual => ">=", Token::GreaterEqualDot => ">=.", Token::GtGt => ">>", Token::Hash => "#", Token::If => "if", Token::Implement => "implement", Token::Import => "import", Token::LArrow => "<-", Token::LeftBrace => "{", Token::LeftParen => "(", Token::LeftSquare => "[", Token::Less => "<", Token::LessDot => "<.", Token::LessEqual => "<=", Token::LessEqualDot => "<=.", Token::Let => "let", Token::Concatenate => "<>", Token::LtLt => "<<", Token::Macro => "macro", Token::Minus => "-", Token::MinusDot => "-.", Token::NotEqual => "!=", Token::Opaque => "opaque", Token::Panic => "panic", Token::Percent => "%", Token::Pipe => "|>", Token::Plus => "+", Token::PlusDot => "+.", Token::Pub => "pub", Token::RArrow => "->", Token::RightBrace => "}", Token::RightParen => ")", Token::RightSquare => "]", Token::Slash => "/", Token::SlashDot => "/.", Token::Star => "*", Token::StarDot => "*.", Token::Test => "test", Token::Todo => "todo", Token::Type => "type", Token::Use => "use", Token::Vbar => "|", Token::VbarVbar => "||", }; write!(f, "`{s}`") } }