Add ArithmeticOperation

This commit is contained in:
Austen Adler 2021-05-31 15:37:55 -04:00
parent 39e3c83abc
commit d84f2f7076
3 changed files with 223 additions and 111 deletions

View File

@ -7,7 +7,7 @@ use crate::calc::entries::CalculatorEntry;
use confy::{load, store}; use confy::{load, store};
use entries::{Entry, Number}; use entries::{Entry, Number};
use errors::{CalculatorError, CalculatorResult}; use errors::{CalculatorError, CalculatorResult};
use operations::{CalculatorOperation, CalculatorStateChange, MacroState, OpArgs}; use operations::{ArithmeticOperation,CalculatorOperation, CalculatorStateChange, MacroState, OpArgs};
use serde::ser::Serializer; use serde::ser::Serializer;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap}; use std::collections::{BTreeMap, HashMap};
@ -214,29 +214,29 @@ impl Calculator {
_ => Err(CalculatorError::ParseError), _ => Err(CalculatorError::ParseError),
} }
} }
'+' => self.op(CalculatorOperation::Add), '+' => self.op(CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Add)),
'-' => self.op(CalculatorOperation::Subtract), '-' => self.op(CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Subtract)),
'*' => self.op(CalculatorOperation::Multiply), '*' => self.op(CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Multiply)),
'/' => self.op(CalculatorOperation::Divide), '/' => self.op(CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Divide)),
'n' => self.op(CalculatorOperation::Negate), 'n' => self.op(CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Negate)),
'|' => self.op(CalculatorOperation::AbsoluteValue), '|' => self.op(CalculatorOperation::ArithmeticOperation(ArithmeticOperation::AbsoluteValue)),
'i' => self.op(CalculatorOperation::Inverse), 'i' => self.op(CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Inverse)),
'%' => self.op(CalculatorOperation::Modulo), '%' => self.op(CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Modulo)),
'?' => self.op(CalculatorOperation::ArithmeticOperation(ArithmeticOperation::IntegerDivide)),
's' => self.op(CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Sin)),
'c' => self.op(CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Cos)),
't' => self.op(CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Tan)),
'S' => self.op(CalculatorOperation::ArithmeticOperation(ArithmeticOperation::ASin)),
'C' => self.op(CalculatorOperation::ArithmeticOperation(ArithmeticOperation::ACos)),
'T' => self.op(CalculatorOperation::ArithmeticOperation(ArithmeticOperation::ATan)),
'v' => self.op(CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Sqrt)),
'^' => self.op(CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Pow)),
'l' => self.op(CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Log)),
'L' => self.op(CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Ln)),
// Special
'\\' => self.op(CalculatorOperation::Drop), '\\' => self.op(CalculatorOperation::Drop),
'?' => self.op(CalculatorOperation::IntegerDivide),
' ' => self.op(CalculatorOperation::Dup), ' ' => self.op(CalculatorOperation::Dup),
'>' => self.op(CalculatorOperation::Swap), '>' => self.op(CalculatorOperation::Swap),
's' => self.op(CalculatorOperation::Sin),
'c' => self.op(CalculatorOperation::Cos),
't' => self.op(CalculatorOperation::Tan),
'S' => self.op(CalculatorOperation::ASin),
'C' => self.op(CalculatorOperation::ACos),
'T' => self.op(CalculatorOperation::ATan),
'v' => self.op(CalculatorOperation::Sqrt),
'^' => self.op(CalculatorOperation::Pow),
'l' => self.op(CalculatorOperation::Log),
'L' => self.op(CalculatorOperation::Ln),
// Special
'u' => self.op(CalculatorOperation::Undo), 'u' => self.op(CalculatorOperation::Undo),
'U' => self.op(CalculatorOperation::Redo), 'U' => self.op(CalculatorOperation::Redo),
// State modifiers // State modifiers
@ -478,7 +478,7 @@ impl Calculator {
let entry = self.peek(0)?; let entry = self.peek(0)?;
let f = match entry { let f = match entry {
Entry::Number(Number { value }) => value, Entry::Number(Number { value }) => value,
// Entry::Vector(_) => return Err(CalculatorError::TypeMismatch), Entry::Vector(_) => return Err(CalculatorError::TypeMismatch),
}; };
// Ensure this can be cast to a usize // Ensure this can be cast to a usize
if !f.is_finite() || f.is_sign_negative() { if !f.is_finite() || f.is_sign_negative() {
@ -507,63 +507,63 @@ impl Calculator {
} }
} }
let state_change = match op { let state_change = match op {
CalculatorOperation::Add => { CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Add) => {
self.binary_op(|[a, b]| Ok(OpArgs::Unary(b.add(a)?))) self.binary_op(|[a, b]| Ok(OpArgs::Unary(b.add(a)?)))
} }
CalculatorOperation::Subtract => { CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Subtract) => {
self.binary_op(|[a, b]| Ok(OpArgs::Unary(b.sub(a)?))) self.binary_op(|[a, b]| Ok(OpArgs::Unary(b.sub(a)?)))
} }
CalculatorOperation::Multiply => { CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Multiply) => {
self.binary_op(|[a, b]| Ok(OpArgs::Unary(b.mul(a)?))) self.binary_op(|[a, b]| Ok(OpArgs::Unary(b.mul(a)?)))
} }
CalculatorOperation::Divide => { CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Divide) => {
self.binary_op(|[a, b]| Ok(OpArgs::Unary(b.div(a)?))) self.binary_op(|[a, b]| Ok(OpArgs::Unary(b.div(a)?)))
} }
CalculatorOperation::IntegerDivide => { CalculatorOperation::ArithmeticOperation(ArithmeticOperation::IntegerDivide) => {
self.binary_op(|[a, b]| Ok(OpArgs::Unary(b.int_divide(a)?))) self.binary_op(|[a, b]| Ok(OpArgs::Unary(b.int_divide(a)?)))
} }
CalculatorOperation::Negate => { CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Negate) => {
self.unary_op(|a| Ok(OpArgs::Unary(a.negate()?))) self.unary_op(|a| Ok(OpArgs::Unary(a.negate()?)))
} }
CalculatorOperation::AbsoluteValue => { CalculatorOperation::ArithmeticOperation(ArithmeticOperation::AbsoluteValue) => {
self.unary_op(|a| Ok(OpArgs::Unary(a.abs()?))) self.unary_op(|a| Ok(OpArgs::Unary(a.abs()?)))
} }
CalculatorOperation::Inverse => { CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Inverse) => {
self.unary_op(|a| Ok(OpArgs::Unary(a.inverse()?))) self.unary_op(|a| Ok(OpArgs::Unary(a.inverse()?)))
} }
CalculatorOperation::Modulo => { CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Modulo) => {
self.binary_op(|[a, b]| Ok(OpArgs::Unary(b.modulo(a)?))) self.binary_op(|[a, b]| Ok(OpArgs::Unary(b.modulo(a)?)))
} }
CalculatorOperation::Sin => { CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Sin) => {
let angle_mode = self.angle_mode; let angle_mode = self.angle_mode;
self.unary_op(|a| Ok(OpArgs::Unary(a.sin(angle_mode)?))) self.unary_op(|a| Ok(OpArgs::Unary(a.sin(angle_mode)?)))
} }
CalculatorOperation::Cos => { CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Cos) => {
let angle_mode = self.angle_mode; let angle_mode = self.angle_mode;
self.unary_op(|a| Ok(OpArgs::Unary(a.cos(angle_mode)?))) self.unary_op(|a| Ok(OpArgs::Unary(a.cos(angle_mode)?)))
} }
CalculatorOperation::Tan => { CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Tan) => {
let angle_mode = self.angle_mode; let angle_mode = self.angle_mode;
self.unary_op(|a| Ok(OpArgs::Unary(a.tan(angle_mode)?))) self.unary_op(|a| Ok(OpArgs::Unary(a.tan(angle_mode)?)))
} }
CalculatorOperation::ASin => { CalculatorOperation::ArithmeticOperation(ArithmeticOperation::ASin) => {
let angle_mode = self.angle_mode; let angle_mode = self.angle_mode;
self.unary_op(|a| Ok(OpArgs::Unary(a.asin(angle_mode)?))) self.unary_op(|a| Ok(OpArgs::Unary(a.asin(angle_mode)?)))
} }
CalculatorOperation::ACos => { CalculatorOperation::ArithmeticOperation(ArithmeticOperation::ACos) => {
let angle_mode = self.angle_mode; let angle_mode = self.angle_mode;
self.unary_op(|a| Ok(OpArgs::Unary(a.acos(angle_mode)?))) self.unary_op(|a| Ok(OpArgs::Unary(a.acos(angle_mode)?)))
} }
CalculatorOperation::ATan => { CalculatorOperation::ArithmeticOperation(ArithmeticOperation::ATan) => {
let angle_mode = self.angle_mode; let angle_mode = self.angle_mode;
self.unary_op(|a| Ok(OpArgs::Unary(a.atan(angle_mode)?))) self.unary_op(|a| Ok(OpArgs::Unary(a.atan(angle_mode)?)))
} }
CalculatorOperation::Sqrt => { CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Sqrt) => {
self.unary_op(|a| Ok(OpArgs::Unary(a.sqrt()?))) self.unary_op(|a| Ok(OpArgs::Unary(a.sqrt()?)))
} }
CalculatorOperation::Log => self.unary_op(|a| Ok(OpArgs::Unary(a.log()?))), CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Log) => self.unary_op(|a| Ok(OpArgs::Unary(a.log()?))),
CalculatorOperation::Ln => self.unary_op(|a| Ok(OpArgs::Unary(a.ln()?))), CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Ln) => self.unary_op(|a| Ok(OpArgs::Unary(a.ln()?))),
CalculatorOperation::Pow => { CalculatorOperation::ArithmeticOperation(ArithmeticOperation::Pow) => {
self.binary_op(|[a, b]| Ok(OpArgs::Unary(b.pow(a)?))) self.binary_op(|[a, b]| Ok(OpArgs::Unary(b.pow(a)?)))
} }
CalculatorOperation::Dup => { CalculatorOperation::Dup => {
@ -741,7 +741,6 @@ impl Calculator {
&mut self, &mut self,
op: impl FnOnce(Entry) -> CalculatorResult<OpArgs>, op: impl FnOnce(Entry) -> CalculatorResult<OpArgs>,
) -> CalculatorResult<CalculatorStateChange> { ) -> CalculatorResult<CalculatorStateChange> {
// TODO: Use peek instead of stack.get()
let arg = self.peek(0)?; let arg = self.peek(0)?;
Ok(CalculatorStateChange { Ok(CalculatorStateChange {
pop: OpArgs::Unary(arg.clone()), pop: OpArgs::Unary(arg.clone()),

View File

@ -1,5 +1,6 @@
// use super::operations::CalculatorStateChange; // use super::operations::CalculatorStateChange;
use super::errors::CalculatorResult; // TODO: This file kina blows. Tons of repetition. Do not know how to fix yet though
use super::errors::{CalculatorError, CalculatorResult};
use super::types::CalculatorAngleMode; use super::types::CalculatorAngleMode;
use crate::calc::CalculatorDisplayMode; use crate::calc::CalculatorDisplayMode;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -11,6 +12,15 @@ pub struct Number {
pub value: f64, pub value: f64,
} }
impl Number {
fn binary_op(arg: &Entry, op: impl Fn(&Number) -> Number) -> CalculatorResult<Entry> {
match arg {
Entry::Number(number) => Ok(Entry::Number(op(number))),
Entry::Vector(vector) => Ok(vector.map_into(op)),
}
}
}
impl PartialEq for Number { impl PartialEq for Number {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
if self.value.is_nan() && other.value.is_nan() if self.value.is_nan() && other.value.is_nan()
@ -29,17 +39,52 @@ impl PartialEq for Number {
} }
} }
// #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
// pub struct Vector { pub struct Vector {
// pub value: Vec<Number>, pub direction: bool,
// } pub values: Vec<Number>,
}
impl Vector {
fn binary_op(
&self,
arg: &Entry,
op: impl Fn((&Number, &Number)) -> Number,
) -> CalculatorResult<Entry> {
match arg {
// Entry::Number(number) => Ok(Entry::Number(op(number))),
Entry::Number(number) => Ok(self.map_into(|t| op((t, number)))),
Entry::Vector(vector) => {
if self.values.len() != vector.values.len() {
return Err(CalculatorError::ArithmeticError);
}
Ok(Entry::Vector(Vector {
values: self
.values
.iter()
.zip(vector.values.iter())
.map(op)
.collect(),
..*self
}))
}
}
}
pub fn map_into(&self, op: impl Fn(&Number) -> Number) -> Entry {
Entry::Vector(Vector {
values: (self.values.iter().map(op).collect()),
..*self
})
}
}
// TODO: Remove the copy trait
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
#[serde(tag = "type")] #[serde(tag = "type")]
pub enum Entry { pub enum Entry {
Number(Number), Number(Number),
// Vector(Vec<Number>), Vector(Vector),
// Matrix(Vec<Vec<Number>>), // Matrix(Vec<Vec<Number>>),
} }
@ -47,127 +92,127 @@ impl CalculatorEntry for Entry {
fn format_entry(&self, display_mode: &CalculatorDisplayMode) -> String { fn format_entry(&self, display_mode: &CalculatorDisplayMode) -> String {
match self { match self {
Self::Number(number) => number.format_entry(display_mode), Self::Number(number) => number.format_entry(display_mode),
// Self::Vector(vector) => vector.add(), Self::Vector(vector) => vector.format_entry(display_mode),
} }
} }
fn is_valid(&self) -> bool { fn is_valid(&self) -> bool {
match self { match self {
Self::Number(number) => number.is_valid(), Self::Number(number) => number.is_valid(),
// Self::Vector(vector) => vector.add(), Self::Vector(vector) => vector.is_valid(),
} }
} }
fn add(&self, arg: Self) -> CalculatorResult<Self> { fn add(&self, arg: Self) -> CalculatorResult<Self> {
match self { match self {
Self::Number(number) => number.add(arg), Self::Number(number) => number.add(arg),
// Self::Vector(vector) => vector.add(), Self::Vector(vector) => vector.add(arg),
} }
} }
fn sub(&self, arg: Self) -> CalculatorResult<Self> { fn sub(&self, arg: Self) -> CalculatorResult<Self> {
match self { match self {
Self::Number(number) => number.sub(arg), Self::Number(number) => number.sub(arg),
// Self::Vector(vector) => vector.sub(), Self::Vector(vector) => vector.sub(arg),
} }
} }
fn mul(&self, arg: Self) -> CalculatorResult<Self> { fn mul(&self, arg: Self) -> CalculatorResult<Self> {
match self { match self {
Self::Number(number) => number.mul(arg), Self::Number(number) => number.mul(arg),
// Self::Vector(vector) => vector.mul(), Self::Vector(vector) => vector.mul(arg),
} }
} }
fn div(&self, arg: Self) -> CalculatorResult<Self> { fn div(&self, arg: Self) -> CalculatorResult<Self> {
match self { match self {
Self::Number(number) => number.div(arg), Self::Number(number) => number.div(arg),
// Self::Vector(vector) => vector.div(), Self::Vector(vector) => vector.div(arg),
} }
} }
fn int_divide(&self, arg: Self) -> CalculatorResult<Self> { fn int_divide(&self, arg: Self) -> CalculatorResult<Self> {
match self { match self {
Self::Number(number) => number.int_divide(arg), Self::Number(number) => number.int_divide(arg),
// Self::Vector(vector) => vector.int_divide(), Self::Vector(vector) => vector.int_divide(arg),
} }
} }
fn negate(&self) -> CalculatorResult<Self> { fn negate(&self) -> CalculatorResult<Self> {
match self { match self {
Self::Number(number) => number.negate(), Self::Number(number) => number.negate(),
// Self::Vector(vector) => vector.negate(), Self::Vector(vector) => vector.negate(),
} }
} }
fn abs(&self) -> CalculatorResult<Self> { fn abs(&self) -> CalculatorResult<Self> {
match self { match self {
Self::Number(number) => number.abs(), Self::Number(number) => number.abs(),
// Self::Vector(vector) => vector.abs(), Self::Vector(vector) => vector.abs(),
} }
} }
fn inverse(&self) -> CalculatorResult<Self> { fn inverse(&self) -> CalculatorResult<Self> {
match self { match self {
Self::Number(number) => number.inverse(), Self::Number(number) => number.inverse(),
// Self::Vector(vector) => vector.inverse(), Self::Vector(vector) => vector.inverse(),
} }
} }
fn modulo(&self, arg: Self) -> CalculatorResult<Self> { fn modulo(&self, arg: Self) -> CalculatorResult<Self> {
match self { match self {
Self::Number(number) => number.modulo(arg), Self::Number(number) => number.modulo(arg),
// Self::Vector(vector) => vector.modulo(), Self::Vector(vector) => vector.modulo(arg),
} }
} }
fn sin(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Self> { fn sin(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Self> {
match self { match self {
Self::Number(number) => number.sin(angle_mode), Self::Number(number) => number.sin(angle_mode),
// Self::Vector(vector) => vector.sin(), Self::Vector(vector) => vector.sin(angle_mode),
} }
} }
fn cos(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Self> { fn cos(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Self> {
match self { match self {
Self::Number(number) => number.cos(angle_mode), Self::Number(number) => number.cos(angle_mode),
// Self::Vector(vector) => vector.cos(), Self::Vector(vector) => vector.cos(angle_mode),
} }
} }
fn tan(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Self> { fn tan(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Self> {
match self { match self {
Self::Number(number) => number.tan(angle_mode), Self::Number(number) => number.tan(angle_mode),
// Self::Vector(vector) => vector.tan(), Self::Vector(vector) => vector.tan(angle_mode),
} }
} }
fn asin(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Self> { fn asin(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Self> {
match self { match self {
Self::Number(number) => number.asin(angle_mode), Self::Number(number) => number.asin(angle_mode),
// Self::Vector(vector) => vector.asin(), Self::Vector(vector) => vector.asin(angle_mode),
} }
} }
fn acos(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Self> { fn acos(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Self> {
match self { match self {
Self::Number(number) => number.acos(angle_mode), Self::Number(number) => number.acos(angle_mode),
// Self::Vector(vector) => vector.acos(), Self::Vector(vector) => vector.acos(angle_mode),
} }
} }
fn atan(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Self> { fn atan(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Self> {
match self { match self {
Self::Number(number) => number.atan(angle_mode), Self::Number(number) => number.atan(angle_mode),
// Self::Vector(vector) => vector.atan(), Self::Vector(vector) => vector.atan(angle_mode),
} }
} }
fn sqrt(&self) -> CalculatorResult<Self> { fn sqrt(&self) -> CalculatorResult<Self> {
match self { match self {
Self::Number(number) => number.sqrt(), Self::Number(number) => number.sqrt(),
// Self::Vector(vector) => vector.sqrt(), Self::Vector(vector) => vector.sqrt(),
} }
} }
fn log(&self) -> CalculatorResult<Self> { fn log(&self) -> CalculatorResult<Self> {
match self { match self {
Self::Number(number) => number.log(), Self::Number(number) => number.log(),
// Self::Vector(vector) => vector.log(), Self::Vector(vector) => vector.log(),
} }
} }
fn ln(&self) -> CalculatorResult<Self> { fn ln(&self) -> CalculatorResult<Self> {
match self { match self {
Self::Number(number) => number.ln(), Self::Number(number) => number.ln(),
// Self::Vector(vector) => vector.ln(), Self::Vector(vector) => vector.ln(),
} }
} }
fn pow(&self, arg: Self) -> CalculatorResult<Self> { fn pow(&self, arg: Self) -> CalculatorResult<Self> {
match self { match self {
Self::Number(number) => number.pow(arg), Self::Number(number) => number.pow(arg),
// Self::Vector(vector) => vector.pow(), Self::Vector(vector) => vector.pow(arg),
} }
} }
} }
@ -194,39 +239,29 @@ impl CalculatorEntry for Number {
!self.value.is_nan() && !self.value.is_infinite() !self.value.is_nan() && !self.value.is_infinite()
} }
fn add(&self, arg: Entry) -> CalculatorResult<Entry> { fn add(&self, arg: Entry) -> CalculatorResult<Entry> {
match arg { Number::binary_op(&arg, |b| Self {
Entry::Number(Self { value }) => Ok(Entry::Number(Self { value: b.value + self.value,
value: value + self.value, })
})),
}
} }
fn sub(&self, arg: Entry) -> CalculatorResult<Entry> { fn sub(&self, arg: Entry) -> CalculatorResult<Entry> {
match arg { Number::binary_op(&arg, |b| Self {
Entry::Number(Self { value }) => Ok(Entry::Number(Self { value: b.value - self.value,
value: value - self.value, })
})),
}
} }
fn mul(&self, arg: Entry) -> CalculatorResult<Entry> { fn mul(&self, arg: Entry) -> CalculatorResult<Entry> {
match arg { Number::binary_op(&arg, |b| Self {
Entry::Number(Self { value }) => Ok(Entry::Number(Self { value: b.value * self.value,
value: value * self.value, })
})),
}
} }
fn div(&self, arg: Entry) -> CalculatorResult<Entry> { fn div(&self, arg: Entry) -> CalculatorResult<Entry> {
match arg { Number::binary_op(&arg, |b| Self {
Entry::Number(Self { value }) => Ok(Entry::Number(Self { value: b.value / self.value,
value: value / self.value, })
})),
}
} }
fn int_divide(&self, arg: Entry) -> CalculatorResult<Entry> { fn int_divide(&self, arg: Entry) -> CalculatorResult<Entry> {
match arg { Number::binary_op(&arg, |b| Self {
Entry::Number(Self { value }) => Ok(Entry::Number(Self { value: b.value.div_euclid(self.value),
value: value.div_euclid(self.value), })
})),
}
} }
fn negate(&self) -> CalculatorResult<Entry> { fn negate(&self) -> CalculatorResult<Entry> {
Ok(Entry::Number(Self { value: -self.value })) Ok(Entry::Number(Self { value: -self.value }))
@ -242,11 +277,9 @@ impl CalculatorEntry for Number {
})) }))
} }
fn modulo(&self, arg: Entry) -> CalculatorResult<Entry> { fn modulo(&self, arg: Entry) -> CalculatorResult<Entry> {
match arg { Number::binary_op(&arg, |b| Self {
Entry::Number(Self { value }) => Ok(Entry::Number(Self { value: b.value % self.value,
value: value % self.value, })
})),
}
} }
fn sin(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> { fn sin(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {
Ok(Entry::Number(Self { Ok(Entry::Number(Self {
@ -330,11 +363,88 @@ impl CalculatorEntry for Number {
})) }))
} }
fn pow(&self, arg: Entry) -> CalculatorResult<Entry> { fn pow(&self, arg: Entry) -> CalculatorResult<Entry> {
match arg { Number::binary_op(&arg, |b| Self {
Entry::Number(Self { value }) => Ok(Entry::Number(Self { value: b.value.powf(self.value),
value: value.powf(self.value), })
})), }
} }
impl CalculatorEntry for Vector {
// Misc
fn is_valid(&self) -> bool {
!self.values
.iter()
.find(|number| !number.is_valid())
.is_some()
}
fn format_entry(&self, display_mode: &CalculatorDisplayMode) -> String {
format!(
"[{}]",
self.values
.iter()
.map(|number| number.format_entry(display_mode))
.collect::<Vec<String>>()
.join("; ")
)
}
// Mathematical operations
fn add(&self, arg: Entry) -> CalculatorResult<Entry> {
self.binary_op(&arg, |(a, b)| Number {
value: b.value + a.value,
})
}
fn sub(&self, arg: Entry) -> CalculatorResult<Entry> {
self.binary_op(&arg, |(a, b)| Number {
value: b.value - a.value,
})
}
fn mul(&self, arg: Entry) -> CalculatorResult<Entry> {
self.binary_op(&arg, |(a, b)| Number {
value: b.value * a.value,
})
}
fn div(&self, arg: Entry) -> CalculatorResult<Entry> {
self.binary_op(&arg, |(a, b)| Number {
value: b.value / a.value,
})
}
fn int_divide(&self, arg: Entry) -> CalculatorResult<Entry> {
self.binary_op(&arg, |(a, b)| Number {
value: b.value.div_euclid(a.value),
})
}
fn negate(&self) -> CalculatorResult<Entry> {
Ok(self.map_into(|n| Number { value: -n.value }))
}
fn abs(&self) -> CalculatorResult<Entry> {
Ok(self.map_into(|n| Number {
value: n.value.abs(),
}))
}
fn inverse(&self) -> CalculatorResult<Entry> {
Ok(Entry::Vector(Vector {
direction: !self.direction,
..*self
}))
}
fn modulo(&self, arg: Entry) -> CalculatorResult<Entry> {
self.binary_op(&arg, |(a, b)| Number {
value: b.value % a.value,
})
}
fn sin(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {}
fn cos(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {}
fn tan(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {}
fn asin(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {}
fn acos(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {}
fn atan(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {}
fn sqrt(&self) -> CalculatorResult<Entry> {}
fn log(&self) -> CalculatorResult<Entry> {}
fn ln(&self) -> CalculatorResult<Entry> {}
fn pow(&self, arg: Entry) -> CalculatorResult<Entry> {
self.binary_op(&arg, |(a, b)| Number {
value: b.value.powf(a.value),
})
} }
} }

View File

@ -1,8 +1,8 @@
use super::entries::Entry; use super::entries::Entry;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Operations that can be sent to the calculator such as +, -, or undo
#[derive(PartialEq, Debug, Serialize, Deserialize)] #[derive(PartialEq, Debug, Serialize, Deserialize)]
pub enum CalculatorOperation { pub enum ArithmeticOperation {
Add, Add,
Subtract, Subtract,
Multiply, Multiply,
@ -12,7 +12,6 @@ pub enum CalculatorOperation {
Inverse, Inverse,
Modulo, Modulo,
IntegerDivide, IntegerDivide,
//Remainder,
Sin, Sin,
Cos, Cos,
Tan, Tan,
@ -20,12 +19,16 @@ pub enum CalculatorOperation {
ACos, ACos,
ATan, ATan,
Sqrt, Sqrt,
Undo,
Redo,
Pow, Pow,
// Factorial,
Log, Log,
Ln, Ln,
}
/// Operations that can be sent to the calculator such as +, -, or undo
#[derive(PartialEq, Debug, Serialize, Deserialize)]
pub enum CalculatorOperation {
ArithmeticOperation(ArithmeticOperation),
Undo,
Redo,
Drop, Drop,
Dup, Dup,
Swap, Swap,