diff --git a/src/exact_math/symbolic.rs b/src/exact_math/symbolic.rs index 5296d68..76b4f99 100644 --- a/src/exact_math/symbolic.rs +++ b/src/exact_math/symbolic.rs @@ -30,6 +30,7 @@ pub fn size(p: &Parameters) -> i32 { Var(x, _, _) => 1 + size(x), Mul(x, y) => 1 + size(x) + size(y), Div(x, y) => 1 + size(x) + size(y), + Call(_, y) => 1 + size(y), } } diff --git a/src/functions/add.rs b/src/functions/add.rs index fedaaa9..13bcae6 100644 --- a/src/functions/add.rs +++ b/src/functions/add.rs @@ -533,6 +533,84 @@ pub fn add(i: Parameters, i2: Parameters, ram: Option<&HashMap Div(s1.clone(), s2.clone()), (Div(s1, s2), Null) => Div(s1.clone(), s2.clone()), + + (Call(x, y), Call(a, b)) => Plus( + Box::from(Call(x.clone(), y.clone())), + Box::from(Call(a.clone(), b.clone())), + ), + + (Call(x, y), Null) => Call(x.clone(), y.clone()), + + (Null, Call(x, y)) => Call(x.clone(), y.clone()), + + (Call(x, y), Int(i)) => Plus(Box::from(Call(x.clone(), y.clone())), Box::from(Int(i))), + + (Call(x, y), Float(i)) => Plus(Box::from(Call(x.clone(), y.clone())), Box::from(Float(i))), + + (Call(x, y), Rational(i)) => Plus( + Box::from(Call(x.clone(), y.clone())), + Box::from(Rational(i)), + ), + + (Int(i), Call(x, y)) => Plus(Box::from(Call(x.clone(), y.clone())), Box::from(Int(i))), + + (Float(i), Call(x, y)) => Plus(Box::from(Call(x.clone(), y.clone())), Box::from(Float(i))), + + (Rational(i), Call(x, y)) => Plus( + Box::from(Call(x.clone(), y.clone())), + Box::from(Rational(i)), + ), + + (Call(x, y), Identifier(a)) => Plus( + Box::from(Call(x.clone(), y.clone())), + Box::from(Var(Box::from(Int(1)), 1, a.clone())), + ), + + (Identifier(a), Call(x, y)) => Plus( + Box::from(Var(Box::from(Int(1)), 1, a.clone())), + Box::from(Call(x.clone(), y.clone())), + ), + + (Call(x, y), Var(a, b, c)) => Plus( + Box::from(Call(x.clone(), y.clone())), + Box::from(Var(a.clone(), b, c.clone())), + ), + + (Var(a, b, c), Call(x, y)) => Plus( + Box::from(Var(a.clone(), b, c.clone())), + Box::from(Call(x.clone(), y.clone())), + ), + + (Call(x, y), Plus(a, b)) => Plus( + Box::from(Plus(a.clone(), b.clone())), + Box::from(Call(x.clone(), y.clone())), + ), + + (Plus(a, b), Call(x, y)) => Plus( + Box::from(Call(x.clone(), y.clone())), + Box::from(Plus(a.clone(), b.clone())), + ), + + (Call(x, y), Mul(a, b)) => Plus( + Box::from(Call(x.clone(), y.clone())), + Box::from(Mul(a.clone(), b.clone())), + ), + + (Mul(a, b), Call(x, y)) => Plus( + Box::from(Mul(a.clone(), b.clone())), + Box::from(Call(x.clone(), y.clone())), + ), + + (Call(x, y), Div(a, b)) => Plus( + Box::from(Call(x.clone(), y.clone())), + Box::from(Div(a.clone(), b.clone())), + ), + + (Div(a, b), Call(x, y)) => Plus( + Box::from(Div(a.clone(), b.clone())), + Box::from(Call(x.clone(), y.clone())), + ), + _ => Identifier("@Those two values are incompatible with the + operator".to_string()), } } diff --git a/src/functions/divide.rs b/src/functions/divide.rs index 742e742..cf95daa 100644 --- a/src/functions/divide.rs +++ b/src/functions/divide.rs @@ -631,6 +631,84 @@ pub fn divide( (Null, Div(s1, s2)) => divide(*s2.clone(), *s1.clone(), ram), (Div(s1, s2), Null) => divide(*s2.clone(), *s1.clone(), ram), + + (Call(x, y), Call(a, b)) => Div( + Box::from(Call(x.clone(), y.clone())), + Box::from(Call(a.clone(), b.clone())), + ), + + (Call(x, y), Null) => Call(x.clone(), y.clone()), + + (Null, Call(x, y)) => Call(x.clone(), y.clone()), + + (Call(x, y), Int(i)) => Div(Box::from(Call(x.clone(), y.clone())), Box::from(Int(i))), + + (Call(x, y), Float(i)) => Div(Box::from(Call(x.clone(), y.clone())), Box::from(Float(i))), + + (Call(x, y), Rational(i)) => Div( + Box::from(Call(x.clone(), y.clone())), + Box::from(Rational(i)), + ), + + (Int(i), Call(x, y)) => Div(Box::from(Int(i)), Box::from(Call(x.clone(), y.clone()))), + + (Float(i), Call(x, y)) => Div(Box::from(Float(i)), Box::from(Call(x.clone(), y.clone()))), + + (Rational(i), Call(x, y)) => Div( + Box::from(Rational(i)), + Box::from(Call(x.clone(), y.clone())), + ), + + (Call(x, y), Identifier(a)) => Div( + Box::from(Call(x.clone(), y.clone())), + Box::from(Var(Box::from(Int(1)), 1, a.clone())), + ), + + (Identifier(a), Call(x, y)) => Div( + Box::from(Var(Box::from(Int(1)), 1, a.clone())), + Box::from(Call(x.clone(), y.clone())), + ), + + (Call(x, y), Var(a, b, c)) => Div( + Box::from(Call(x.clone(), y.clone())), + Box::from(Var(a.clone(), b, c.clone())), + ), + + (Var(a, b, c), Call(x, y)) => Div( + Box::from(Var(a.clone(), b, c.clone())), + Box::from(Call(x.clone(), y.clone())), + ), + + (Call(x, y), Plus(a, b)) => Div( + Box::from(Call(x.clone(), y.clone())), + Box::from(Plus(a.clone(), b.clone())), + ), + + (Plus(a, b), Call(x, y)) => Div( + Box::from(Plus(a.clone(), b.clone())), + Box::from(Call(x.clone(), y.clone())), + ), + + (Call(x, y), Mul(a, b)) => Div( + Box::from(Call(x.clone(), y.clone())), + Box::from(Mul(a.clone(), b.clone())), + ), + + (Mul(a, b), Call(x, y)) => Div( + Box::from(Mul(a.clone(), b.clone())), + Box::from(Call(x.clone(), y.clone())), + ), + + (Call(x, y), Div(a, b)) => Div( + Box::from(Call(x.clone(), y.clone())), + Box::from(Div(a.clone(), b.clone())), + ), + + (Div(a, b), Call(x, y)) => Div( + Box::from(Div(a.clone(), b.clone())), + Box::from(Call(x.clone(), y.clone())), + ), + _ => Identifier("@Those two values are incompatible with the / operator".to_string()), } } diff --git a/src/functions/minus.rs b/src/functions/minus.rs index e8fd64a..9e94563 100644 --- a/src/functions/minus.rs +++ b/src/functions/minus.rs @@ -1,3 +1,5 @@ +use gnuplot::palettes::PLASMA; + use crate::exact_math::rationals::Rationals; use crate::exact_math::symbolic::size; use crate::functions::function::apply_operator; @@ -639,6 +641,125 @@ pub fn minus( ram, ), + (Call(x, y), Call(a, b)) => Plus( + Box::from(Call(x.clone(), y.clone())), + Box::from(Mul( + Box::from(Int(-1)), + Box::from(Call(a.clone(), b.clone())), + )), + ), + + (Call(x, y), Null) => Mul(Box::from(Int(-1)), Box::from(Call(x.clone(), y.clone()))), + + (Null, Call(x, y)) => Mul(Box::from(Int(-1)), Box::from(Call(x.clone(), y.clone()))), + + (Call(x, y), Int(i)) => Plus(Box::from(Call(x.clone(), y.clone())), Box::from(Int(-i))), + + (Call(x, y), Float(i)) => Plus(Box::from(Call(x.clone(), y.clone())), Box::from(Float(-i))), + + (Call(x, y), Rational(i)) => Plus( + Box::from(Call(x.clone(), y.clone())), + Box::from(Rational(i.opposite())), + ), + + (Int(i), Call(x, y)) => Plus( + Box::from(Int(i)), + Box::from(Mul( + Box::from(Int(-1)), + Box::from(Call(x.clone(), y.clone())), + )), + ), + + (Float(i), Call(x, y)) => Plus( + Box::from(Float(i)), + Box::from(Mul( + Box::from(Int(-1)), + Box::from(Call(x.clone(), y.clone())), + )), + ), + + (Rational(i), Call(x, y)) => Plus( + Box::from(Rational(i)), + Box::from(Mul( + Box::from(Int(-1)), + Box::from(Call(x.clone(), y.clone())), + )), + ), + + (Call(x, y), Identifier(a)) => Plus( + Box::from(Call(x.clone(), y.clone())), + Box::from(Var(Box::from(Int(-1)), 1, a.clone())), + ), + + (Identifier(a), Call(x, y)) => Plus( + Box::from(Var(Box::from(Int(1)), 1, a.clone())), + Box::from(Mul( + Box::from(Int(-1)), + Box::from(Call(x.clone(), y.clone())), + )), + ), + + (Call(x, y), Var(a, b, c)) => Plus( + Box::from(Call(x.clone(), y.clone())), + Box::from(Var( + Box::from(mult(*a.clone(), Int(-1), ram).clone()), + b, + c.clone(), + )), + ), + + (Var(a, b, c), Call(x, y)) => Plus( + Box::from(Var(a.clone(), b, c.clone())), + Box::from(Mul( + Box::from(Int(-1)), + Box::from(Call(x.clone(), y.clone())), + )), + ), + + (Call(x, y), Plus(a, b)) => Plus( + Box::from(Call(x.clone(), y.clone())), + Box::from(Mul( + Box::from(Int(-1)), + Box::from(Plus(a.clone(), b.clone())), + )), + ), + + (Plus(a, b), Call(x, y)) => Plus( + Box::from(Plus(a.clone(), b.clone())), + Box::from(Mul( + Box::from(Int(-1)), + Box::from(Call(x.clone(), y.clone())), + )), + ), + + (Call(x, y), Mul(a, b)) => Plus( + Box::from(Call(x.clone(), y.clone())), + Box::from(Mul( + Box::from(Mul(Box::from(Int(-1)), a.clone())), + b.clone(), + )), + ), + + (Mul(a, b), Call(x, y)) => Plus( + Box::from(Mul(a.clone(), b.clone())), + Box::from(Box::from(Mul( + Box::from(Int(-1)), + Box::from(Call(x.clone(), y.clone())), + ))), + ), + + (Call(x, y), Div(a, b)) => Plus( + Box::from(Call(x.clone(), y.clone())), + Box::from(Div(Box::from(mult(*a.clone(), Int(-1), ram)), b.clone())), + ), + + (Div(a, b), Call(x, y)) => Plus( + Box::from(Div(a.clone(), b.clone())), + Box::from(Box::from(Mul( + Box::from(Int(-1)), + Box::from(Call(x.clone(), y.clone())), + ))), + ), _ => Identifier("Those two values are incompatible with the - operator".to_string()), } } diff --git a/src/functions/mult.rs b/src/functions/mult.rs index 9d61189..b758828 100644 --- a/src/functions/mult.rs +++ b/src/functions/mult.rs @@ -565,6 +565,83 @@ pub fn mult( (Div(s1, s2), Null) => Div(s1.clone(), s2.clone()), + (Call(x, y), Call(a, b)) => Mul( + Box::from(Call(x.clone(), y.clone())), + Box::from(Call(a.clone(), b.clone())), + ), + + (Call(x, y), Null) => Call(x.clone(), y.clone()), + + (Null, Call(x, y)) => Call(x.clone(), y.clone()), + + (Call(x, y), Int(i)) => Mul(Box::from(Call(x.clone(), y.clone())), Box::from(Int(i))), + + (Call(x, y), Float(i)) => Mul(Box::from(Call(x.clone(), y.clone())), Box::from(Float(i))), + + (Call(x, y), Rational(i)) => Mul( + Box::from(Call(x.clone(), y.clone())), + Box::from(Rational(i)), + ), + + (Int(i), Call(x, y)) => Mul(Box::from(Call(x.clone(), y.clone())), Box::from(Int(i))), + + (Float(i), Call(x, y)) => Mul(Box::from(Call(x.clone(), y.clone())), Box::from(Float(i))), + + (Rational(i), Call(x, y)) => Mul( + Box::from(Call(x.clone(), y.clone())), + Box::from(Rational(i)), + ), + + (Call(x, y), Identifier(a)) => Mul( + Box::from(Call(x.clone(), y.clone())), + Box::from(Var(Box::from(Int(1)), 1, a.clone())), + ), + + (Identifier(a), Call(x, y)) => Mul( + Box::from(Var(Box::from(Int(1)), 1, a.clone())), + Box::from(Call(x.clone(), y.clone())), + ), + + (Call(x, y), Var(a, b, c)) => Mul( + Box::from(Call(x.clone(), y.clone())), + Box::from(Var(a.clone(), b, c.clone())), + ), + + (Var(a, b, c), Call(x, y)) => Mul( + Box::from(Var(a.clone(), b, c.clone())), + Box::from(Call(x.clone(), y.clone())), + ), + + (Call(x, y), Plus(a, b)) => Mul( + Box::from(Plus(a.clone(), b.clone())), + Box::from(Call(x.clone(), y.clone())), + ), + + (Plus(a, b), Call(x, y)) => Mul( + Box::from(Call(x.clone(), y.clone())), + Box::from(Plus(a.clone(), b.clone())), + ), + + (Call(x, y), Mul(a, b)) => Mul( + Box::from(Call(x.clone(), y.clone())), + Box::from(Mul(a.clone(), b.clone())), + ), + + (Mul(a, b), Call(x, y)) => Mul( + Box::from(Mul(a.clone(), b.clone())), + Box::from(Call(x.clone(), y.clone())), + ), + + (Call(x, y), Div(a, b)) => Mul( + Box::from(Call(x.clone(), y.clone())), + Box::from(Div(a.clone(), b.clone())), + ), + + (Div(a, b), Call(x, y)) => Mul( + Box::from(Div(a.clone(), b.clone())), + Box::from(Call(x.clone(), y.clone())), + ), + _ => Identifier("@Those two values are incompatible with the * operator".to_string()), } } diff --git a/src/interpreting/interpreter.rs b/src/interpreting/interpreter.rs index af27e94..70115db 100644 --- a/src/interpreting/interpreter.rs +++ b/src/interpreting/interpreter.rs @@ -95,6 +95,9 @@ pub fn interpret( Parameters::Plus(x, y) => add(*x.clone(), *y.clone(), Some(&ram)), Parameters::Mul(x, y) => mult(*x.clone(), *y.clone(), Some(&ram)), Parameters::Div(x, y) => divide(*x.clone(), *y.clone(), Some(&ram)), + Parameters::Call(x, y) => { + exec(x.clone(), vec![*y.clone()], Some(ram), Some(function)) + } }; last.clone() } diff --git a/src/interpreting/stdlib.rs b/src/interpreting/stdlib.rs index d354eb2..f7f2e5d 100644 --- a/src/interpreting/stdlib.rs +++ b/src/interpreting/stdlib.rs @@ -4,6 +4,7 @@ use std::f64::consts::{E, PI}; use gnuplot::{AxesCommon, Figure}; use crate::configuration::loader::{load, load_config, Config}; +use crate::functions::minus::minus; use crate::interpreting::interpreter::interpret; use crate::parsing::ast::{Ast, Parameters, Parameters::*}; use crate::utils::matrix_utils::{lup_decompose, lup_determinant, lup_invert, transpose}; @@ -164,9 +165,9 @@ pub fn cos(p: &Vec, ram: &Option<&mut HashMap>) InterpreterVector(Box::from(res)) } Identifier(s) => match ram { - None => Identifier("This variable is not initialized yet".to_string()), + None => Call("cos".to_string(), Box::from(Identifier(s.clone()))), Some(ref t) => match t.get(s.as_str()) { - None => Null, + None => Call("cos".to_string(), Box::from(Identifier(s.clone()))), Some(t) => { if degrees { cos(&vec![t.clone(), Identifier("false".to_string())], ram) @@ -176,7 +177,7 @@ pub fn cos(p: &Vec, ram: &Option<&mut HashMap>) } }, }, - _ => Null, + p => Call("cos".to_string(), Box::from(p.clone())), } } @@ -251,9 +252,9 @@ pub fn sin(p: &Vec, ram: &Option<&mut HashMap>) InterpreterVector(Box::from(res)) } Identifier(s) => match ram { - None => Identifier("This variable is not initialized yet".to_string()), + None => Call("sin".to_string(), Box::from(Identifier(s.clone()))), Some(ref t) => match t.get(s.as_str()) { - None => Null, + None => Call("sin".to_string(), Box::from(Identifier(s.clone()))), Some(t) => { if degrees { sin(&vec![t.clone(), Identifier("false".to_string())], ram) @@ -263,7 +264,7 @@ pub fn sin(p: &Vec, ram: &Option<&mut HashMap>) } }, }, - _ => Null, + p => Call("sin".to_string(), Box::from(p.clone())), } } @@ -339,9 +340,9 @@ pub fn tan(p: &Vec, ram: &Option<&mut HashMap>) InterpreterVector(Box::from(res)) } Identifier(s) => match ram { - None => Identifier("This variable is not initialized yet".to_string()), + None => Call("tan".to_string(), Box::from(Identifier(s.clone()))), Some(ref t) => match t.get(s.as_str()) { - None => Null, + None => Call("tan".to_string(), Box::from(Identifier(s.clone()))), Some(t) => { if degrees { tan(&vec![t.clone(), Identifier("false".to_string())], ram) @@ -351,7 +352,7 @@ pub fn tan(p: &Vec, ram: &Option<&mut HashMap>) } }, }, - _ => Null, + p => Call("tan".to_string(), Box::from(p.clone())), } } @@ -427,9 +428,9 @@ pub fn cosh(p: &Vec, ram: &Option<&mut HashMap>) InterpreterVector(Box::from(res)) } Identifier(s) => match ram { - None => Identifier("This variable is not initialized yet".to_string()), + None => Call("cosh".to_string(), Box::from(Identifier(s.clone()))), Some(ref t) => match t.get(s.as_str()) { - None => Null, + None => Call("cosh".to_string(), Box::from(Identifier(s.clone()))), Some(t) => { if degrees { cosh(&vec![t.clone(), Identifier("false".to_string())], ram) @@ -439,7 +440,7 @@ pub fn cosh(p: &Vec, ram: &Option<&mut HashMap>) } }, }, - _ => Null, + p => Call("cosh".to_string(), Box::from(p.clone())), } } @@ -515,9 +516,9 @@ pub fn sinh(p: &Vec, ram: &Option<&mut HashMap>) InterpreterVector(Box::from(res)) } Identifier(s) => match ram { - None => Identifier("This variable is not initialized yet".to_string()), + None => Call("sinh".to_string(), Box::from(Identifier(s.clone()))), Some(ref t) => match t.get(s.as_str()) { - None => Null, + None => Call("sinh".to_string(), Box::from(Identifier(s.clone()))), Some(t) => { if degrees { sinh(&vec![t.clone(), Identifier("false".to_string())], ram) @@ -527,7 +528,7 @@ pub fn sinh(p: &Vec, ram: &Option<&mut HashMap>) } }, }, - _ => Null, + p => Call("sinh".to_string(), Box::from(p.clone())), } } @@ -603,9 +604,9 @@ pub fn tanh(p: &Vec, ram: &Option<&mut HashMap>) InterpreterVector(Box::from(res)) } Identifier(s) => match ram { - None => Identifier("This variable is not initialized yet".to_string()), + None => Call("tanh".to_string(), Box::from(Identifier(s.clone()))), Some(ref t) => match t.get(s.as_str()) { - None => Null, + None => Call("tanh".to_string(), Box::from(Identifier(s.clone()))), Some(t) => { if degrees { tanh(&vec![t.clone(), Identifier("false".to_string())], ram) @@ -615,7 +616,7 @@ pub fn tanh(p: &Vec, ram: &Option<&mut HashMap>) } }, }, - _ => Null, + p => Call("tanh".to_string(), Box::from(p.clone())), } } @@ -689,9 +690,9 @@ pub fn acos(p: &Vec, ram: &Option<&mut HashMap>) InterpreterVector(Box::from(res)) } Identifier(s) => match ram { - None => Identifier("This variable is not initialized yet".to_string()), + None => Call("acos".to_string(), Box::from(Identifier(s.clone()))), Some(ref t) => match t.get(s.as_str()) { - None => Null, + None => Call("acos".to_string(), Box::from(Identifier(s.clone()))), Some(t) => { if degrees { acos(&vec![t.clone(), Identifier("false".to_string())], ram) @@ -701,7 +702,7 @@ pub fn acos(p: &Vec, ram: &Option<&mut HashMap>) } }, }, - _ => Null, + p => Call("acos".to_string(), Box::from(p.clone())), } } @@ -776,9 +777,9 @@ pub fn asin(p: &Vec, ram: &Option<&mut HashMap>) InterpreterVector(Box::from(res)) } Identifier(s) => match ram { - None => Identifier("This variable is not initialized yet".to_string()), + None => Call("asin".to_string(), Box::from(Identifier(s.clone()))), Some(ref t) => match t.get(s.as_str()) { - None => Null, + None => Call("asin".to_string(), Box::from(Identifier(s.clone()))), Some(t) => { if degrees { asin(&vec![t.clone(), Identifier("false".to_string())], ram) @@ -788,7 +789,7 @@ pub fn asin(p: &Vec, ram: &Option<&mut HashMap>) } }, }, - _ => Null, + p => Call("asin".to_string(), Box::from(p.clone())), } } @@ -863,9 +864,9 @@ pub fn atan(p: &Vec, ram: &Option<&mut HashMap>) InterpreterVector(Box::from(res)) } Identifier(s) => match ram { - None => Identifier("This variable is not initialized yet".to_string()), + None => Call("atan".to_string(), Box::from(Identifier(s.clone()))), Some(ref t) => match t.get(s.as_str()) { - None => Null, + None => Call("atan".to_string(), Box::from(Identifier(s.clone()))), Some(t) => { if degrees { atan(&vec![t.clone(), Identifier("false".to_string())], ram) @@ -875,7 +876,7 @@ pub fn atan(p: &Vec, ram: &Option<&mut HashMap>) } }, }, - _ => Null, + p => Call("atan".to_string(), Box::from(p.clone())), } } @@ -957,13 +958,13 @@ pub fn exp(p: &Vec, ram: &Option<&mut HashMap>) InterpreterVector(Box::from(res)) } Identifier(s) => match ram { - None => Identifier("This variable is not initialized yet".to_string()), + None => Call("exp".to_string(), Box::from(Identifier(s.clone()))), Some(ref t) => match t.get(s.as_str()) { - None => Null, + None => Call("exp".to_string(), Box::from(Identifier(s.clone()))), Some(t) => exp(&vec![t.clone(), Float(ln)], ram), }, }, - _ => Null, + p => Call("exp".to_string(), Box::from(p.clone())), } } @@ -1046,13 +1047,13 @@ pub fn ln(p: &Vec, ram: &Option<&mut HashMap>) - InterpreterVector(Box::from(res)) } Identifier(s) => match ram { - None => Identifier("This variable is not initialized yet".to_string()), + None => Call("ln".to_string(), Box::from(Identifier(s.clone()))), Some(ref t) => match t.get(s.as_str()) { - None => Null, + None => Call("ln".to_string(), Box::from(Identifier(s.clone()))), Some(t) => ln(&vec![t.clone(), Float(sln)], ram), }, }, - _ => Null, + p => Call("ln".to_string(), Box::from(p.clone())), } } @@ -1138,13 +1139,13 @@ pub fn sqrt(p: &Vec, ram: &Option<&mut HashMap>) InterpreterVector(Box::from(res)) } Identifier(s) => match ram { - None => Identifier("This variable is not initialized yet".to_string()), + None => Call("sqrt".to_string(), Box::from(Identifier(s.clone()))), Some(ref t) => match t.get(s.as_str()) { - None => Null, + None => Call("sqrt".to_string(), Box::from(Identifier(s.clone()))), Some(t) => sqrt(&vec![t.clone(), Float(sln)], ram), }, }, - _ => Null, + p => Call("sqrt".to_string(), Box::from(p.clone())), } } @@ -1579,17 +1580,80 @@ pub fn diff( } match first_param { Identifier(fun) => match fun.as_str() { - "cos" => Identifier("-sin(x)".to_string()), - "sin" => Identifier("cos(x)".to_string()), - "exp" => Identifier("exp(x)".to_string()), - "ln" => Identifier("1/x".to_string()), - "tan" => Identifier("1/(cos(x)*cos(x))".to_string()), - "sinh" => Identifier("sinh".to_string()), - "cosh" => Identifier("cosh".to_string()), - "acos" => Identifier("(-1)/(sqrt(1 - x*x))".to_string()), - "asin" => Identifier("1/(sqrt(1-x*x))".to_string()), + "cos" => Plus( + Box::from(Int(0)), + Box::from(mult( + Int(-1), + Call( + "sin".to_string(), + Box::from(Var(Box::from(Int(1)), 1, "x".to_string())), + ), + Some(&c), + )), + ), + "sin" => Call( + "cos".to_string(), + Box::from(Var(Box::from(Int(1)), 1, "x".to_string())), + ), + "exp" => Call( + "exp".to_string(), + Box::from(Var(Box::from(Int(1)), 1, "x".to_string())), + ), + "ln" => Var(Box::from(Int(1)), -1, "x".to_string()), + "tan" => Div( + Box::from(Int(1)), + Box::from(Mul( + Box::from(Call( + "cos".to_string(), + Box::from(Var(Box::from(Int(1)), 1, "x".to_string())), + )), + Box::from(Call( + "cos".to_string(), + Box::from(Var(Box::from(Int(1)), 1, "x".to_string())), + )), + )), + ), + "sinh" => Call( + "cosh".to_string(), + Box::from(Var(Box::from(Int(1)), 1, "x".to_string())), + ), + "cosh" => Call( + "sinh".to_string(), + Box::from(Var(Box::from(Int(1)), 1, "x".to_string())), + ), + "acos" => Div( + Box::from(Int(-1)), + Box::from(Call( + "sqrt".to_string(), + Box::from(minus( + Int(1), + Var(Box::from(Int(1)), 2, "x".to_string()), + Some(&c), + )), + )), + ), + "asin" => Div( + Box::from(Int(1)), + Box::from(Call( + "sqrt".to_string(), + Box::from(minus( + Int(1), + Var(Box::from(Int(1)), 2, "x".to_string()), + Some(&c), + )), + )), + ), "x" => Identifier("1".to_string()), - "sqrt" => Identifier("1/(2*sqrt(x))".to_string()), + "sqrt" => Div( + Box::from(Int(1)), + Box::from(Mul( + Box::from(Int(2)), + Box::from(Call( + "sqrt".to_string(), + Box::from(Var(Box::from(Int(1)), 1, "x".to_string())), + )), + )), + ), p => { let param = exec( p.to_string(), diff --git a/src/parsing/ast.rs b/src/parsing/ast.rs index 21d7f37..fa97b30 100644 --- a/src/parsing/ast.rs +++ b/src/parsing/ast.rs @@ -36,6 +36,7 @@ pub enum Parameters { Plus(Box, Box), Mul(Box, Box), Div(Box, Box), + Call(String, Box), } #[derive(Debug, Clone, PartialEq)] @@ -117,6 +118,7 @@ impl Display for Parameters { Mul(x, y) => write!(f, "(({x})*({y}))"), Var(x, y, s) => write!(f, "({x}){s}{}", int_to_superscript_string(*y)), Div(x, y) => write!(f, "(({x})/({y}))"), + Call(x, y) => write!(f, "{x}({y})"), } } }