From 51c7ae148c3f06336e80e9432e3e496076e15cec Mon Sep 17 00:00:00 2001 From: Jeff Date: Sun, 4 Aug 2024 19:41:00 -0400 Subject: [PATCH] Add float lexing --- dust-lang/src/lex.rs | 52 +++++++++++++++++++++++++++++++++++++----- dust-lang/src/token.rs | 1 + 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/dust-lang/src/lex.rs b/dust-lang/src/lex.rs index 0a1c65c..f1a0271 100644 --- a/dust-lang/src/lex.rs +++ b/dust-lang/src/lex.rs @@ -1,3 +1,5 @@ +use std::num::{ParseFloatError, ParseIntError}; + use crate::{Identifier, Span, Token}; pub fn lex(input: &str) -> Result, LexError> { @@ -88,8 +90,23 @@ impl<'a> Lexer<'a> { fn lex_number(&mut self) -> Result<(Token, Span), LexError> { 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() { + if c.is_ascii_digit() { + self.next_char(); + } else { + break; + } + } + } + if c.is_ascii_digit() { self.next_char(); } else { @@ -97,9 +114,15 @@ impl<'a> Lexer<'a> { } } - let integer = self.input[start_pos..self.position].parse::()?; + if is_float { + let float = self.input[start_pos..self.position].parse::()?; - Ok((Token::Number(integer), (start_pos, self.position))) + Ok((Token::Float(float), (start_pos, self.position))) + } else { + let integer = self.input[start_pos..self.position].parse::()?; + + Ok((Token::Number(integer), (start_pos, self.position))) + } } fn lex_identifier(&mut self) -> Result<(Token, Span), LexError> { @@ -122,12 +145,19 @@ impl<'a> Lexer<'a> { #[derive(Debug, PartialEq, Clone)] pub enum LexError { - IntegerParseError(std::num::ParseIntError), + FloatError(ParseFloatError), + IntegerError(ParseIntError), } -impl From for LexError { - fn from(v: std::num::ParseIntError) -> Self { - Self::IntegerParseError(v) +impl From for LexError { + fn from(error: std::num::ParseFloatError) -> Self { + Self::FloatError(error) + } +} + +impl From for LexError { + fn from(error: std::num::ParseIntError) -> Self { + Self::IntegerError(error) } } @@ -135,6 +165,16 @@ impl From for LexError { mod tests { 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] fn add() { let input = "1 + 2"; diff --git a/dust-lang/src/token.rs b/dust-lang/src/token.rs index 4c18804..ad1a31b 100644 --- a/dust-lang/src/token.rs +++ b/dust-lang/src/token.rs @@ -10,4 +10,5 @@ pub enum Token { Star, LeftParenthesis, RightParenthesis, + Float(f64), }