diff --git a/src/math/calculator/mod.rs b/src/math/calculator/mod.rs index bb6d3c1..9be83bf 100644 --- a/src/math/calculator/mod.rs +++ b/src/math/calculator/mod.rs @@ -18,6 +18,8 @@ //// IMPORTS /////////////////////////////////////////////////////////////////////////////////////// pub mod result; pub use result::{Error, Result, CalculateResult}; +pub mod term; +pub use term::*; #[allow(unused_imports)] // we possibly want to use all log levels use crate::logger::{trace, debug, info, warn, error}; @@ -31,74 +33,21 @@ use crate::logger::{trace, debug, info, warn, error}; //// MACROS //////////////////////////////////////////////////////////////////////////////////////// //// ENUMS ///////////////////////////////////////////////////////////////////////////////////////// -// #[non_exhaustive] -// #[derive(Debug)] -// pub enum Constants { -// Pi -// } - -//////////////////////////////////////////////////////////////////////////////////////////////////// -#[non_exhaustive] -#[derive(Debug)] -/// ## Supported Operations -/// -/// This `enum` contains all operations supported in this module. -pub enum Operations { - /// Mathmatical addition - Addition, - /// Mathmatical subtraction - Subtraction, - /// Mathmatical multiplication - Multiplication, - /// Mathmatical division - Division, - /// Mathmatical modulo, finite field arithmetic - Modulo, - /// Any function, seel [`Function`] - Function(Function) - -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -/// ## Supported Functions -/// -/// This `enum` contains all functions supported in this module. -/// -/// A function has a name followed by braces directly afterwards. -/// A function may have 0 to 31 Arguments. -/// -/// Example: `sqrt(19)`, `floor(19.9)` -#[non_exhaustive] -#[derive(Debug)] -pub enum Function { - /// Draw the mathmatical root, attribute n is the nth root - Root(u16), - /// round up - Floor, - /// round down - Ceil, - /// round to nearest integer - /// (commercial rounding) - Round, -} //// STRUCTS /////////////////////////////////////////////////////////////////////////////////////// -/// ## A Calculator object +/// ## A Calculator struct +/// +/// This struct does not do anything at the moment, but aims to be the target for high level +/// control. Instead of using the [`Calculator`], you could just use the [`Term`] struct for +/// lower level control. pub struct Calculator; -//////////////////////////////////////////////////////////////////////////////////////////////////// -#[derive(Debug)] -pub struct Term { - original: String, - result: Option, - parts: Vec -} - //// IMPLEMENTATION //////////////////////////////////////////////////////////////////////////////// impl Calculator { + /// Do a single calculation without doing anything else pub fn oneshot(t: String) -> Result { trace!(orig=t, "parsing original string to Term"); - let mut t = Term::new(t); + let t = Term::new(t)?; trace!("term has been parsed, starting Calculation"); debug!("parsed term: {t:#?}"); Self::calc(t) @@ -106,24 +55,20 @@ impl Calculator { /// ## Calculate a [`Term`] /// - /// This method makes use of the + /// This method makes use of the /// [shunting yard algorithm](https://en.wikipedia.org/wiki/Shunting_yard_algorithm) to /// Calculate the final value of any term. /// /// This method only processes a single term at a time, without caching. pub fn calc(mut t: Term) -> Result { trace!("Calculating term {t:?}"); - return Ok(CalculateResult::from(0)) - } -} - -impl Term { - pub fn new(orig: String) -> Self { - Term { - original: orig, - result: None, - parts: Vec::new() + t.prepare(); + t.process(); + if t.result.is_none() { + error!("Term was processed but no result was assigned."); + return Err(Error::SyntaxError) } + return Ok(t.result.unwrap()) } } diff --git a/src/math/calculator/term.rs b/src/math/calculator/term.rs index 6bcdf95..d776f0f 100644 --- a/src/math/calculator/term.rs +++ b/src/math/calculator/term.rs @@ -17,7 +17,10 @@ // enable clippy's extra lints, the pedantic version #![warn(clippy::pedantic)] +use std::collections::VecDeque; + //// IMPORTS /////////////////////////////////////////////////////////////////////////////////////// +pub use super::{Error, Result, CalculateResult}; //// TYPES ///////////////////////////////////////////////////////////////////////////////////////// @@ -28,10 +31,111 @@ //// MACROS //////////////////////////////////////////////////////////////////////////////////////// //// ENUMS ///////////////////////////////////////////////////////////////////////////////////////// +/// ## Supported Operations +/// +/// This `enum` contains all operations supported in this module. +#[non_exhaustive] +#[derive(Debug)] +pub enum Operator { + /// Mathmatical addition + Addition, + /// Mathmatical subtraction + Subtraction, + /// Mathmatical multiplication + Multiplication, + /// Mathmatical division + Division, + /// Mathmatical modulo, finite field arithmetic + Modulo, + /// Any function, seel [`Function`] + Function(Function) +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// ## Supported Functions +/// +/// This `enum` contains all functions supported in this module. +/// +/// A function has a name followed by braces directly afterwards. +/// A function may have 0 to 31 Arguments. +/// +/// Example: `sqrt(19)`, `floor(19.9)` +#[non_exhaustive] +#[derive(Debug)] +pub enum Function { + /// Draw the mathmatical root, attribute n is the nth root + Root(u16), + /// round up + Floor, + /// round down + Ceil, + /// round to nearest integer + /// (commercial rounding) + Round, +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// ## Parsed value to be calculated +/// +/// This enum represents anything that goes to the output queue of [`Term::prepare()`] and will +/// then be used to actually calculate something in [`Term::process()`]. +#[derive(Debug)] +enum Token { + /// Some kind of operator + Operator(Operator), + /// A concrete value that we can calculate something with. May be a constant, integer, float, + /// etc. + Value(), + /// A variable of some kind that will be present in the result + Variable(char), +} //// STRUCTS /////////////////////////////////////////////////////////////////////////////////////// +/// ## Term that can be calculated +/// +/// Represents a signular term, that can be calculated. Terms will be evaluated by the [`Term::prepare`] +/// function, afterwards calculated (as much as possible) in the [`Term::process`] function. +/// +#[derive(Debug)] +pub struct Term { + /// the original expression to calculate + pub original: String, + /// the calculated result, may be of diffrent types, see [`crate::math::calculator::result`]. + pub result: Option, + ///////////////////////////////////// + ///// internal values following ///// + ///////////////////////////////////// + operator_stack: Vec, + output_queue: VecDeque +} //// IMPLEMENTATION //////////////////////////////////////////////////////////////////////////////// +impl Term { + /// Build a new term from an expression + /// + /// Invalid terms will result in an [`Err`]. + pub fn new(orig: String) -> Result { + return Ok( + Term { + original: orig, + result: None, + operator_stack: Vec::new(), + output_queue: VecDeque::new() + } + ) + } + + /// Prepare the term for the processing. + pub fn prepare(&mut self) { + // TODO: shunting yard + } + + pub fn process(&mut self) { + // TODO: process RPN and set result + self.result = Some(CalculateResult::Numerical(19.into())) + } +} + //// PUBLIC FUNCTIONS //////////////////////////////////////////////////////////////////////////////