Merge pull request #15 from djmattyg007/add_lexer_tests

Add initial set of tests for the lexer
This commit is contained in:
Kasper 2021-07-03 06:45:31 +02:00 committed by GitHub
commit 4904ac3c21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 8 deletions

View File

@ -589,3 +589,29 @@ pub fn lex(input: &str, allow_trailing_operators: bool, default_degree: Unit) ->
Ok(tokens)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::numtok;
#[test]
fn test_lex() {
pub fn run_lex(input: &str, expected_tokens: Vec<Token>) {
let tokens = lex(input, false, Unit::Celsius).unwrap();
let matching_tokens = tokens.iter().zip(&expected_tokens).filter(|&(a, b)| a == b);
assert_eq!(matching_tokens.count(), expected_tokens.len());
}
run_lex("42 millilitres", vec![numtok!(42), Token::Unit(Milliliter)]);
run_lex("50 / 10", vec![numtok!(50), Token::Operator(Divide), numtok!(10)]);
run_lex("33.3 square meters", vec![numtok!(33.3), Token::Unit(SquareMeter)]);
run_lex("101 nautical miles", vec![numtok!(101), Token::Unit(NauticalMile)]);
run_lex("87 sq miles", vec![numtok!(87), Token::Unit(SquareMile)]);
run_lex("1 light year", vec![numtok!(1), Token::Unit(LightYear)]);
run_lex("34 cubic feet + 23 cubic yards", vec![numtok!(34), Token::Unit(CubicFoot), Token::Operator(Plus), numtok!(23), Token::Unit(CubicYard)]);
run_lex("50 metric tonnes", vec![numtok!(50), Token::Unit(MetricTon)]);
run_lex("5432 newton metres", vec![numtok!(5432), Token::Unit(NewtonMeter)]);
run_lex("2345 newton-meters", vec![numtok!(2345), Token::Unit(NewtonMeter)]);
}
}

View File

@ -78,7 +78,7 @@ impl Display for Number {
}
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
/// Math operators like [`Multiply`](Operator::Multiply), parentheses, etc.
pub enum Operator {
Plus,
@ -91,21 +91,21 @@ pub enum Operator {
RightParen, // lexer only
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
/// Unary operators like [`Percent`](UnaryOperator::Percent) and [`Factorial`](UnaryOperator::Factorial).
pub enum UnaryOperator {
Percent,
Factorial,
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
/// A Text operator like [`To`](TextOperator::To) or [`Of`](TextOperator::Of).
pub enum TextOperator {
To,
Of,
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
/// A named number like [`Million`](NamedNumber::Million).
pub enum NamedNumber {
Hundred,
@ -134,14 +134,14 @@ pub enum NamedNumber {
Googol,
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
/// A constant like [`Pi`](Constant::Pi) or [`E`](Constant::E).
pub enum Constant {
Pi,
E,
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
/// Functions identifiers like [`Sqrt`](FunctionIdentifier::Sqrt), [`Sin`](FunctionIdentifier::Sin), [`Round`](FunctionIdentifier::Round), etc.
pub enum FunctionIdentifier {
Sqrt,
@ -161,7 +161,7 @@ pub enum FunctionIdentifier {
Tan,
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
/// A temporary enum used by the [`lexer`] to later determine what [`Token`] it is.
///
/// For example, when a symbol like `%` is found, the lexer turns it into a
@ -180,7 +180,7 @@ pub enum LexerKeyword {
Force,
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
/// A token like a [`Number`](Token::Number), [`Operator`](Token::Operator), [`Unit`](Token::Unit) etc.
///
/// Strings can be divided up into these tokens by the [`lexer`], and then put into the [`parser`].
@ -203,6 +203,13 @@ pub enum Token {
Unit(units::Unit),
}
#[macro_export]
macro_rules! numtok {
( $num:literal ) => {
Token::Number(d128!($num));
}
}
/// Evaluates a string into a resulting [`Number`].
///
/// Example: