From 1bb3819350fcb4e867b64d6fb17bd60e2a265a56 Mon Sep 17 00:00:00 2001 From: Kasper Date: Mon, 12 Sep 2022 00:45:29 +0200 Subject: [PATCH] Use rustfmt for some files --- rustfmt.toml | 1 + src/evaluator.rs | 162 +++++++++++++++++++++++++---------------------- src/lib.rs | 81 ++++++++++++++---------- src/main.rs | 14 ++-- src/parser.rs | 149 ++++++++++++++++++++++++------------------- 5 files changed, 223 insertions(+), 184 deletions(-) create mode 100644 rustfmt.toml diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..28781c7 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1 @@ +tab_spaces=2 diff --git a/src/evaluator.rs b/src/evaluator.rs index ce4f94d..02e14a1 100644 --- a/src/evaluator.rs +++ b/src/evaluator.rs @@ -1,13 +1,13 @@ -use decimal::d128; -use crate::{Token, Number}; -use crate::units::{Unit, UnitType, convert, add, subtract, multiply, divide, modulo, pow}; -use crate::parser::AstNode; -use crate::Operator::{Caret, Divide, Minus, Modulo, Multiply, Plus}; -use crate::Constant::{Pi, E}; -use crate::UnaryOperator::{Percent, Factorial}; -use crate::TextOperator::{To, Of}; -use crate::FunctionIdentifier::*; use crate::lookup::{lookup_factorial, lookup_named_number}; +use crate::parser::AstNode; +use crate::units::{add, convert, divide, modulo, multiply, pow, subtract, Unit, UnitType}; +use crate::Constant::{Pi, E}; +use crate::FunctionIdentifier::*; +use crate::Operator::{Caret, Divide, Minus, Modulo, Multiply, Plus}; +use crate::TextOperator::{Of, To}; +use crate::UnaryOperator::{Factorial, Percent}; +use crate::{Number, Token}; +use decimal::d128; /// Evaluate an [`AstNode`] into a [`Number`] pub fn evaluate(ast: &AstNode) -> Result { @@ -16,9 +16,9 @@ pub fn evaluate(ast: &AstNode) -> Result { } /// Returns the factorial of a [`struct@d128`] up to `1000!` without doing any math -/// +/// /// Factorials do not work with decimal numbers. -/// +/// /// All return values of this function are hard-coded. pub fn factorial(input: d128) -> d128 { lookup_factorial(input.into()) @@ -29,7 +29,7 @@ pub fn sqrt(input: d128) -> d128 { let mut n = d128!(1); let half = d128!(0.5); for _ in 0..10 { - n = (n + input/n) * half; + n = (n + input / n) * half; } n } @@ -40,8 +40,8 @@ pub fn cbrt(input: d128) -> d128 { // hope that 20 iterations makes it accurate enough let three = d128!(3); for _ in 0..20 { - let z2 = n*n; - n = n - ((n*z2 - input) / (three*z2)); + let z2 = n * n; + n = n - ((n * z2 - input) / (three * z2)); } n } @@ -68,12 +68,11 @@ pub fn sin(mut input: d128) -> d128 { let mut result = d128!(0); for i_int in 0..precision { let i = d128::from(i_int); - let calc_result = two*i+one; + let calc_result = two * i + one; result += neg_one.pow(i) * (input.pow(calc_result) / factorial(calc_result)); } negative_correction * result - } /// Returns the cosine of a [`struct@d128`] @@ -92,18 +91,16 @@ fn evaluate_node(ast_node: &AstNode) -> Result { let token = &ast_node.token; let children = &ast_node.children; match token { - Token::Number(number) => { - Ok(Number::new(*number, Unit::NoUnit)) - }, - Token::Constant(constant) => { - match constant { - Pi => { - Ok(Number::new(d128!(3.141592653589793238462643383279503), Unit::NoUnit)) - }, - E => { - Ok(Number::new(d128!(2.718281828459045235360287471352662), Unit::NoUnit)) - }, - } + Token::Number(number) => Ok(Number::new(*number, Unit::NoUnit)), + Token::Constant(constant) => match constant { + Pi => Ok(Number::new( + d128!(3.141592653589793238462643383279503), + Unit::NoUnit, + )), + E => Ok(Number::new( + d128!(2.718281828459045235360287471352662), + Unit::NoUnit, + )), }, Token::FunctionIdentifier(function) => { let child_node = children.get(0).ok_or("Paren has no child[0]")?; @@ -116,7 +113,7 @@ fn evaluate_node(ast_node: &AstNode) -> Result { } else { Err("log() only accepts UnitType::NoType".to_string()) } - }, + } Sqrt => { if child_answer.unit.category() == UnitType::NoType { let result = sqrt(child_answer.value); @@ -124,7 +121,7 @@ fn evaluate_node(ast_node: &AstNode) -> Result { } else { Err("log() only accepts UnitType::NoType".to_string()) } - }, + } Log => { if child_answer.unit.category() == UnitType::NoType { let result = child_answer.value.log10(); @@ -132,7 +129,7 @@ fn evaluate_node(ast_node: &AstNode) -> Result { } else { Err("log() only accepts UnitType::NoType".to_string()) } - }, + } Ln => { if child_answer.unit.category() == UnitType::NoType { let result = child_answer.value.ln(); @@ -140,7 +137,7 @@ fn evaluate_node(ast_node: &AstNode) -> Result { } else { Err("ln() only accepts UnitType::NoType".to_string()) } - }, + } Exp => { if child_answer.unit.category() == UnitType::NoType { let result = child_answer.value.exp(child_answer.value); @@ -148,79 +145,92 @@ fn evaluate_node(ast_node: &AstNode) -> Result { } else { Err("exp() only accepts UnitType::NoType".to_string()) } - }, + } Round => { // .quantize() rounds .5 to nearest even integer, so we correct that let mut result = child_answer.value.quantize(d128!(1)); let rounding_change = result - child_answer.value; // If the result was rounded down by 0.5, correct by +1 - if rounding_change == d128!(-0.5) { result += d128!(1); } + if rounding_change == d128!(-0.5) { + result += d128!(1); + } Ok(Number::new(result, child_answer.unit)) - }, + } Ceil => { let mut result = child_answer.value.quantize(d128!(1)); let rounding_change = result - child_answer.value; - if rounding_change.is_negative() { result += d128!(1); } + if rounding_change.is_negative() { + result += d128!(1); + } Ok(Number::new(result, child_answer.unit)) - }, + } Floor => { let mut result = child_answer.value.quantize(d128!(1)); let rounding_change = result - child_answer.value; - if !rounding_change.is_negative() { result -= d128!(1); } + if !rounding_change.is_negative() { + result -= d128!(1); + } Ok(Number::new(result, child_answer.unit)) - }, + } Abs => { let mut result = child_answer.value.abs(); let rounding_change = result - child_answer.value; - if rounding_change == d128!(-0.5) { result += d128!(1); } + if rounding_change == d128!(-0.5) { + result += d128!(1); + } Ok(Number::new(result, child_answer.unit)) - }, + } Sin => { let result = sin(child_answer.value); Ok(Number::new(result, child_answer.unit)) - }, + } Cos => { let result = cos(child_answer.value); Ok(Number::new(result, child_answer.unit)) - }, + } Tan => { let result = tan(child_answer.value); Ok(Number::new(result, child_answer.unit)) - }, + } } } Token::Unit(unit) => { let child_node = children.get(0).ok_or("Unit has no child[0]")?; let child_answer = evaluate_node(child_node)?; Ok(Number::new(child_answer.value, *unit)) - }, + } Token::Negative => { let child_node = children.get(0).ok_or("Negative has no child[0]")?; let child_answer = evaluate_node(child_node)?; Ok(Number::new(-child_answer.value, child_answer.unit)) - }, + } Token::Paren => { let child_node = children.get(0).ok_or("Paren has no child[0]")?; evaluate_node(child_node) - }, + } Token::UnaryOperator(operator) => { - let child_node = children.get(0).ok_or(format!("Token {:?} has no child[0]", token))?; + let child_node = children + .get(0) + .ok_or(format!("Token {:?} has no child[0]", token))?; let child_answer = evaluate_node(child_node)?; match operator { - Percent => { - Ok(Number::new(child_answer.value / d128!(100), child_answer.unit)) - }, + Percent => Ok(Number::new( + child_answer.value / d128!(100), + child_answer.unit, + )), Factorial => { let result = factorial(child_answer.value); if result.is_nan() { return Err("Can only perform factorial on integers from 0 to 1000".to_string()); } Ok(Number::new(result, child_answer.unit)) - }, + } } - }, + } Token::NamedNumber(named_number) => { - let child_node = children.get(0).ok_or(format!("Token {:?} has no child[0]", token))?; + let child_node = children + .get(0) + .ok_or(format!("Token {:?} has no child[0]", token))?; let named_number_value = lookup_named_number(named_number); if let Token::NamedNumber(child_nn) = &child_node.token { let child_nn_value = lookup_named_number(child_nn); @@ -233,8 +243,12 @@ fn evaluate_node(ast_node: &AstNode) -> Result { Ok(Number::new(result, child_answer.unit)) } Token::TextOperator(operator) => { - let left_child = children.get(0).ok_or(format!("Token {:?} has no child[0]", token))?; - let right_child = children.get(1).ok_or(format!("Token {:?} has no child[1]", token))?; + let left_child = children + .get(0) + .ok_or(format!("Token {:?} has no child[0]", token))?; + let right_child = children + .get(1) + .ok_or(format!("Token {:?} has no child[1]", token))?; match operator { To => { @@ -245,7 +259,7 @@ fn evaluate_node(ast_node: &AstNode) -> Result { } else { Err("Right side of To operator needs to be a unit".to_string()) } - }, + } Of => { let left = evaluate_node(left_child)?; let right = evaluate_node(right_child)?; @@ -254,44 +268,40 @@ fn evaluate_node(ast_node: &AstNode) -> Result { } else { Err("Left side of the Of operator must be NoUnit".to_string()) } - }, + } } - }, + } Token::Operator(operator) => { - let left_child = children.get(0).ok_or(format!("Token {:?} has no child[0]", token))?; - let right_child = children.get(1).ok_or(format!("Token {:?} has no child[1]", token))?; + let left_child = children + .get(0) + .ok_or(format!("Token {:?} has no child[0]", token))?; + let right_child = children + .get(1) + .ok_or(format!("Token {:?} has no child[1]", token))?; let left = evaluate_node(left_child)?; let right = evaluate_node(right_child)?; match operator { - Plus => { - Ok(add(left, right)?) - }, - Minus => { - Ok(subtract(left, right)?) - }, + Plus => Ok(add(left, right)?), + Minus => Ok(subtract(left, right)?), Multiply => { Ok(multiply(left, right)?) // } - }, + } Divide => { Ok(divide(left, right)?) // } - }, + } Modulo => { Ok(modulo(left, right)?) // } - }, + } Caret => { Ok(pow(left, right)?) // } - }, - _ => { - Err(format!("Unexpected operator {:?}", operator)) } + _ => Err(format!("Unexpected operator {:?}", operator)), } - }, - _ => { - Err(format!("Unexpected token {:?}", token)) } + _ => Err(format!("Unexpected token {:?}", token)), } } diff --git a/src/lib.rs b/src/lib.rs index bf9b61c..7cd1a14 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,24 +1,24 @@ #![cfg_attr( feature = "cargo-clippy", allow( - clippy::comparison_chain, - clippy::if_same_then_else, - clippy::match_like_matches_macro, + clippy::comparison_chain, + clippy::if_same_then_else, + clippy::match_like_matches_macro, ) )] //! calculation + conversion -//! +//! //! cpc parses and evaluates strings of math, with support for units and conversion. 128-bit decimal floating points are used for high accuracy. -//! +//! //! cpc lets you mix units, so for example 1 km - 1m results in Number { value: 999, unit: Meter }. -//! +//! //! Check out the [list of supported units](units/enum.Unit.html) -//! +//! //! # Example usage //! ```rust //! use cpc::eval; //! use cpc::units::Unit; -//! +//! //! match eval("3m + 1cm", true, Unit::Celsius, false) { //! Ok(answer) => { //! // answer: Number { value: 301, unit: Unit::Centimeter } @@ -30,30 +30,33 @@ //! } //! ``` +use crate::units::Unit; +use decimal::d128; use std::fmt::{self, Display}; use std::time::Instant; -use decimal::d128; -use crate::units::Unit; -/// Units, and functions you can use with them -pub mod units; -/// Turns a string into [`Token`]s -pub mod lexer; -/// Turns [`Token`]s into an [`AstNode`](parser::AstNode) -pub mod parser; /// Turns an [`AstNode`](parser::AstNode) into a [`Number`] pub mod evaluator; +/// Turns a string into [`Token`]s +#[rustfmt::skip] +pub mod lexer; +#[rustfmt::skip] mod lookup; +/// Turns [`Token`]s into an [`AstNode`](parser::AstNode) +pub mod parser; +/// Units, and functions you can use with them +#[rustfmt::skip] +pub mod units; #[derive(Clone, Debug)] /// A number with a `Unit`. -/// +/// /// Example: /// ```rust /// use cpc::{eval,Number}; /// use cpc::units::Unit; /// use decimal::d128; -/// +/// /// let x = Number { /// value: d128!(100), /// unit: Unit::Meter, @@ -92,7 +95,7 @@ pub enum Operator { Divide, Modulo, Caret, - LeftParen, // lexer only + LeftParen, // lexer only RightParen, // lexer only } @@ -155,7 +158,7 @@ pub enum FunctionIdentifier { Log, Ln, Exp, - + Round, Ceil, Floor, @@ -168,7 +171,7 @@ pub enum FunctionIdentifier { #[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 /// the [`PercentChar`](LexerKeyword::PercentChar) variant /// and then later it checks the surrounding [`Token`]s and, @@ -188,7 +191,7 @@ pub enum LexerKeyword { #[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`]. pub enum Token { Operator(Operator), @@ -213,16 +216,16 @@ pub enum Token { macro_rules! numtok { ( $num:literal ) => { Token::Number(d128!($num)) - } + }; } /// Evaluates a string into a resulting [`Number`]. -/// +/// /// Example: /// ```rust /// use cpc::eval; /// use cpc::units::Unit; -/// +/// /// match eval("3m + 1cm", true, Unit::Celsius, false) { /// Ok(answer) => { /// // answer: Number { value: 301, unit: Unit::Centimeter } @@ -233,20 +236,28 @@ macro_rules! numtok { /// } /// } /// ``` -pub fn eval(input: &str, allow_trailing_operators: bool, default_degree: Unit, verbose: bool) -> Result { - +pub fn eval( + input: &str, + allow_trailing_operators: bool, + default_degree: Unit, + verbose: bool, +) -> Result { let lex_start = Instant::now(); match lexer::lex(input, allow_trailing_operators, default_degree) { Ok(tokens) => { let lex_time = Instant::now().duration_since(lex_start).as_nanos() as f32; - if verbose { println!("Lexed TokenVector: {:?}", tokens); } + if verbose { + println!("Lexed TokenVector: {:?}", tokens); + } let parse_start = Instant::now(); match parser::parse(&tokens) { Ok(ast) => { let parse_time = Instant::now().duration_since(parse_start).as_nanos() as f32; - if verbose { println!("Parsed AstNode: {:#?}", ast); } + if verbose { + println!("Parsed AstNode: {:#?}", ast); + } let eval_start = Instant::now(); match evaluator::evaluate(&ast) { @@ -255,19 +266,19 @@ pub fn eval(input: &str, allow_trailing_operators: bool, default_degree: Unit, v if verbose { println!("Evaluated value: {} {:?}", answer.value, answer.unit); - println!("\u{23f1} {:.3}ms lexing", lex_time/1000.0/1000.0); - println!("\u{23f1} {:.3}ms parsing", parse_time/1000.0/1000.0); - println!("\u{23f1} {:.3}ms evaluation", eval_time/1000.0/1000.0); + println!("\u{23f1} {:.3}ms lexing", lex_time / 1000.0 / 1000.0); + println!("\u{23f1} {:.3}ms parsing", parse_time / 1000.0 / 1000.0); + println!("\u{23f1} {:.3}ms evaluation", eval_time / 1000.0 / 1000.0); } Ok(answer) - }, + } Err(e) => Err(format!("Eval error: {}", e)), } - }, + } Err(e) => Err(format!("Parsing error: {}", e)), } - }, + } Err(e) => Err(format!("Lexing error: {}", e)), } } diff --git a/src/main.rs b/src/main.rs index bd5dd84..b57b652 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use cpc::eval; use cpc::units::Unit; -use std::process::exit; use std::env; +use std::process::exit; const VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -30,12 +30,12 @@ fn main() { "--version" => { println!("{}", VERSION); exit(0); - }, + } "--help" => { print_help(); exit(0); - }, - _ => {}, + } + _ => {} } } let mut verbose = false; @@ -58,7 +58,7 @@ fn main() { None => { print_help(); exit(0); - }, + } }; match eval(&expression, true, Unit::Celsius, verbose) { @@ -66,10 +66,10 @@ fn main() { if !verbose { println!("{}", answer); } - }, + } Err(e) => { eprintln!("{}", e); exit(1); - }, + } } } diff --git a/src/parser.rs b/src/parser.rs index 63eae2d..7889ed9 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,8 +1,8 @@ -use crate::Token; -use crate::Operator::{Caret, Divide, LeftParen, Minus, Modulo, Multiply, Plus, RightParen}; -use crate::UnaryOperator::{Percent, Factorial}; -use crate::TextOperator::{To, Of}; use crate::units::Unit::{Foot, Inch}; +use crate::Operator::{Caret, Divide, LeftParen, Minus, Modulo, Multiply, Plus, RightParen}; +use crate::TextOperator::{Of, To}; +use crate::Token; +use crate::UnaryOperator::{Factorial, Percent}; #[derive(Debug)] /// A struct with a [`Token`](AstNode::token) and [`AstNode`] [`children`](AstNode::children) @@ -24,10 +24,15 @@ impl AstNode { /// Parse [`Token`]s into an Abstract Syntax Tree ([`AstNode`]) pub fn parse(tokens: &[Token]) -> Result { - parse_level_1(tokens, 0).and_then(|(ast, next_pos)| if next_pos == tokens.len() { + parse_level_1(tokens, 0).and_then(|(ast, next_pos)| { + if next_pos == tokens.len() { Ok(ast) - } else { - Err(format!("Expected end of input, found {:?} at {}", tokens[next_pos], next_pos)) + } else { + Err(format!( + "Expected end of input, found {:?} at {}", + tokens[next_pos], next_pos + )) + } }) } @@ -49,12 +54,12 @@ pub fn parse_level_1(tokens: &[Token], pos: usize) -> Result<(AstNode, usize), S new_node.children.push(right_node); node = new_node; pos = next_pos; - }, + } // if there's no match, we go down to a lower precedence (or, in this // case, we're done) _ => { return Ok((node, pos)); - }, + } } } } @@ -73,10 +78,10 @@ pub fn parse_level_2(tokens: &[Token], pos: usize) -> Result<(AstNode, usize), S new_node.children.push(right_node); node = new_node; pos = next_pos; - }, + } _ => { return Ok((node, pos)); - }, + } } } } @@ -96,21 +101,17 @@ pub fn parse_level_3(tokens: &[Token], pos: usize) -> Result<(AstNode, usize), S let new_node = AstNode { children: vec![ AstNode { - children: vec![ - AstNode::new(token0.unwrap().clone()), - ], + children: vec![AstNode::new(token0.unwrap().clone())], token: Token::Unit(Foot), }, AstNode { - children: vec![ - AstNode::new(token2.unwrap().clone()), - ], + children: vec![AstNode::new(token2.unwrap().clone())], token: Token::Unit(Inch), }, ], token: Token::Operator(Plus), }; - return Ok((new_node, pos + 4)) + return Ok((new_node, pos + 4)); } } } @@ -121,14 +122,16 @@ pub fn parse_level_3(tokens: &[Token], pos: usize) -> Result<(AstNode, usize), S loop { let token = tokens.get(pos); match token { - Some(&Token::Operator(Multiply)) | Some(&Token::Operator(Divide)) | Some(&Token::Operator(Modulo)) => { + Some(&Token::Operator(Multiply)) + | Some(&Token::Operator(Divide)) + | Some(&Token::Operator(Modulo)) => { let (right_node, next_pos) = parse_level_4(tokens, pos + 1)?; let mut new_node = AstNode::new(token.unwrap().clone()); new_node.children.push(node); new_node.children.push(right_node); node = new_node; pos = next_pos; - }, + } // Below is implicative multiplication, for example '2pi'. Constants and // such will only end up here if they were unable to be parsed as part of @@ -148,12 +151,12 @@ pub fn parse_level_3(tokens: &[Token], pos: usize) -> Result<(AstNode, usize), S new_node.children.push(right_node); node = new_node; pos = next_pos; - }, + } _ => { return Ok((node, pos)); - }, + } } - }, + } // 2pi, )pi Some(&Token::Constant(_)) => { let last_token = tokens.get(pos - 1); @@ -165,12 +168,12 @@ pub fn parse_level_3(tokens: &[Token], pos: usize) -> Result<(AstNode, usize), S new_node.children.push(right_node); node = new_node; pos = next_pos; - }, + } _ => { return Ok((node, pos)); - }, + } } - }, + } // 2log(1), )log(1) Some(&Token::FunctionIdentifier(_)) => { let last_token = tokens.get(pos - 1); @@ -182,32 +185,34 @@ pub fn parse_level_3(tokens: &[Token], pos: usize) -> Result<(AstNode, usize), S new_node.children.push(right_node); node = new_node; pos = next_pos; - }, + } _ => { return Ok((node, pos)); - }, + } } - }, + } // 2(3), pi(3), )(3) Some(&Token::Operator(LeftParen)) => { let last_token = tokens.get(pos - 1); match last_token { - Some(&Token::Number(_)) | Some(&Token::Constant(_)) | Some(&Token::Operator(RightParen)) => { + Some(&Token::Number(_)) + | Some(&Token::Constant(_)) + | Some(&Token::Operator(RightParen)) => { let (right_node, next_pos) = parse_level_4(tokens, pos)?; let mut new_node = AstNode::new(Token::Operator(Multiply)); new_node.children.push(node); new_node.children.push(right_node); node = new_node; pos = next_pos; - }, + } _ => { return Ok((node, pos)); - }, + } } - }, + } _ => { return Ok((node, pos)); - }, + } } } } @@ -226,10 +231,10 @@ pub fn parse_level_4(tokens: &[Token], pos: usize) -> Result<(AstNode, usize), S new_node.children.push(right_node); node = new_node; pos = next_pos; - }, + } _ => { return Ok((node, pos)); - }, + } } } } @@ -239,7 +244,7 @@ pub fn parse_level_4(tokens: &[Token], pos: usize) -> Result<(AstNode, usize), S pub fn parse_level_5(tokens: &[Token], pos: usize) -> Result<(AstNode, usize), String> { // Here we parse the negative unary operator. If the current token // is a minus, we wrap the right_node inside a Negative AstNode. - // + // // Why doesn't this parse 4-5? First, we will first get a 4. In which case, // we just return the result of parse_level_6(), which will include the pos // of +. This will then go down to level 2 and be parsed as a normal minus @@ -254,8 +259,8 @@ pub fn parse_level_5(tokens: &[Token], pos: usize) -> Result<(AstNode, usize), S let mut new_node = AstNode::new(Token::Negative); new_node.children.push(right_node); Ok((new_node, next_pos)) - }, - _ => parse_level_6(tokens, pos) + } + _ => parse_level_6(tokens, pos), } } @@ -266,7 +271,9 @@ pub fn parse_level_6(tokens: &[Token], pos: usize) -> Result<(AstNode, usize), S loop { let token = tokens.get(pos); match token { - Some(&Token::UnaryOperator(Factorial)) | Some(&Token::UnaryOperator(Percent)) | Some(&Token::NamedNumber(_)) => { + Some(&Token::UnaryOperator(Factorial)) + | Some(&Token::UnaryOperator(Percent)) + | Some(&Token::NamedNumber(_)) => { // Here we are handling unary operators, aka stuff written as // "Number Operator" (3!) instead of "Number Operator Number" (3+3). // Therefore, if we find a match, we don't parse what comes after it. @@ -274,19 +281,19 @@ pub fn parse_level_6(tokens: &[Token], pos: usize) -> Result<(AstNode, usize), S new_node.children.push(node); node = new_node; pos += 1; - }, + } Some(&Token::Unit(_unit)) => { // We won't allow units to repeat, like "1min min", so we end the loop if it's found. let mut new_node = AstNode::new(token.unwrap().clone()); new_node.children.push(node); return Ok((new_node, pos + 1)); - }, + } _ => { // let's say we parse 1+2. parse_level_7 then returns 1, and token // is set to plus. Plus has lower precedence than level 4, so we // don't do anything, and pass the number down to a lower precedence. return Ok((node, pos)); - }, + } } } } @@ -298,20 +305,22 @@ pub fn parse_level_6(tokens: &[Token], pos: usize) -> Result<(AstNode, usize), S /// [`FunctionIdentifier`](Token::FunctionIdentifier), /// [`Paren`](Token::Paren) pub fn parse_level_7(tokens: &[Token], pos: usize) -> Result<(AstNode, usize), String> { - let token: &Token = tokens.get(pos).ok_or(format!("Unexpected end of input at {}", pos))?; + let token: &Token = tokens + .get(pos) + .ok_or(format!("Unexpected end of input at {}", pos))?; match token { &Token::Number(_number) => { let node = AstNode::new(token.clone()); Ok((node, pos + 1)) - }, + } &Token::Unit(_unit) => { let node = AstNode::new(token.clone()); Ok((node, pos + 1)) - }, + } Token::Constant(_constant) => { let node = AstNode::new(token.clone()); Ok((node, pos + 1)) - }, + } Token::FunctionIdentifier(_function_identifier) => { let left_paren_pos = pos + 1; let left_paren_token = tokens.get(left_paren_pos); @@ -326,28 +335,36 @@ pub fn parse_level_7(tokens: &[Token], pos: usize) -> Result<(AstNode, usize), S function_node.children.push(node); Ok((function_node, next_pos + 1)) } else { - Err(format!("Expected closing paren at {} but found {:?}", next_pos, tokens.get(next_pos))) + Err(format!( + "Expected closing paren at {} but found {:?}", + next_pos, + tokens.get(next_pos) + )) } }) - }, - _ => { - Err(format!("Expected ( after {} at {:?} but found {:?}", left_paren_pos, token, left_paren_token)) } + _ => Err(format!( + "Expected ( after {} at {:?} but found {:?}", + left_paren_pos, token, left_paren_token + )), } - }, - Token::Operator(LeftParen) => { - parse_level_1(tokens, pos + 1).and_then(|(node, next_pos)| { - if let Some(&Token::Operator(RightParen)) = tokens.get(next_pos) { - let mut paren_node = AstNode::new(Token::Paren); - paren_node.children.push(node); - Ok((paren_node, next_pos + 1)) - } else { - Err(format!("Expected closing paren at {} but found {:?}", next_pos, tokens.get(next_pos))) - } - }) - }, - _ => { - Err(format!("Unexpected token {:?}, expected paren or number", token)) - }, + } + Token::Operator(LeftParen) => parse_level_1(tokens, pos + 1).and_then(|(node, next_pos)| { + if let Some(&Token::Operator(RightParen)) = tokens.get(next_pos) { + let mut paren_node = AstNode::new(Token::Paren); + paren_node.children.push(node); + Ok((paren_node, next_pos + 1)) + } else { + Err(format!( + "Expected closing paren at {} but found {:?}", + next_pos, + tokens.get(next_pos) + )) + } + }), + _ => Err(format!( + "Unexpected token {:?}, expected paren or number", + token + )), } }