From ab6e75872664015a86ba8b3fa8a59349559dbf4d Mon Sep 17 00:00:00 2001 From: bakk Date: Sun, 23 May 2021 01:56:25 +0200 Subject: [PATCH] Allow a comma before 'dx' in integrals --- kalk/src/calculus.rs | 14 ++++++++++++-- kalk/src/interpreter.rs | 31 ++++++++++++++++++++++++------- kalk/src/parser.rs | 4 ++-- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/kalk/src/calculus.rs b/kalk/src/calculus.rs index a37a406..818180a 100644 --- a/kalk/src/calculus.rs +++ b/kalk/src/calculus.rs @@ -28,7 +28,7 @@ pub fn derive_func( .round_if_needed()) } -pub fn integrate( +pub fn integrate_with_unknown_variable( context: &mut interpreter::Context, a: &Expr, b: &Expr, @@ -56,7 +56,17 @@ pub fn integrate( Box::new(Expr::Literal(1f64)), )); - Ok(simpsons_rule(context, a, b, expr, integration_variable.unwrap())?.round_if_needed()) + Ok(integrate(context, a, b, expr, integration_variable.unwrap())?.round_if_needed()) +} + +pub fn integrate( + context: &mut interpreter::Context, + a: &Expr, + b: &Expr, + expr: &Expr, + integration_variable: &str, +) -> Result { + Ok(simpsons_rule(context, a, b, expr, integration_variable)?.round_if_needed()) } /// Composite Simpson's 3/8 rule diff --git a/kalk/src/interpreter.rs b/kalk/src/interpreter.rs index 073e78a..4d308b5 100644 --- a/kalk/src/interpreter.rs +++ b/kalk/src/interpreter.rs @@ -365,16 +365,33 @@ pub(crate) fn eval_fn_call_expr( return Ok(sum); } "integrate" | "integral" | "∫" => { - // Make sure exactly 3 arguments were supplied. - if expressions.len() != 3 { - return Err(CalcError::IncorrectAmountOfArguments( + // Make sure either 3 or 4 arguments were supplied. + if expressions.len() < 3 || expressions.len() > 4 {} + + return match expressions.len() { + 3 => calculus::integrate_with_unknown_variable( + context, + &expressions[0], + &expressions[1], + &expressions[2], + ), + 4 => calculus::integrate( + context, + &expressions[0], + &expressions[1], + &expressions[2], + if let Expr::Var(integration_variable) = &expressions[3] { + &integration_variable.full_name[1..] + } else { + return Err(CalcError::ExpectedDx); + }, + ), + _ => Err(CalcError::IncorrectAmountOfArguments( 3, "integrate".into(), expressions.len(), - )); - } - - return calculus::integrate(context, &expressions[0], &expressions[1], &expressions[2]); + )), + }; } _ => (), } diff --git a/kalk/src/parser.rs b/kalk/src/parser.rs index f34e55e..ad320b5 100644 --- a/kalk/src/parser.rs +++ b/kalk/src/parser.rs @@ -111,8 +111,8 @@ pub enum CalcError { impl ToString for CalcError { fn to_string(&self) -> String { - match self { - CalcError::ExpectedDx => format!("Expected eg. dx, to specify for which variable the operation is being done to. Example with integration: ∫(0, 1, x dx). You may need to put parenthesis around the expression before dx/dy/du/etc."), + match self + 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::IncorrectAmountOfArguments(expected, func, got) => format!( "Expected {} arguments for function {}, but got {}.", expected, func, got