Skip to content

Commit

Permalink
Parse decimal number literals
Browse files Browse the repository at this point in the history
  • Loading branch information
kdkasad committed Oct 3, 2022
1 parent 080b4ad commit 3c28693
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 7 deletions.
6 changes: 4 additions & 2 deletions src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,11 @@ impl Iterator for Lexer {
// consume whitespace and continue
collect_chars(&mut self.chars, |c| c.is_whitespace());
self.next()
} else if c.is_numeric() {
} else if c.is_numeric() || c == '.' {
// c is a digit
// collect contiguous digits and return number token
Some(Token::Number(collect_chars(&mut self.chars, |c| {
c.is_numeric()
c.is_numeric() || c == '.'
})))
} else if "({[".contains(c) {
self.chars.next();
Expand Down Expand Up @@ -213,6 +213,8 @@ mod tests {
"foo := 1 + 2^3",
toks!(i foo, o ":=", n 1, o "+", n 2, o "^", n 3),
),
("1.23", toks!(n 1.23,)),
("1.35 m", toks!(n 1.35, i m)),
];
for (src, toks) in cases {
let result: Vec<Token> = Lexer::new(src).collect();
Expand Down
15 changes: 10 additions & 5 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ use crate::{
ast::{BinaryExpression, Node, Variable},
lexer::{Lexer, Token},
operation::Operation,
rat_util_macros::rat,
};

pub struct Parser {
Expand Down Expand Up @@ -113,8 +112,11 @@ impl Parser {
}

fn str_to_num(src: &str) -> Result<BigRational, ParseError> {
match src.parse::<i32>() {
Ok(int) => Ok(rat!(int)),
match src.parse::<f64>() {
Ok(float) => match BigRational::from_float(float) {
Some(rat) => Ok(rat),
None => Err(ParseError::ParseNumberLiteral(src.to_owned())),
},
Err(_) => Err(ParseError::ParseNumberLiteral(src.to_owned())),
}
}
Expand Down Expand Up @@ -177,7 +179,6 @@ mod tests {
use pretty_assertions::assert_eq;

use super::*;
use crate::rat_util_macros::rat;

#[test]
fn parse_valid_expressions() {
Expand All @@ -194,7 +195,7 @@ mod tests {
( ( $($e:tt)+ ) ) => {
binexpr!( $($e)+ )
};
( $num:literal ) => { Node::Number(rat!($num)) };
( $num:literal ) => { Node::Number(BigRational::from_float($num as f64).unwrap()) };
( $name:ident ) => { Node::Variable(Variable::from(stringify!($name))) };
}

Expand All @@ -219,6 +220,9 @@ mod tests {
("foo := 1 + 2^3", binexpr!(":=" foo ("+" 1 ("^" 2 3)))),
("a := b := c", binexpr!(":=" a (":=" b c))),
("1 + a := 2 + 3", binexpr!("+" 1 (":=" a ("+" 2 3)))),
("1.5", subexpr!(1.5)),
(".0125", subexpr!(0.0125)),
("180.", subexpr!(180)),
];

for (input, expected_result) in cases {
Expand All @@ -243,6 +247,7 @@ mod tests {
ParseError::ExpectedOperand("operator") => ["+", "-", "*", "/", "1 * +"];
ParseError::ExpectedToken("operator", _got) => ["1 a 2"];
ParseError::IllegalToken(_) => ["123 ? 456", "&", "#001"];
ParseError::ParseNumberLiteral(_) => ["1.2.3"];
}
}
}

0 comments on commit 3c28693

Please sign in to comment.