diff --git a/cli/src/main.rs b/cli/src/main.rs index 24dffe6..97b6e78 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -63,7 +63,7 @@ fn default_action(context: &Context) { load_input_file(&input_file_path, precision, &mut parser_context); } - if context.args.len() == 0 { + if context.args.is_empty() { // REPL repl::start(&mut parser_context, precision); } else { diff --git a/cli/src/repl.rs b/cli/src/repl.rs index 719ff4d..8f52bca 100644 --- a/cli/src/repl.rs +++ b/cli/src/repl.rs @@ -20,7 +20,7 @@ use std::collections::HashMap; use std::fs; use std::process; -pub fn start(mut parser: &mut parser::Context, precision: u32) { +pub fn start(parser: &mut parser::Context, precision: u32) { let mut editor = Editor::::new(); editor.set_helper(Some(RLHelper { highlighter: LineHighlighter {}, @@ -31,9 +31,9 @@ pub fn start(mut parser: &mut parser::Context, precision: u32) { // Load history let mut history_path = None; if let Some(config_path) = dirs::config_dir() { - let mut config_path = config_path.clone(); + let mut config_path = config_path; config_path.push("kalker"); - if let Ok(_) = fs::create_dir_all(config_path.as_path()) { + if fs::create_dir_all(config_path.as_path()).is_ok() { config_path.push("history.txt"); let history = config_path.into_os_string().into_string().unwrap(); editor.load_history(&history).ok(); @@ -61,7 +61,7 @@ pub fn start(mut parser: &mut parser::Context, precision: u32) { match readline { Ok(input) => { editor.add_history_entry(input.as_str()); - eval_repl(&mut parser, &input, precision); + eval_repl(parser, &input, precision); } Err(ReadlineError::Interrupted) => break, _ => break, @@ -74,8 +74,7 @@ pub fn start(mut parser: &mut parser::Context, precision: u32) { } fn eval_repl(parser: &mut parser::Context, input: &str, precision: u32) { - if input.starts_with("load ") { - let file_name = &input[5..]; + if let Some(file_name) = input.strip_prefix("load ") { if let Some(file_path) = crate::get_input_file_by_name(file_name) { crate::load_input_file(&file_path, precision, parser); } else { @@ -216,7 +215,7 @@ impl Completer for RLHelper { fn update(&self, line: &mut rustyline::line_buffer::LineBuffer, start: usize, elected: &str) { line.backspace(line.pos() - start); line.insert_str(line.pos(), elected); - line.move_forward(if elected.ends_with(")") || elected.ends_with("⟧") { + line.move_forward(if elected.ends_with(')') || elected.ends_with('⟧') { elected.chars().count() - 1 } else { elected.chars().count() @@ -242,7 +241,7 @@ impl Highlighter for RLHelper { } fn highlight_char(&self, line: &str, _: usize) -> bool { - line.len() > 0 + !line.is_empty() } } diff --git a/kalk/src/analysis.rs b/kalk/src/analysis.rs index cb2b687..57d51be 100644 --- a/kalk/src/analysis.rs +++ b/kalk/src/analysis.rs @@ -83,18 +83,12 @@ fn analyse_stmt_expr(context: &mut Context, value: Expr) -> Result { - if inverter::contains_var( - &mut context.symbol_table, - &right, - &identifier.full_name, - ) { + if inverter::contains_var(context.symbol_table, &right, &identifier.full_name) { return Err(CalcError::VariableReferencesItself); } if prelude::is_constant(&identifier.full_name) { - return Err(CalcError::UnableToOverrideConstant( - identifier.pure_name.into(), - )); + return Err(CalcError::UnableToOverrideConstant(identifier.pure_name)); } let result = @@ -129,14 +123,10 @@ fn build_fn_decl( Expr::Vector(exprs) => { exprs .iter() - .any(|x| if let Expr::Var(_) = x { true } else { false }) + .any(|x| matches!(x, Expr::Var(_))) } Expr::Group(expr) => { - if let Expr::Var(_) = &**expr { - true - } else { - false - } + matches!(&**expr, Expr::Var(_)) } _ => false, }; @@ -266,8 +256,8 @@ fn analyse_expr(context: &mut Context, expr: Expr) -> Result { }) } -fn analyse_binary<'a>( - context: &'a mut Context, +fn analyse_binary( + context: &mut Context, left: Expr, op: TokenKind, right: Expr, @@ -286,7 +276,7 @@ fn analyse_binary<'a>( // If it has already been set to false manually somewhere else, // abort and analyse as a comparison instead. - if context.in_equation == false { + if !context.in_equation { context.in_conditional = true; let result = analyse_binary(context, left, op, right); context.in_conditional = previous_in_conditional; @@ -306,7 +296,7 @@ fn analyse_binary<'a>( return result; }; - let inverted = if inverter::contains_var(&mut context.symbol_table, &left, var_name) { + let inverted = if inverter::contains_var(context.symbol_table, &left, var_name) { left.invert_to_target(context.symbol_table, right, var_name)? } else { right.invert_to_target(context.symbol_table, left, var_name)? @@ -441,20 +431,20 @@ fn analyse_comparison_with_var( match op { TokenKind::GreaterThan => { ranged_var.min = Expr::Binary( - Box::new(right.clone()), + Box::new(right), TokenKind::Plus, Box::new(Expr::Literal(1f64)), ); } TokenKind::LessThan => { - ranged_var.max = right.clone(); + ranged_var.max = right; } TokenKind::GreaterOrEquals => { - ranged_var.min = right.clone(); + ranged_var.min = right; } TokenKind::LessOrEquals => { ranged_var.max = Expr::Binary( - Box::new(right.clone()), + Box::new(right), TokenKind::Plus, Box::new(Expr::Literal(1f64)), ); @@ -526,7 +516,7 @@ fn analyse_var( ) } else if context .symbol_table - .contains_var(&identifier.get_name_without_lowered()) + .contains_var(identifier.get_name_without_lowered()) { with_adjacent( build_indexed_var(context, identifier)?, @@ -653,21 +643,22 @@ fn build_fn_call( context.in_sum_prod = false; } - return Ok(Expr::FnCall(identifier, arguments)); + Ok(Expr::FnCall(identifier, arguments)) } fn build_indexed_var(context: &mut Context, identifier: Identifier) -> Result { let underscore_pos = identifier.pure_name.find('_').unwrap(); let var_name = &identifier.pure_name[0..underscore_pos]; let lowered = &identifier.pure_name[underscore_pos + 1..]; - let lowered_expr = if lowered.len() > 0 && lowered.chars().nth(0).unwrap_or('\0').is_digit(10) { + let lowered_expr = if !lowered.is_empty() && lowered.chars().next().unwrap_or('\0').is_digit(10) + { Expr::Literal(lowered.parse::().unwrap_or(f64::NAN)) } else { build_var(context, lowered) }; Ok(Expr::Indexer( - Box::new(build_var(context, &var_name)), + Box::new(build_var(context, var_name)), vec![lowered_expr], )) } @@ -677,10 +668,10 @@ fn build_dx( name_without_dx: &str, char_after_d: char, ) -> Result { - if name_without_dx.len() == 0 { + if name_without_dx.is_empty() { Ok(Expr::Var(Identifier::from_full_name(&format!( "d{}", - char_after_d.to_string() + char_after_d )))) } else { Ok(Expr::Binary( @@ -693,7 +684,7 @@ fn build_dx( TokenKind::Star, Box::new(Expr::Var(Identifier::from_full_name(&format!( "d{}", - char_after_d.to_string() + char_after_d )))), )) } @@ -754,7 +745,7 @@ fn build_var(context: &mut Context, name: &str) -> Expr { context.current_function_name.as_ref(), context.current_function_parameters.as_ref(), ) { - let identifier = Identifier::parameter_from_name(name, &function_name); + let identifier = Identifier::parameter_from_name(name, function_name); if params.contains(&identifier.full_name) { return Expr::Var(identifier); } diff --git a/kalk/src/ast.rs b/kalk/src/ast.rs index 2792ebe..926664a 100644 --- a/kalk/src/ast.rs +++ b/kalk/src/ast.rs @@ -116,7 +116,7 @@ fn separate_identifier_and_prime(identifier: &str) -> (String, u32) { let mut pure_identifier = identifier.to_string(); loop { - if pure_identifier.ends_with("'") { + if pure_identifier.ends_with('\'') { pure_identifier.pop(); prim_count += 1; } else { diff --git a/kalk/src/calculation_result.rs b/kalk/src/calculation_result.rs index 072f2de..e5d1ce9 100644 --- a/kalk/src/calculation_result.rs +++ b/kalk/src/calculation_result.rs @@ -22,8 +22,8 @@ impl CalculationResult { } #[wasm_bindgen(js_name = toString)] - pub fn to_string(&self) -> String { - self.value.to_string() + pub fn to_js_string(&self) -> String { + self.to_string() } #[wasm_bindgen(js_name = toStringBig)] @@ -71,3 +71,9 @@ impl CalculationResult { self.value.estimate() } } + +impl std::fmt::Display for CalculationResult { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.value) + } +} \ No newline at end of file diff --git a/kalk/src/calculus.rs b/kalk/src/calculus.rs index 26e6184..62f666b 100644 --- a/kalk/src/calculus.rs +++ b/kalk/src/calculus.rs @@ -42,7 +42,7 @@ pub fn integrate_with_unknown_variable( // integral(a, b, expr dx) if let Expr::Binary(_, TokenKind::Star, right) = expr { if let Expr::Var(right_name) = &**right { - if right_name.full_name.starts_with("d") { + if right_name.full_name.starts_with('d') { // Take the value, but remove the d, so that only eg. x is left from dx integration_variable = Some(&right_name.full_name[1..]); } @@ -89,7 +89,7 @@ fn simpsons_rule( const N: i32 = 900; let a = interpreter::eval_expr(context, a_expr, "")?; let b = interpreter::eval_expr(context, b_expr, "")?; - let h = (b.sub_without_unit(&a.clone())).div_without_unit(&KalkValue::from(N)); + let h = (b.sub_without_unit(&a)).div_without_unit(&KalkValue::from(N)); for i in 0..=N { let variable_value = a .clone() @@ -143,7 +143,7 @@ mod tests { use crate::symbol_table::SymbolTable; use crate::test_helpers::*; - fn get_context<'a>(symbol_table: &'a mut SymbolTable) -> interpreter::Context<'a> { + fn get_context(symbol_table: &mut SymbolTable) -> interpreter::Context { interpreter::Context::new( symbol_table, "", diff --git a/kalk/src/interpreter.rs b/kalk/src/interpreter.rs index 119a2f3..72b0ae4 100644 --- a/kalk/src/interpreter.rs +++ b/kalk/src/interpreter.rs @@ -35,7 +35,7 @@ impl<'a> Context<'a> { precision, sum_n_value: None, #[cfg(not(target_arch = "wasm32"))] - timeout: timeout, + timeout, #[cfg(not(target_arch = "wasm32"))] start_time: std::time::SystemTime::now(), } @@ -80,7 +80,7 @@ fn eval_stmt(context: &mut Context, stmt: &Stmt) -> Result Stmt::VarDecl(_, _) => eval_var_decl_stmt(context, stmt), Stmt::FnDecl(_, _, _) => eval_fn_decl_stmt(), Stmt::UnitDecl(_, _, _) => eval_unit_decl_stmt(), - Stmt::Expr(expr) => eval_expr_stmt(context, &expr), + Stmt::Expr(expr) => eval_expr_stmt(context, expr), } } @@ -98,7 +98,7 @@ fn eval_unit_decl_stmt() -> Result { } fn eval_expr_stmt(context: &mut Context, expr: &Expr) -> Result { - eval_expr(context, &expr, "") + eval_expr(context, expr, "") } pub(crate) fn eval_expr( @@ -114,12 +114,12 @@ pub(crate) fn eval_expr( } match expr { - Expr::Binary(left, op, right) => eval_binary_expr(context, &left, op, &right, unit), + Expr::Binary(left, op, right) => eval_binary_expr(context, left, op, right, unit), Expr::Unary(op, expr) => eval_unary_expr(context, op, expr, unit), Expr::Unit(identifier, expr) => eval_unit_expr(context, identifier, expr), Expr::Var(identifier) => eval_var_expr(context, identifier, unit), Expr::Literal(value) => eval_literal_expr(context, *value, unit), - Expr::Group(expr) => eval_group_expr(context, &expr, unit), + Expr::Group(expr) => eval_group_expr(context, expr, unit), Expr::FnCall(identifier, expressions) => { eval_fn_call_expr(context, identifier, expressions, unit) } @@ -177,7 +177,7 @@ fn eval_binary_expr( _ => KalkValue::from(1), }; - if unit.len() > 0 { + if !unit.is_empty() { if let KalkValue::Number(real, imaginary, _) = result { return Ok(KalkValue::Number(real, imaginary, unit.to_string())); } @@ -192,7 +192,7 @@ fn eval_unary_expr( expr: &Expr, unit: &str, ) -> Result { - let num = eval_expr(context, &expr, unit)?; + let num = eval_expr(context, expr, unit)?; match op { TokenKind::Minus => Ok(num.mul(context, KalkValue::from(-1f64))), @@ -318,7 +318,7 @@ pub(crate) fn eval_fn_call_expr( return Ok( prelude::call_vector_func(&identifier.full_name, KalkValue::Vector(values)) - .unwrap_or(KalkValue::nan()), + .unwrap_or_else(KalkValue::nan), ); } @@ -327,7 +327,7 @@ pub(crate) fn eval_fn_call_expr( 1 => { let x = eval_expr(context, &expressions[0], "")?; if identifier.prime_count > 0 { - return calculus::derive_func(context, &identifier, x); + return calculus::derive_func(context, identifier, x); } else { prelude::call_unary_func( context, @@ -496,7 +496,7 @@ pub(crate) fn eval_fn_call_expr( // Initialise the arguments as their own variables. let mut new_argument_values = Vec::new(); for (i, argument) in arguments.iter().enumerate() { - let argument_identifier = if argument.contains("-") { + let argument_identifier = if argument.contains('-') { let identifier_parts: Vec<&str> = argument.split('-').collect(); Identifier::parameter_from_name(identifier_parts[1], identifier_parts[0]) } else { @@ -533,10 +533,8 @@ pub(crate) fn eval_fn_call_expr( let fn_value = eval_expr(context, &fn_body, unit); // Revert to original argument values - for old_argument_value in old_argument_values { - if let Some(old_argument_value) = old_argument_value { - context.symbol_table.insert(old_argument_value); - } + for old_argument_value in old_argument_values.into_iter().flatten() { + context.symbol_table.insert(old_argument_value); } fn_value @@ -547,13 +545,13 @@ pub(crate) fn eval_fn_call_expr( fn eval_piecewise( context: &mut Context, - pieces: &Vec, + pieces: &[crate::ast::ConditionalPiece], unit: &str, ) -> Result { for piece in pieces { if let KalkValue::Boolean(condition_is_true) = eval_expr(context, &piece.condition, unit)? { if condition_is_true { - return Ok(eval_expr(context, &piece.expr, unit)?); + return eval_expr(context, &piece.expr, unit); } } } @@ -561,7 +559,7 @@ fn eval_piecewise( Err(CalcError::PiecewiseConditionsAreFalse) } -fn eval_vector(context: &mut Context, values: &Vec) -> Result { +fn eval_vector(context: &mut Context, values: &[Expr]) -> Result { let mut eval_values = Vec::new(); for value in values { eval_values.push(eval_expr(context, value, "")?); @@ -570,7 +568,7 @@ fn eval_vector(context: &mut Context, values: &Vec) -> Result>) -> Result { +fn eval_matrix(context: &mut Context, rows: &[Vec]) -> Result { let mut eval_rows = Vec::new(); for row in rows { let mut eval_row = Vec::new(); @@ -783,27 +781,27 @@ mod tests { assert_eq!(interpret(pow).unwrap().unwrap().to_f64(), 8f64); let result = interpret(equals).unwrap().unwrap(); - assert_eq!(bool(&result), false); + assert!(!bool(&result)); assert!(result.to_f64().is_nan()); let result = interpret(not_equals).unwrap().unwrap(); - assert_eq!(bool(&result), true); + assert!(bool(&result)); assert!(result.to_f64().is_nan()); let result = interpret(greater_than).unwrap().unwrap(); - assert_eq!(bool(&result), false); + assert!(!bool(&result)); assert!(result.to_f64().is_nan()); let result = interpret(less_than).unwrap().unwrap(); - assert_eq!(bool(&result), true); + assert!(bool(&result)); assert!(result.to_f64().is_nan()); let result = interpret(greater_or_equals).unwrap().unwrap(); - assert_eq!(bool(&result), false); + assert!(!bool(&result)); assert!(result.to_f64().is_nan()); let result = interpret(less_or_equals).unwrap().unwrap(); - assert_eq!(bool(&result), true); + assert!(bool(&result)); assert!(result.to_f64().is_nan()); } diff --git a/kalk/src/inverter.rs b/kalk/src/inverter.rs index 71507c6..6c2f24c 100644 --- a/kalk/src/inverter.rs +++ b/kalk/src/inverter.rs @@ -70,11 +70,11 @@ fn invert( ) -> Result<(Expr, Expr), CalcError> { match expr { Expr::Binary(left, op, right) => { - invert_binary(target_expr, symbol_table, &left, op, &right, unknown_var) + invert_binary(target_expr, symbol_table, left, op, right, unknown_var) } - Expr::Unary(op, expr) => invert_unary(target_expr, op, &expr), + Expr::Unary(op, expr) => invert_unary(target_expr, op, expr), Expr::Unit(identifier, expr) => { - invert_unit(target_expr, symbol_table, &identifier, &expr, unknown_var) + invert_unit(target_expr, symbol_table, identifier, expr, unknown_var) } Expr::Var(identifier) => invert_var(target_expr, symbol_table, identifier, unknown_var), Expr::Group(expr) => Ok((target_expr, *expr.clone())), @@ -153,7 +153,7 @@ fn invert_binary( return invert( target_expr, symbol_table, - &Expr::Binary(inside_group.clone(), op.clone(), Box::new(right.clone())), + &Expr::Binary(inside_group.clone(), *op, Box::new(right.clone())), unknown_var, ); } @@ -164,7 +164,7 @@ fn invert_binary( return invert( target_expr, symbol_table, - &Expr::Binary(Box::new(left.clone()), op.clone(), inside_group.clone()), + &Expr::Binary(Box::new(left.clone()), *op, inside_group.clone()), unknown_var, ); } @@ -208,17 +208,17 @@ fn invert_binary( ))); } - return Ok(invert( + return invert( Expr::Binary(Box::new(target_expr), op_inv, Box::new(right.clone())), symbol_table, left, unknown_var, - )?); + ); } // Otherwise, invert the left side. let final_target_expr = Expr::Binary(Box::new(target_expr), op_inv, Box::new(left.clone())); - Ok(invert( + invert( // Eg. 2-a // If the operator is minus (and the left expression is being inverted), // make the target expression negative to keep balance. @@ -230,7 +230,7 @@ fn invert_binary( symbol_table, right, // Then invert the right expression. unknown_var, - )?) + ) } fn invert_unary(target_expr: Expr, op: &TokenKind, expr: &Expr) -> Result<(Expr, Expr), CalcError> { @@ -240,7 +240,7 @@ fn invert_unary(target_expr: Expr, op: &TokenKind, expr: &Expr) -> Result<(Expr, Expr::Unary(TokenKind::Minus, Box::new(target_expr)), expr.clone(), // And then continue inverting the inner-expression. )), - _ => return Err(CalcError::UnableToInvert(String::new())), + _ => Err(CalcError::UnableToInvert(String::new())), } } @@ -280,7 +280,7 @@ fn invert_fn_call( target_expr: Expr, symbol_table: &mut SymbolTable, identifier: &Identifier, - arguments: &Vec, + arguments: &[Expr], unknown_var: &str, ) -> Result<(Expr, Expr), CalcError> { // If prelude function @@ -409,17 +409,17 @@ fn multiply_into(expr: &Expr, base_expr: &Expr) -> Result { Expr::Binary(left, op, right) => match op { // If + or -, multiply the expression with each term. TokenKind::Plus | TokenKind::Minus => Ok(Expr::Binary( - Box::new(multiply_into(expr, &left)?), - op.clone(), - Box::new(multiply_into(expr, &right)?), + Box::new(multiply_into(expr, left)?), + *op, + Box::new(multiply_into(expr, right)?), )), // If * or /, only multiply with the first factor. TokenKind::Star | TokenKind::Slash => Ok(Expr::Binary( - Box::new(multiply_into(expr, &left)?), - op.clone(), + Box::new(multiply_into(expr, left)?), + *op, right.clone(), )), - _ => return Err(CalcError::UnableToInvert(String::new())), + _ => Err(CalcError::UnableToInvert(String::new())), }, // If it's a literal, just multiply them together. Expr::Literal(_) | Expr::Var(_) => Ok(Expr::Binary( @@ -430,7 +430,7 @@ fn multiply_into(expr: &Expr, base_expr: &Expr) -> Result { Expr::Group(_) => Err(CalcError::UnableToInvert(String::from( "Parenthesis multiplied with parenthesis (this should be possible in the future).", ))), - _ => return Err(CalcError::UnableToInvert(String::new())), + _ => Err(CalcError::UnableToInvert(String::new())), } } diff --git a/kalk/src/kalk_value/mod.rs b/kalk/src/kalk_value/mod.rs index c9aace2..61c1a82 100644 --- a/kalk/src/kalk_value/mod.rs +++ b/kalk/src/kalk_value/mod.rs @@ -147,7 +147,13 @@ pub enum ComplexNumberType { #[wasm_bindgen] impl ScientificNotation { #[wasm_bindgen(js_name = toString)] - pub fn to_string(&self) -> String { + pub fn to_js_string(&self) -> String { + self.to_string() + } +} + +impl std::fmt::Display for ScientificNotation { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let sign = if self.negative { "-" } else { "" }; let digits_and_mul = if self.value == 1f64 { String::new() @@ -155,7 +161,8 @@ impl ScientificNotation { format!("{}×", format_number(self.value)) }; - format!( + write!( + f, "{}{}10^{} {}", sign, digits_and_mul, @@ -176,12 +183,8 @@ pub enum KalkValue { Matrix(Vec>), } -impl KalkValue { - pub fn nan() -> Self { - KalkValue::Number(float!(f64::NAN), float!(0f64), String::new()) - } - - pub fn to_string(&self) -> String { +impl std::fmt::Display for KalkValue { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { KalkValue::Number(real, imaginary, _) => { let as_str = format_number(primitive!(real)); @@ -191,23 +194,24 @@ impl KalkValue { let sign = if imaginary < &0f64 { "-" } else { "+" }; if &as_str == "0" { - imaginary_as_str + write!(f, "{}", imaginary_as_str) } else { - format!("{} {} {}i", as_str, sign, imaginary_as_str) + write!(f, "{} {} {}i", as_str, sign, imaginary_as_str) } } else { - as_str + write!(f, "{}", as_str) } } KalkValue::Boolean(is_true) => { if *is_true { - String::from("true") + write!(f, "true") } else { - String::from("false") + write!(f, "false") } } KalkValue::Vector(values) => { - format!( + write!( + f, "({})", values .iter() @@ -245,10 +249,16 @@ impl KalkValue { result.pop(); // Trailing comma result.push(']'); - result + write!(f, "{}", result) } } } +} + +impl KalkValue { + pub fn nan() -> Self { + KalkValue::Number(float!(f64::NAN), float!(0f64), String::new()) + } pub fn to_string_big(&self) -> String { if let KalkValue::Number(real, imaginary, _) = self { @@ -257,7 +267,7 @@ impl KalkValue { } let sign = if imaginary < &0f64 { "-" } else { "+" }; - format!("{} {} {}", real.to_string(), sign, imaginary.to_string()) + format!("{} {} {}", real, sign, imaginary) } else { self.to_string() } @@ -304,12 +314,10 @@ impl KalkValue { } else if sci_notation_real.exponent <= -14 { new_real = float!(0); String::from("0") + } else if radix == 10 { + sci_notation_real.to_string().trim().to_string() } else { - if radix == 10 { - sci_notation_real.to_string().trim().to_string() - } else { - return String::new(); - } + return String::new(); }; let sci_notation_imaginary = self.to_scientific_notation(ComplexNumberType::Imaginary); @@ -321,12 +329,10 @@ impl KalkValue { } else if sci_notation_imaginary.exponent <= -14 { new_imaginary = float!(0); String::from("0") + } else if radix == 10 { + sci_notation_imaginary.to_string().trim().to_string() } else { - if radix == 10 { - format!("{}", sci_notation_imaginary.to_string().trim()) - } else { - return String::new(); - } + return String::new(); }; let mut output = result_str; @@ -338,18 +344,18 @@ impl KalkValue { } // If there is a real value as well - if output.len() > 0 { + if !output.is_empty() { output.push_str(&format!( " {} {}", if imaginary < &0f64 { "-" } else { "+" }, - result_str_imaginary.trim_start_matches("-"), + result_str_imaginary.trim_start_matches('-'), )); } else { - output.push_str(&format!("{}", result_str_imaginary)); + output.push_str(&result_str_imaginary); } } - if unit != "" { + if !unit.is_empty() { output.push_str(&format!(" {}", unit)); } @@ -370,7 +376,7 @@ impl KalkValue { pub fn to_string_with_unit(&self) -> String { match self { - KalkValue::Number(_, _, unit) => format!("{} {}", self.to_string(), unit), + KalkValue::Number(_, _, unit) => format!("{} {}", self, unit), _ => self.to_string(), } } @@ -408,11 +414,11 @@ impl KalkValue { if value == "0" { // If both values ended up being estimated as zero, // return zero. - if output.len() == 0 { + if output.is_empty() { return Some(String::from("0")); } } else { - let sign = if value.starts_with("-") { "-" } else { "+" }; + let sign = if value.starts_with('-') { "-" } else { "+" }; let value = match value.as_ref() { "1" => String::from("i"), "-1" => String::from("-i"), @@ -420,8 +426,8 @@ impl KalkValue { }; // If there is a real value as well - if output.len() > 0 { - output.push_str(&format!(" {} {}", sign, value.trim_start_matches("-"))); + if !output.is_empty() { + output.push_str(&format!(" {} {}", sign, value.trim_start_matches('-'))); } else { output.push_str(&value); } @@ -500,7 +506,7 @@ impl KalkValue { ComplexNumberType::Real => self.to_f64(), ComplexNumberType::Imaginary => self.imaginary_to_f64(), }; - let exponent = value.clone().abs().log10().floor() as i32 + 1; + let exponent = value.abs().log10().floor() as i32 + 1; ScientificNotation { negative: value < 0f64, @@ -513,7 +519,7 @@ impl KalkValue { pub fn has_unit(&self) -> bool { if let KalkValue::Number(_, _, unit) = self { - unit.len() > 0 + !unit.is_empty() } else { false } @@ -536,7 +542,7 @@ impl KalkValue { let result = crate::interpreter::convert_unit( context, &Expr::Literal(primitive!(real)), - &unit, + unit, to_unit, ); @@ -582,7 +588,7 @@ impl KalkValue { context: &mut crate::interpreter::Context, rhs: KalkValue, ) -> KalkValue { - let right = calculate_unit(context, &self, rhs.clone()).unwrap_or(rhs.clone()); + let right = calculate_unit(context, &self, rhs.clone()).unwrap_or(rhs); self.div_without_unit(&right) } @@ -649,7 +655,7 @@ impl KalkValue { context: &mut crate::interpreter::Context, rhs: KalkValue, ) -> KalkValue { - let right = calculate_unit(context, &self, rhs.clone()).unwrap_or(rhs.clone()); + let right = calculate_unit(context, &self, rhs.clone()).unwrap_or(rhs); if let (KalkValue::Boolean(greater), KalkValue::Boolean(equal)) = ( self.greater_than_without_unit(&right), self.eq_without_unit(&right), @@ -665,7 +671,7 @@ impl KalkValue { context: &mut crate::interpreter::Context, rhs: KalkValue, ) -> KalkValue { - let right = calculate_unit(context, &self, rhs.clone()).unwrap_or(rhs.clone()); + let right = calculate_unit(context, &self, rhs.clone()).unwrap_or(rhs); if let (KalkValue::Boolean(less), KalkValue::Boolean(equal)) = ( self.less_than_without_unit(&right), self.eq_without_unit(&right), @@ -824,10 +830,7 @@ impl KalkValue { pub(crate) fn div_without_unit(self, rhs: &KalkValue) -> KalkValue { match (self.clone(), rhs.clone()) { - ( - KalkValue::Number(real, _, _), - KalkValue::Number(real_rhs, _, unit), - ) => { + (KalkValue::Number(real, _, _), KalkValue::Number(real_rhs, _, unit)) => { // Avoid unecessary calculations if !self.has_imaginary() && !rhs.has_imaginary() { KalkValue::Number(real / real_rhs, float!(0f64), unit) @@ -836,7 +839,7 @@ impl KalkValue { // with the conjugate of the denominator, and divide. let conjugate = rhs.get_conjugate(); let (numerator, numerator_imaginary) = - self.clone().mul_without_unit(&conjugate.clone()).values(); + self.mul_without_unit(&conjugate).values(); let (denominator, _) = rhs.clone().mul_without_unit(&conjugate).values(); KalkValue::Number( numerator / denominator.clone(), @@ -861,10 +864,12 @@ impl KalkValue { KalkValue::Number(real, imaginary, _), KalkValue::Number(real_rhs, imaginary_rhs, unit), ) => { - if self.has_imaginary() || imaginary_rhs != &0f64 || (real < 0f64 && real_rhs < &1f64) + if self.has_imaginary() + || imaginary_rhs != &0f64 + || (real < 0f64 && real_rhs < &1f64) { - let a = real.clone(); - let b = imaginary.clone(); + let a = real; + let b = imaginary; let c = real_rhs; let d = imaginary_rhs; let arg = crate::prelude::funcs::arg(self).values().0; @@ -935,7 +940,7 @@ impl KalkValue { let mut matrices_are_equal = true; for (row, row_rhs) in rows.iter().zip(rows_rhs) { for (value, value_rhs) in row.iter().zip(row_rhs) { - if let KalkValue::Boolean(are_equal) = value.eq_without_unit(&value_rhs) { + if let KalkValue::Boolean(are_equal) = value.eq_without_unit(value_rhs) { if !are_equal { matrices_are_equal = false; } @@ -949,7 +954,7 @@ impl KalkValue { (KalkValue::Vector(values), KalkValue::Vector(values_rhs)) => { let mut vecs_are_equal = true; for (value, value_rhs) in values.iter().zip(values_rhs) { - if let KalkValue::Boolean(are_equal) = value.eq_without_unit(&value_rhs) { + if let KalkValue::Boolean(are_equal) = value.eq_without_unit(value_rhs) { if !are_equal { vecs_are_equal = false; } @@ -1025,13 +1030,13 @@ impl KalkValue { pub fn format_number(input: f64) -> String { let rounded = format!("{:.1$}", input, 10); - if rounded.contains(".") { + if rounded.contains('.') { rounded .trim_end_matches('0') .trim_end_matches('.') .to_string() } else { - rounded.into() + rounded } } @@ -1053,7 +1058,7 @@ fn calculate_vector( values .iter() .zip(values_rhs) - .map(|(x, y)| action(x.clone(), &y)) + .map(|(x, y)| action(x.clone(), y)) .collect(), ) } else { @@ -1158,9 +1163,9 @@ fn pow(x: Float, y: Float) -> Float { x.pow(y) } -impl Into for ScientificNotation { - fn into(self) -> String { - self.to_string() +impl From for String { + fn from(val: ScientificNotation) -> Self { + val.to_string() } } @@ -1178,15 +1183,15 @@ impl std::iter::Sum for KalkValue { } } -impl Into for KalkValue { - fn into(self) -> String { - self.to_string() +impl From for String { + fn from(val: KalkValue) -> Self { + val.to_string() } } -impl Into for KalkValue { - fn into(self) -> f64 { - self.to_f64() +impl From for f64 { + fn from(val: KalkValue) -> Self { + val.to_f64() } } diff --git a/kalk/src/kalk_value/rounding.rs b/kalk/src/kalk_value/rounding.rs index 440c08a..5b31e48 100644 --- a/kalk/src/kalk_value/rounding.rs +++ b/kalk/src/kalk_value/rounding.rs @@ -31,19 +31,19 @@ pub(super) fn estimate( } // Eg. 0.5 to 1/2 - let as_abs_string = value_string.trim_start_matches("-").to_string(); + let as_abs_string = value_string.trim_start_matches('-').to_string(); let sign = if value < &0f64 { "-" } else { "" }; - if as_abs_string.starts_with("0.5") { - if as_abs_string.len() == 3 || (as_abs_string.len() > 6 && &as_abs_string[3..5] == "00") { - return Some(format!("{}1/2", sign)); - } + if as_abs_string.starts_with("0.5") + && (as_abs_string.len() == 3 || (as_abs_string.len() > 6 && &as_abs_string[3..5] == "00")) + { + return Some(format!("{}1/2", sign)); } // Eg. 1.33333333 to 1 + 1/3 if fract_as_string.len() >= 7 { let first_five_decimals = &fract_as_string[2..7]; if first_five_decimals == "33333" || first_five_decimals == "66666" { - let fraction = match first_five_decimals.as_ref() { + let fraction = match first_five_decimals { "33333" => "1/3", "66666" => "2/3", _ => "?", @@ -52,7 +52,7 @@ pub(super) fn estimate( if integer == 0f64 { return Some(format!("{}{}", sign, fraction)); } else { - let explicit_sign = if sign == "" { "+" } else { "-" }; + let explicit_sign = if sign.is_empty() { "+" } else { "-" }; return Some(format!( "{} {} {}", trim_zeroes(&integer.to_string()), @@ -66,7 +66,7 @@ pub(super) fn estimate( // Match with common numbers, eg. π, 2π/3, √2 if as_abs_string.len() >= 8 { if let Some(constant) = CONSTANTS.get(&as_abs_string[0..8]) { - return Some(format!("{}{}", sign, constant.to_string())); + return Some(format!("{}{}", sign, constant)); } } @@ -80,7 +80,7 @@ pub(super) fn estimate( .values() .0; if squared.clone().sqrt().fract() != 0f64 && squared.clone().fract() == 0f64 { - return Some(format!("√{}", squared.to_string())); + return Some(format!("√{}", squared)); } } @@ -135,7 +135,7 @@ pub(super) fn round( }; Some(new_num) - } else if (1f64 - fract.clone()).log10() < limit_ceil { + } else if (1f64 - fract).log10() < limit_ceil { // If eg. 0.999 // .abs() this before ceiling to make sure it rounds correctly. The sign is re-added afterwards. let new_value = value.clone().abs().ceil() * sign; @@ -155,10 +155,10 @@ pub(super) fn round( } pub(super) fn trim_zeroes(input: &str) -> String { - if input.contains(".") { + if input.contains('.') { input - .trim_end_matches("0") - .trim_end_matches(".") + .trim_end_matches('0') + .trim_end_matches('.') .to_string() } else { input.into() diff --git a/kalk/src/lexer.rs b/kalk/src/lexer.rs index 242211c..c58d27e 100644 --- a/kalk/src/lexer.rs +++ b/kalk/src/lexer.rs @@ -49,7 +49,7 @@ pub enum TokenKind { Semicolon, Newline, - EOF, + Eof, } #[derive(Clone, Debug, PartialEq)] @@ -80,7 +80,7 @@ impl<'a> Lexer<'a> { loop { let next = self.next(); - if let TokenKind::EOF = next.kind { + if let TokenKind::Eof = next.kind { tokens.push(next); break; } else { @@ -96,7 +96,7 @@ impl<'a> Lexer<'a> { } fn next(&mut self) -> Token { - let eof = build(TokenKind::EOF, "", (self.index, self.index)); + let eof = build(TokenKind::Eof, "", (self.index, self.index)); let mut c = if let Some(c) = self.peek() { *c } else { @@ -104,7 +104,7 @@ impl<'a> Lexer<'a> { }; while c == ' ' || c == '\t' || c == '\r' { - if let None = self.advance() { + if self.advance().is_none() { return eof; } @@ -210,13 +210,7 @@ impl<'a> Lexer<'a> { let mut leading_zero = self.peek().unwrap_or(&'\0') == &'0'; let mut base = 10u8; - loop { - let c = if let Some(c) = self.peek() { - *c - } else { - break; - }; - + while let Some(c) = self.peek() { // If at the second character and // the first character is a zero, // allow a letter @@ -239,15 +233,15 @@ impl<'a> Lexer<'a> { } } - if !c.is_digit(base as u32) && c != '.' && c != '_' && !c.is_whitespace() - || c == '\n' - || c == '\r' + if !c.is_digit(base as u32) && *c != '.' && *c != '_' && !c.is_whitespace() + || *c == '\n' + || *c == '\r' { break; } end += 1; - value.push(c); + value.push(*c); self.advance(); } @@ -258,7 +252,7 @@ impl<'a> Lexer<'a> { self.advance(); } - if base_str != "" { + if !base_str.is_empty() { base = crate::text_utils::subscript_to_normal(base_str.chars()) .parse::() .unwrap_or(10); @@ -295,7 +289,7 @@ impl<'a> Lexer<'a> { self.advance(); let num = self.next().value; value.push('_'); - value.push_str(&num.trim_end()); // Trim, since the number_literal function allows whitespace, which identifiers should not contain. + value.push_str(num.trim_end()); // Trim, since the number_literal function allows whitespace, which identifiers should not contain. break; } @@ -353,7 +347,7 @@ impl<'a> Lexer<'a> { _ => value, // things like log_2 are handled in the parser }; - if subscript.len() > 0 { + if !subscript.is_empty() { build( kind, &format!( @@ -433,7 +427,7 @@ mod tests { TokenKind::Equals, TokenKind::Exclamation, TokenKind::Comma, - TokenKind::EOF, + TokenKind::Eof, ]; match_tokens(tokens, expected); @@ -449,7 +443,7 @@ mod tests { TokenKind::LessThan, TokenKind::Literal, TokenKind::ClosedBracket, - TokenKind::EOF, + TokenKind::Eof, ]; match_tokens(tokens, expected); @@ -465,10 +459,10 @@ mod tests { let tokens = Lexer::new(input).lex(); if regex::Regex::new(r"^\s*$").unwrap().is_match(input) { - let expected = vec![TokenKind::EOF]; + let expected = vec![TokenKind::Eof]; match_tokens(tokens, expected); } else { - let expected = vec![TokenKind::Identifier, TokenKind::EOF]; + let expected = vec![TokenKind::Identifier, TokenKind::Eof]; match_tokens(tokens, expected); } } @@ -479,7 +473,7 @@ mod tests { #[test_case("56.4")] fn test_number_literal(input: &str) { let tokens = Lexer::new(input).lex(); - let expected = vec![TokenKind::Literal, TokenKind::EOF]; + let expected = vec![TokenKind::Literal, TokenKind::Eof]; assert_eq!(&tokens[0].value, input); match_tokens(tokens, expected); @@ -489,7 +483,7 @@ mod tests { #[test_case("xy")] fn test_identifier(input: &str) { let tokens = Lexer::new(input).lex(); - let expected = vec![TokenKind::Identifier, TokenKind::EOF]; + let expected = vec![TokenKind::Identifier, TokenKind::Eof]; assert_eq!(&tokens[0].value, input); match_tokens(tokens, expected); @@ -503,7 +497,7 @@ mod tests { TokenKind::OpenParenthesis, TokenKind::Identifier, TokenKind::ClosedParenthesis, - TokenKind::EOF, + TokenKind::Eof, ]; match_tokens(tokens, expected); diff --git a/kalk/src/lib.rs b/kalk/src/lib.rs index c1663d3..9872e45 100644 --- a/kalk/src/lib.rs +++ b/kalk/src/lib.rs @@ -1,3 +1,4 @@ +#![allow(clippy::unused_unit)] mod analysis; pub mod ast; pub mod calculation_result; diff --git a/kalk/src/parser.rs b/kalk/src/parser.rs index e944a02..fba8aa2 100644 --- a/kalk/src/parser.rs +++ b/kalk/src/parser.rs @@ -11,8 +11,8 @@ use crate::{ }; use wasm_bindgen::prelude::*; -pub const DECL_UNIT: &'static str = ".u"; -pub const DEFAULT_ANGLE_UNIT: &'static str = "rad"; +pub const DECL_UNIT: &str = ".u"; +pub const DEFAULT_ANGLE_UNIT: &str = "rad"; /// Struct containing the current state of the parser. It stores user-defined functions and variables. #[wasm_bindgen] @@ -118,10 +118,10 @@ pub enum CalcError { impl ToString for CalcError { fn to_string(&self) -> String { match self { - CalcError::CanOnlyIndexVectors => format!("Indexing (getting an item with a specific index) is only possible on vectors."), + CalcError::CanOnlyIndexVectors => String::from("Indexing (getting an item with a specific index) is only possible on vectors."), CalcError::Expected(description) => format!("Expected: {}", description), - CalcError::ExpectedDx => format!("Expected eg. dx, to specify for which variable the operation is being done to. Example with integration: ∫(0, 1, x dx) or ∫(0, 1, x, dx). You may need to put parenthesis around the expression before dx/dy/du/etc."), - CalcError::ExpectedIf => format!("Expected 'if', with a condition after it."), + CalcError::ExpectedDx => String::from("Expected eg. dx, to specify for which variable the operation is being done to. Example with integration: ∫(0, 1, x dx) or ∫(0, 1, x, dx). You may need to put parenthesis around the expression before dx/dy/du/etc."), + CalcError::ExpectedIf => String::from("Expected 'if', with a condition after it."), CalcError::IncorrectAmountOfArguments(expected, func, got) => format!( "Expected {} arguments for function {}, but got {}.", expected, func, got @@ -131,25 +131,25 @@ impl ToString for CalcError { expected, got ), CalcError::ItemOfIndexDoesNotExist(indexes) => format!("Item of index ⟦{}⟧ does not exist.", indexes.iter().map(|x| x.to_string()).collect::>().join(", ")), - CalcError::InconsistentColumnWidths => format!("Inconsistent column widths. Matrix columns must be the same size."), + CalcError::InconsistentColumnWidths => String::from("Inconsistent column widths. Matrix columns must be the same size."), CalcError::InvalidComprehension(x) => format!("Invalid comprehension: {}", x), CalcError::InvalidNumberLiteral(x) => format!("Invalid number literal: '{}'.", x), - CalcError::InvalidOperator => format!("Invalid operator."), - CalcError::InvalidUnit => format!("Invalid unit."), - CalcError::TimedOut => format!("Operation took too long."), - CalcError::VariableReferencesItself => format!("Variable references itself."), - CalcError::PiecewiseConditionsAreFalse => format!("All the conditions in the piecewise are false."), + CalcError::InvalidOperator => String::from("Invalid operator."), + CalcError::InvalidUnit => String::from("Invalid unit."), + CalcError::TimedOut => String::from("Operation took too long."), + CalcError::VariableReferencesItself => String::from("Variable references itself."), + CalcError::PiecewiseConditionsAreFalse => String::from("All the conditions in the piecewise are false."), CalcError::UnexpectedToken(got, expected) => { format!("Unexpected token: '{:?}', expected '{:?}'.", got, expected) } CalcError::UnableToInvert(msg) => format!("Unable to invert: {}", msg), CalcError::UndefinedFn(name) => format!("Undefined function: '{}'.", name), CalcError::UndefinedVar(name) => format!("Undefined variable: '{}'.", name), - CalcError::UnableToParseExpression => format!("Unable to parse expression."), - CalcError::UnableToSolveEquation => format!("Unable to solve equation."), + CalcError::UnableToParseExpression => String::from("Unable to parse expression."), + CalcError::UnableToSolveEquation => String::from("Unable to solve equation."), CalcError::UnableToOverrideConstant(name) => format!("Unable to override constant: '{}'.", name), - CalcError::UnrecognizedBase => format!("Unrecognized base."), - CalcError::Unknown => format!("Unknown error."), + CalcError::UnrecognizedBase => String::from("Unrecognized base."), + CalcError::Unknown => String::from("Unknown error."), } } } @@ -164,17 +164,13 @@ pub fn eval( ) -> Result, CalcError> { let statements = parse(context, input)?; - let mut symbol_table = context.symbol_table.get_mut(); + let symbol_table = context.symbol_table.get_mut(); let mut interpreter = interpreter::Context::new( - &mut symbol_table, + symbol_table, &context.angle_unit, #[cfg(feature = "rug")] precision, - if let Some(timeout) = context.timeout { - Some(timeout as u128) - } else { - None - }, + context.timeout.map(|timeout| timeout as u128), ); let result = interpreter.interpret(statements); if let Ok(Some(mut num)) = result { @@ -199,8 +195,8 @@ pub fn parse(context: &mut Context, input: &str) -> Result, CalcError> let mut statements: Vec = Vec::new(); while !is_at_end(context) { let parsed = parse_stmt(context)?; - let mut symbol_table = context.symbol_table.get_mut(); - let analysed = analysis::analyse_stmt(&mut symbol_table, parsed)?; + let symbol_table = context.symbol_table.get_mut(); + let analysed = analysis::analyse_stmt(symbol_table, parsed)?; statements.push(analysed); if match_token(context, TokenKind::Semicolon) { @@ -298,7 +294,7 @@ fn parse_unit_decl_stmt(context: &mut Context) -> Result { let stmt_inv = Stmt::UnitDecl( base_unit.clone(), identifier.value.clone(), - Box::new(def.invert(&mut context.symbol_table.get_mut(), DECL_UNIT)?), + Box::new(def.invert(context.symbol_table.get_mut(), DECL_UNIT)?), ); let stmt = Stmt::UnitDecl(identifier.value, base_unit, Box::new(def)); @@ -309,7 +305,7 @@ fn parse_unit_decl_stmt(context: &mut Context) -> Result { } fn parse_expr(context: &mut Context) -> Result { - Ok(parse_or(context)?) + parse_or(context) } fn parse_comprehension(context: &mut Context) -> Result { @@ -386,9 +382,7 @@ fn parse_comparison(context: &mut Context) -> Result { left = match right { Expr::Binary( inner_left, - inner_op - @ - (TokenKind::Equals + inner_op @ (TokenKind::Equals | TokenKind::NotEquals | TokenKind::GreaterThan | TokenKind::LessThan @@ -451,11 +445,11 @@ fn parse_factor(context: &mut Context) -> Result { if let Expr::Unary(TokenKind::Percent, percent_left) = left.clone() { let try_parse = parse_factor(context); - if !try_parse.is_err() { + if try_parse.is_ok() { left = Expr::Binary( percent_left, TokenKind::Percent, - Box::new(try_parse.unwrap()), + Box::new(try_parse?), ); } } @@ -633,7 +627,7 @@ fn parse_vector(context: &mut Context) -> Result { items_in_row += 1; } - if peek(context).kind == TokenKind::EOF { + if peek(context).kind == TokenKind::Eof { return Err(CalcError::Expected(String::from( "Closing group symbol, eg. )", ))); @@ -674,7 +668,7 @@ fn parse_identifier(context: &mut Context) -> Result { fn peek(context: &Context) -> &Token { if context.pos >= context.tokens.len() { - &context.tokens.last().unwrap() // EOF + context.tokens.last().unwrap() // Eof } else { &context.tokens[context.pos] } @@ -710,7 +704,7 @@ fn consume(context: &mut Context, kind: TokenKind) -> Result<&Token, CalcError> } fn is_at_end(context: &Context) -> bool { - context.pos >= context.tokens.len() || peek(context).kind == TokenKind::EOF + context.pos >= context.tokens.len() || peek(context).kind == TokenKind::Eof } fn skip_newlines(context: &mut Context) { @@ -756,8 +750,8 @@ mod tests { context.pos = 0; let parsed = parse_stmt(context)?; - let mut symbol_table = context.symbol_table.get_mut(); - analysis::analyse_stmt(&mut symbol_table, parsed) + let symbol_table = context.symbol_table.get_mut(); + analysis::analyse_stmt(symbol_table, parsed) } fn parse(tokens: Vec) -> Result { @@ -766,15 +760,15 @@ mod tests { context.pos = 0; let parsed = parse_stmt(&mut context)?; - let mut symbol_table = context.symbol_table.get_mut(); - analysis::analyse_stmt(&mut symbol_table, parsed) + let symbol_table = context.symbol_table.get_mut(); + analysis::analyse_stmt(symbol_table, parsed) } #[test] #[wasm_bindgen_test] fn test_var() { // x - let tokens = vec![token(Identifier, "x"), token(EOF, "")]; + let tokens = vec![token(Identifier, "x"), token(Eof, "")]; assert_eq!(parse(tokens).unwrap(), Stmt::Expr(var("x"))); } @@ -797,7 +791,7 @@ mod tests { token(Identifier, "xy"), token(Power, ""), token(Literal, "2"), - token(EOF, ""), + token(Eof, ""), ]; assert_eq!( @@ -826,7 +820,7 @@ mod tests { token(Slash, ""), token(Literal, "5"), token(ClosedParenthesis, ""), - token(EOF, ""), + token(Eof, ""), ]; assert_eq!( @@ -860,7 +854,7 @@ mod tests { token(Literal, "4"), token(Plus, ""), token(Literal, "5"), - token(EOF, ""), + token(Eof, ""), ]; assert_eq!( @@ -891,7 +885,7 @@ mod tests { token(Plus, ""), token(Literal, "5"), token(Percent, ""), - token(EOF, ""), + token(Eof, ""), ]; assert_eq!( @@ -930,7 +924,7 @@ mod tests { token(Literal, "1"), token(Plus, ""), token(Literal, "2"), - token(EOF, ""), + token(Eof, ""), ]; assert_eq!( @@ -954,7 +948,7 @@ mod tests { token(Literal, "1"), token(Plus, ""), token(Identifier, "x"), - token(EOF, ""), + token(Eof, ""), ]; assert_eq!( @@ -979,7 +973,7 @@ mod tests { token(ClosedParenthesis, ""), token(Plus, ""), token(Literal, "3"), - token(EOF, ""), + token(Eof, ""), ]; let mut context = Context::new(); diff --git a/kalk/src/prelude/mod.rs b/kalk/src/prelude/mod.rs index 35a0e73..dd1c450 100644 --- a/kalk/src/prelude/mod.rs +++ b/kalk/src/prelude/mod.rs @@ -22,27 +22,15 @@ use crate::interpreter; pub use funcs::*; // `i` is added in the symbol_table module, since for some reason it didn't work here. -pub const INIT: &'static str = "unit deg = (rad*180)/pi"; +pub const INIT: &str = "unit deg = (rad*180)/pi"; lazy_static! { pub static ref CONSTANTS: HashMap<&'static str, f64> = { let mut m = HashMap::new(); - m.insert( - "pi", - 3.1415926535897932384626433832795028841971693993751058209749445923, - ); - m.insert( - "e", - 2.7182818284590452353602874713526624977572470936999595749669676277, - ); - m.insert( - "tau", - 6.2831853071795864769252867665590057683943387987502116419498891846, - ); - m.insert( - "phi", - 1.6180339887498948482045868343656381177203091798057628621354486227, - ); + m.insert("pi", std::f64::consts::PI); + m.insert("e", std::f64::consts::E); + m.insert("tau", std::f64::consts::TAU); + m.insert("phi", 1.618_033_988_749_895); m }; pub static ref UNARY_FUNCS: HashMap<&'static str, (UnaryFuncInfo, &'static str)> = { @@ -205,7 +193,7 @@ pub fn call_unary_func( ) -> Option<(KalkValue, String)> { if let Some((func_info, func_unit)) = UNARY_FUNCS.get(name) { Some(( - func_info.call(context, x, &angle_unit), + func_info.call(context, x, angle_unit), func_unit.to_string(), )) } else { @@ -231,11 +219,7 @@ pub fn call_binary_func( } pub fn call_vector_func(name: &str, x: KalkValue) -> Option { - if let Some(func_info) = VECTOR_FUNCS.get(name) { - Some(func_info.call(x)) - } else { - None - } + VECTOR_FUNCS.get(name).map(|func_info| func_info.call(x)) } fn to_angle_unit(context: &mut interpreter::Context, x: KalkValue, angle_unit: &str) -> KalkValue { @@ -286,7 +270,7 @@ pub mod funcs { // -i * ln(i * sqrt(1 - z²) + z) let root = sqrt(KalkValue::from(1f64).sub_without_unit(&x.clone().mul_without_unit(&x))); - let iroot = multiply_with_i(root.clone()); + let iroot = multiply_with_i(root); let (ln_real, ln_imaginary, ln_unit) = as_number_or_return!(ln(iroot.add_without_unit(&x))); @@ -305,11 +289,7 @@ pub mod funcs { imaginary.clone(), unit.clone(), )); - let sqrt2 = sqrt(KalkValue::Number( - real.clone() - 1f64, - imaginary.clone(), - unit, - )); + let sqrt2 = sqrt(KalkValue::Number(real - 1f64, imaginary, unit)); ln(x.add_without_unit(&sqrt1.mul_without_unit(&sqrt2))) } else { @@ -399,11 +379,7 @@ pub mod funcs { inv_unit.clone(), )); // sqrt(1/z + 1) - let sqrt2 = sqrt(KalkValue::Number( - inv_real.clone() + 1f64, - inv_imaginary.clone(), - inv_unit, - )); + let sqrt2 = sqrt(KalkValue::Number(inv_real + 1f64, inv_imaginary, inv_unit)); // ln(1/z + sqrt(1/z - 1) * sqrt(1/z + 1)) ln(sqrt1.mul_without_unit(&sqrt2).add_without_unit(&inv)) @@ -418,7 +394,7 @@ pub mod funcs { // i * ln(sqrt(1 - z²) - iz) let root = sqrt(KalkValue::from(1f64).sub_without_unit(&x.clone().mul_without_unit(&x))); - let iz = multiply_with_i(x.clone()); + let iz = multiply_with_i(x); let ln = ln(root.sub_without_unit(&iz)); multiply_with_i(ln) } else { @@ -600,10 +576,10 @@ pub mod funcs { } if x.has_imaginary() || y.has_imaginary() { - if real.clone().fract() != 0f64 - || real_rhs.clone().fract() != 0f64 - || imaginary.clone().fract() != 0f64 - || imaginary_rhs.clone().fract() != 0f64 + if real.fract() != 0f64 + || real_rhs.fract() != 0f64 + || imaginary.fract() != 0f64 + || imaginary_rhs.fract() != 0f64 { // Not a Gaussian integer! // TODO: throw an actual error instead of returning NaN @@ -627,7 +603,7 @@ pub mod funcs { let (b_real, b_imaginary, b_unit) = as_number_or_return!(b.clone()); let (c_real, c_imaginary, c_unit) = - as_number_or_return!(a.clone().div_without_unit(&b.clone())); + as_number_or_return!(a.clone().div_without_unit(&b)); if c_imaginary.clone().fract() == 0f64 { KalkValue::Number(b_real.abs(), b_imaginary, b_unit) } else { @@ -646,8 +622,8 @@ pub mod funcs { } // Euclidean GCD algorithm, but with modulus - let mut x_a = real.clone(); - let mut y_a = real_rhs.clone(); + let mut x_a = real; + let mut y_a = real_rhs; while !y_a.eq(&0f64) { let t = y_a.clone(); y_a = x_a % y_a; @@ -686,10 +662,10 @@ pub mod funcs { pub fn lcm(x: KalkValue, y: KalkValue) -> KalkValue { let (real, imaginary, unit) = as_number_or_return!(x.clone()); let (real_rhs, imaginary_rhs, unit_rhs) = as_number_or_return!(y.clone()); - let gcd = gcd(x.clone(), y.clone()); + let gcd = gcd(x, y); let absx = KalkValue::Number(real.abs(), imaginary, unit); let absy = KalkValue::Number(real_rhs.abs(), imaginary_rhs, unit_rhs); - return absx.div_without_unit(&gcd).mul_without_unit(&absy); + absx.div_without_unit(&gcd).mul_without_unit(&absy) } pub fn log(x: KalkValue) -> KalkValue { @@ -728,7 +704,7 @@ pub mod funcs { let values = as_vector_or_return!(x); let mut max = &values[0]; for value in &values { - if let KalkValue::Boolean(greater) = value.greater_than_without_unit(&max) { + if let KalkValue::Boolean(greater) = value.greater_than_without_unit(max) { if greater { max = value; } @@ -742,7 +718,7 @@ pub mod funcs { let values = as_vector_or_return!(x); let mut min = &values[0]; for value in &values { - if let KalkValue::Boolean(less) = value.less_than_without_unit(&min) { + if let KalkValue::Boolean(less) = value.less_than_without_unit(min) { if less { min = value; } @@ -795,7 +771,7 @@ pub mod funcs { pub fn sqrt(x: KalkValue) -> KalkValue { let (real, imaginary, unit) = as_number_or_return!(x.clone()); if x.has_imaginary() { - let (abs_real, _, abs_unit) = as_number_or_return!(abs(x.clone())); + let (abs_real, _, abs_unit) = as_number_or_return!(abs(x)); let r = abs_real; let a = real; let b = imaginary; @@ -949,6 +925,7 @@ mod tests { } #[test] + #[allow(clippy::approx_constant)] fn test_trig_funcs() { // Auto-generated using kalk/scripts/generate_funcs_test_cases.py let in_out = vec![ @@ -1192,7 +1169,6 @@ mod tests { || actual_output.imaginary_to_f64().is_infinite(); if expected_has_nan_or_inf || actual_has_nan_or_inf { - assert!(true); continue; } diff --git a/kalk/src/radix.rs b/kalk/src/radix.rs index 1e3aa8c..463f015 100644 --- a/kalk/src/radix.rs +++ b/kalk/src/radix.rs @@ -24,10 +24,10 @@ pub fn parse_float_radix(value: &str, radix: u8) -> Option { i -= 1; } - return Some(sum); + Some(sum) } -const DIGITS: &'static str = "0123456789abcdefghijklmnopqrstuvwxyz"; +const DIGITS: &str = "0123456789abcdefghijklmnopqrstuvwxyz"; pub fn int_to_radix(value: i64, radix: u8) -> String { let mut num = value.abs(); let mut result_str = String::new(); @@ -37,7 +37,7 @@ pub fn int_to_radix(value: i64, radix: u8) -> String { num /= radix as i64; } - if result_str == "" { + if result_str.is_empty() { return String::from("0"); } @@ -52,7 +52,7 @@ pub fn float_to_radix(value: f64, radix: u8) -> String { result.push('.'); let precision = 10; let fract_digits = (fract * (radix as i64).pow(precision) as f64) as i64; - result.push_str(&int_to_radix(fract_digits, radix).trim_end_matches('0')) + result.push_str(int_to_radix(fract_digits, radix).trim_end_matches('0')) } result diff --git a/kalk/src/symbol_table.rs b/kalk/src/symbol_table.rs index 207cc1a..4fc6413 100644 --- a/kalk/src/symbol_table.rs +++ b/kalk/src/symbol_table.rs @@ -100,3 +100,9 @@ impl SymbolTable { || self.hashmap.contains_key(&format!("fn.{}", identifier)) } } + +impl Default for SymbolTable { + fn default() -> Self { + Self::new() + } +} diff --git a/kalk/src/text_utils.rs b/kalk/src/text_utils.rs index f91b8f1..924b9ef 100644 --- a/kalk/src/text_utils.rs +++ b/kalk/src/text_utils.rs @@ -1,18 +1,10 @@ pub fn is_superscript(c: &char) -> bool { - match c { - '⁰' | '¹' | '²' | '³' | '⁴' | '⁵' | '⁶' | '⁷' | '⁸' | '⁹' | '⁺' | '⁻' | '⁼' | '⁽' | '⁾' => { - true - } - _ => false, - } + matches!(c, '⁰' | '¹' | '²' | '³' | '⁴' | '⁵' | '⁶' | '⁷' | '⁸' | '⁹' | '⁺' | '⁻' | '⁼' | '⁽' | '⁾') } pub fn is_subscript(c: &char) -> bool { - match c { - '₀' | '₁' | '₂' | '₃' | '₄' | '₅' | '₆' | '₇' | '₈' | '₉' | '₊' | '₋' | '₌' | '₍' | '₎' - | 'ₖ' | 'ₗ' | 'ₘ' | 'ₙ' | 'ₓ' => true, - _ => false, - } + matches!(c, '₀' | '₁' | '₂' | '₃' | '₄' | '₅' | '₆' | '₇' | '₈' | '₉' | '₊' | '₋' | '₌' | '₍' | '₎' + | 'ₖ' | 'ₗ' | 'ₘ' | 'ₙ' | 'ₓ') } pub fn parse_subscript(chars: impl Iterator) -> Option { @@ -82,5 +74,5 @@ pub fn normal_to_subscript(chars: impl Iterator) -> String { }); } - return subscript; + subscript }