aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Anthony <sam@samanthony.xyz>2023-03-13 21:32:05 -0230
committerSam Anthony <sam@samanthony.xyz>2023-03-13 21:32:05 -0230
commit8756ace462ab94e540d53c633b7e76c21b7a6bcd (patch)
tree4ae8e0025aa8c25af8f15164ba06dd98f9a6324b
parentc83c2315dd45bb0bc590995ea0899a0ebd1b59dc (diff)
downloadpfc-8756ace462ab94e540d53c633b7e76c21b7a6bcd.zip
inverse trig functions
-rw-r--r--src/function.rs61
-rw-r--r--src/input.rs4
-rw-r--r--src/lib.rs59
3 files changed, 68 insertions, 56 deletions
diff --git a/src/function.rs b/src/function.rs
new file mode 100644
index 0000000..bb6462d
--- /dev/null
+++ b/src/function.rs
@@ -0,0 +1,61 @@
+use crate::AngleMode;
+
+pub enum Function {
+ Sin, // Sine
+ Cos, // Cosine
+ Tan, // Tangent
+ Asin, // Inverse sine
+ Acos, // Inverse cosine
+ Atan, // Inverse tangent
+ Deg, // Convert from radians to degrees
+ Rad, // Convert from degrees to radians
+}
+
+impl Function {
+ pub fn parse(s: &str) -> Result<Self, ParseFunctionError> {
+ match s {
+ "sin" => Ok(Self::Sin),
+ "cos" => Ok(Self::Cos),
+ "tan" => Ok(Self::Tan),
+ "asin" => Ok(Self::Asin),
+ "acos" => Ok(Self::Acos),
+ "atan" => Ok(Self::Atan),
+ "deg" => Ok(Self::Deg),
+ "rad" => Ok(Self::Rad),
+ _ => Err(ParseFunctionError(s.to_string())),
+ }
+ }
+
+ pub fn call(&self, val: f64, angle_mode: AngleMode) -> f64 {
+ match self {
+ Self::Sin => match angle_mode {
+ AngleMode::Degrees => val.to_radians().sin(),
+ AngleMode::Radians => val.sin(),
+ },
+ Self::Cos => match angle_mode {
+ AngleMode::Degrees => val.to_radians().cos(),
+ AngleMode::Radians => val.cos(),
+ },
+ Self::Tan => match angle_mode {
+ AngleMode::Degrees => val.to_radians().tan(),
+ AngleMode::Radians => val.tan(),
+ },
+ Self::Asin => match angle_mode {
+ AngleMode::Degrees => val.asin().to_degrees(),
+ AngleMode::Radians => val.asin(),
+ },
+ Self::Acos => match angle_mode {
+ AngleMode::Degrees => val.acos().to_degrees(),
+ AngleMode::Radians => val.acos(),
+ },
+ Self::Atan => match angle_mode {
+ AngleMode::Degrees => val.atan().to_degrees(),
+ AngleMode::Radians => val.atan(),
+ },
+ Self::Deg => val.to_degrees(),
+ Self::Rad => val.to_radians(),
+ }
+ }
+}
+
+pub struct ParseFunctionError(String);
diff --git a/src/input.rs b/src/input.rs
index dbfe763..4de615f 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -32,7 +32,9 @@ impl Calculator {
}
KeyCode::Enter => {
if let Ok(func) = Function::parse(&self.input_buffer) {
- self.call_function(func);
+ if let Some(val) = self.stack.pop() {
+ self.stack.push(func.call(val, self.angle_mode));
+ }
} else if let Ok(c) = Constant::parse(&self.input_buffer) {
self.stack.push(c.value());
} else if let Ok(bu) = self.input_buffer.parse::<f64>() {
diff --git a/src/lib.rs b/src/lib.rs
index 039258c..db316f0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -3,9 +3,12 @@ use std::{
fmt::{self, Display, Formatter},
};
+mod function;
mod input;
pub mod ui;
+pub use function::Function;
+
#[derive(Default)]
pub struct Calculator {
stack: Vec<f64>,
@@ -35,41 +38,10 @@ impl Calculator {
Operator::Exp => lhs.powf(rhs),
});
}
-
- fn call_function(&mut self, func: Function) {
- let mut val = match self.stack.pop() {
- Some(v) => v,
- None => {
- return;
- }
- };
- self.stack.push(match func {
- Function::Sin => {
- if self.angle_mode == AngleMode::Degrees {
- val = val.to_radians();
- }
- val.sin()
- }
- Function::Cos => {
- if self.angle_mode == AngleMode::Degrees {
- val = val.to_radians();
- }
- val.cos()
- }
- Function::Tan => {
- if self.angle_mode == AngleMode::Degrees {
- val = val.to_radians();
- }
- val.tan()
- }
- Function::Deg => val.to_degrees(),
- Function::Rad => val.to_radians(),
- });
- }
}
#[derive(Default, Copy, Clone, PartialEq)]
-enum AngleMode {
+pub enum AngleMode {
#[default]
Degrees,
Radians,
@@ -120,29 +92,6 @@ impl Operator {
struct ParseOperatorError(char);
-enum Function {
- Sin, // Sine
- Cos, // Cosine
- Tan, // Tangent
- Deg, // Convert from radians to degrees
- Rad, // Convert from degrees to radians
-}
-
-impl Function {
- fn parse(s: &str) -> Result<Self, ParseFunctionError> {
- match s {
- "sin" => Ok(Self::Sin),
- "cos" => Ok(Self::Cos),
- "tan" => Ok(Self::Tan),
- "deg" => Ok(Self::Deg),
- "rad" => Ok(Self::Rad),
- _ => Err(ParseFunctionError(s.to_string())),
- }
- }
-}
-
-struct ParseFunctionError(String);
-
enum Constant {
Pi, // Archimedes’ constant (π)
E, // Euler's number (e)