use serde::Deserialize;
use serde::Serialize;
use crate::lexer::token::lexeme::Lexeme;
use crate::lexer::token::lexeme::Literal;
use crate::lexer::token::location::Location;
use crate::lexer::token::Token;
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub enum Integer {
Decimal {
inner: String,
},
Hexadecimal {
inner: String,
},
}
impl Integer {
pub fn new_decimal(inner: String) -> Self {
Self::Decimal { inner }
}
pub fn new_hexadecimal(inner: String) -> Self {
Self::Hexadecimal { inner }
}
pub fn parse(input: &str) -> Option<Token> {
let (value, length) = if let Some(body) = input.strip_prefix("0x") {
let end = body
.find(Self::cannot_continue_hexadecimal)
.unwrap_or(body.len());
let length = "0x".len() + end;
let value = Self::new_hexadecimal(input[..length].to_owned());
(value, length)
} else if input.starts_with(Self::can_begin_decimal) {
let end = input
.find(Self::cannot_continue_decimal)
.unwrap_or(input.len());
let length = end;
let value = Self::new_decimal(input[..length].to_owned());
(value, length)
} else {
return None;
};
let length = length
.try_into()
.expect("the YUL should be of reasonable size");
let token = Token::new(
Location::new(0, length),
Lexeme::Literal(Literal::Integer(value)),
length,
);
Some(token)
}
pub fn can_begin_decimal(character: char) -> bool {
Self::can_continue_decimal(character)
}
pub fn can_continue_decimal(character: char) -> bool {
character.is_digit(revive_common::BASE_DECIMAL)
}
pub fn cannot_continue_decimal(character: char) -> bool {
!Self::can_continue_decimal(character)
}
pub fn can_continue_hexadecimal(character: char) -> bool {
character.is_digit(revive_common::BASE_HEXADECIMAL)
}
pub fn cannot_continue_hexadecimal(character: char) -> bool {
!Self::can_continue_hexadecimal(character)
}
}
impl std::fmt::Display for Integer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Decimal { inner } => write!(f, "{inner}"),
Self::Hexadecimal { inner } => write!(f, "{inner}"),
}
}
}