use super::Tokenizer;
use super::token::{Token, TokenKind};
use crate::parse_error::ParseError;
impl Tokenizer<'_> {
pub(super) fn read_number(&mut self, line: usize, col: usize) -> Result<Token, ParseError> {
let mut s = String::new();
let mut is_float = false;
while let Some(ch) = self.peek() {
if ch.is_ascii_digit() {
s.push(self.advance() as char);
} else if ch == b'.' {
if let Some(next) = self.peek_at(1) {
if next.is_ascii_digit() {
is_float = true;
s.push(self.advance() as char); while let Some(d) = self.peek() {
if d.is_ascii_digit() {
s.push(self.advance() as char);
} else {
break;
}
}
} else {
break; }
} else {
break; }
} else {
break;
}
}
if is_float {
let val: f64 = s
.parse()
.map_err(|e| self.lex_error(format!("Invalid float '{s}': {e}")))?;
if val.is_infinite() {
return Err(self.lex_error(format!("Float literal '{s}' overflows f64")));
}
Ok(Token::new(TokenKind::Float(val), line, col))
} else {
let val: i64 = s
.parse()
.map_err(|e| self.lex_error(format!("Invalid integer '{s}': {e}")))?;
Ok(Token::new(TokenKind::Integer(val), line, col))
}
}
}