Add float lexing

This commit is contained in:
Jeff 2024-08-04 19:41:00 -04:00
parent 1607db20f9
commit 51c7ae148c
2 changed files with 47 additions and 6 deletions

View File

@ -1,3 +1,5 @@
use std::num::{ParseFloatError, ParseIntError};
use crate::{Identifier, Span, Token}; use crate::{Identifier, Span, Token};
pub fn lex(input: &str) -> Result<Vec<(Token, Span)>, LexError> { pub fn lex(input: &str) -> Result<Vec<(Token, Span)>, LexError> {
@ -88,6 +90,13 @@ impl<'a> Lexer<'a> {
fn lex_number(&mut self) -> Result<(Token, Span), LexError> { fn lex_number(&mut self) -> Result<(Token, Span), LexError> {
let start_pos = self.position; let start_pos = self.position;
let mut is_float = false;
while let Some(c) = self.peek_char() {
if c == '.' {
is_float = true;
self.next_char();
while let Some(c) = self.peek_char() { while let Some(c) = self.peek_char() {
if c.is_ascii_digit() { if c.is_ascii_digit() {
@ -96,11 +105,25 @@ impl<'a> Lexer<'a> {
break; break;
} }
} }
}
if c.is_ascii_digit() {
self.next_char();
} else {
break;
}
}
if is_float {
let float = self.input[start_pos..self.position].parse::<f64>()?;
Ok((Token::Float(float), (start_pos, self.position)))
} else {
let integer = self.input[start_pos..self.position].parse::<i64>()?; let integer = self.input[start_pos..self.position].parse::<i64>()?;
Ok((Token::Number(integer), (start_pos, self.position))) Ok((Token::Number(integer), (start_pos, self.position)))
} }
}
fn lex_identifier(&mut self) -> Result<(Token, Span), LexError> { fn lex_identifier(&mut self) -> Result<(Token, Span), LexError> {
let start_pos = self.position; let start_pos = self.position;
@ -122,12 +145,19 @@ impl<'a> Lexer<'a> {
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub enum LexError { pub enum LexError {
IntegerParseError(std::num::ParseIntError), FloatError(ParseFloatError),
IntegerError(ParseIntError),
} }
impl From<std::num::ParseIntError> for LexError { impl From<ParseFloatError> for LexError {
fn from(v: std::num::ParseIntError) -> Self { fn from(error: std::num::ParseFloatError) -> Self {
Self::IntegerParseError(v) Self::FloatError(error)
}
}
impl From<ParseIntError> for LexError {
fn from(error: std::num::ParseIntError) -> Self {
Self::IntegerError(error)
} }
} }
@ -135,6 +165,16 @@ impl From<std::num::ParseIntError> for LexError {
mod tests { mod tests {
use super::*; use super::*;
#[test]
fn float() {
let input = "1.23";
assert_eq!(
lex(input),
Ok(vec![(Token::Float(1.23), (0, 4)), (Token::Eof, (4, 4)),])
)
}
#[test] #[test]
fn add() { fn add() {
let input = "1 + 2"; let input = "1 + 2";

View File

@ -10,4 +10,5 @@ pub enum Token {
Star, Star,
LeftParenthesis, LeftParenthesis,
RightParenthesis, RightParenthesis,
Float(f64),
} }