Add ArithmeticOperation
This commit is contained in:
parent
39e3c83abc
commit
d84f2f7076
83
src/calc.rs
83
src/calc.rs
@ -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()),
|
||||||
|
@ -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),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user