use crate::lexer::token::lexeme::keyword::Keyword;
use crate::lexer::token::lexeme::Lexeme;
use crate::lexer::token::location::Location;
use crate::lexer::token::Token;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Identifier {
pub inner: String,
}
impl Identifier {
pub fn new(inner: String) -> Self {
Self { inner }
}
pub fn parse(input: &str) -> Option<Token> {
if !input.starts_with(Self::can_begin) {
return None;
}
let end = input.find(Self::cannot_continue).unwrap_or(input.len());
let inner = input[..end].to_string();
let length = inner
.len()
.try_into()
.expect("the YUL should be of reasonable size");
if let Some(token) = Keyword::parse(inner.as_str()) {
return Some(token);
}
Some(Token::new(
Location::new(0, length),
Lexeme::Identifier(Self::new(inner)),
length,
))
}
pub fn can_begin(character: char) -> bool {
character.is_alphabetic() || character == '_' || character == '$'
}
pub fn can_continue(character: char) -> bool {
Self::can_begin(character)
|| character.is_numeric()
|| character == '_'
|| character == '$'
|| character == '.'
}
pub fn cannot_continue(character: char) -> bool {
!Self::can_continue(character)
}
}
impl std::fmt::Display for Identifier {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.inner)
}
}