Add float lexing
This commit is contained in:
parent
1607db20f9
commit
51c7ae148c
@ -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";
|
||||||
|
@ -10,4 +10,5 @@ pub enum Token {
|
|||||||
Star,
|
Star,
|
||||||
LeftParenthesis,
|
LeftParenthesis,
|
||||||
RightParenthesis,
|
RightParenthesis,
|
||||||
|
Float(f64),
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user