Compare commits

...

2 commits

Author SHA1 Message Date
34578c0b11 terms module design 2023-09-12 21:08:18 +02:00
1e176814e9 rename computer to calculator 2023-09-12 20:45:34 +02:00
6 changed files with 194 additions and 132 deletions

View file

@ -1,6 +1,6 @@
//! # Executable for the math/compute submodule
//!
//! Compute computations with your computer!
//! Calculate Calculations with your Computer!
//!
//! This command line tool allows you to input a mathematical expression. It will then process the
//! expression.
@ -15,7 +15,7 @@
#![warn(clippy::pedantic)]
//// IMPORTS ///////////////////////////////////////////////////////////////////////////////////////
use pt::math::computer::{*, self};
use pt::math::calculator::{*, self};
use pt::logger::*;
use clap::{Parser, Subcommand};
@ -29,7 +29,7 @@ use std::path::PathBuf;
//// CONSTANTS /////////////////////////////////////////////////////////////////////////////////////
/// short about section displayed in help
const ABOUT_ROOT: &'static str = r##"
Compute computations with your computer
Calculate Calculations with your Computer
This commandline tool allows you to calculate complex mathematical expressions right in your
shell.
@ -128,7 +128,7 @@ fn main() {
}
debug!("exporssion: {}", expr);
let r = Computer::oneshot(expr);
let r = Calculator::oneshot(expr);
println!("{}", r.unwrap());
}
////////////////////////////////////////////////////////////////////////////////////////////////////

View file

@ -1,8 +1,8 @@
//! # Compute expressions
//! # Calculate expressions
//!
//! Compute computations with your computer (`ccc`)
//! Calculate Calculations with your Calculator (`ccc`)
//!
//! This modules aim is to take a term of any kind ([String]) and compute it's value, be it
//! This modules aim is to take a term of any kind ([String]) and calculate it's value, be it
//! variable based or a concrete numerical value. It implements different operators and
//! (mathematical) functions.
@ -17,8 +17,11 @@
//// IMPORTS ///////////////////////////////////////////////////////////////////////////////////////
pub mod result;
pub use result::{Error, Result, ComputeResult};
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};
//// TYPES /////////////////////////////////////////////////////////////////////////////////////////
@ -30,87 +33,42 @@ 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,
/// 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
}
////////////////////////////////////////////////////////////////////////////////////////////////////
#[non_exhaustive]
pub enum Functions {
Root
}
//// STRUCTS ///////////////////////////////////////////////////////////////////////////////////////
pub struct Computer;
////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Debug)]
pub struct Term {
original: String,
result: Option<ComputeResult>,
parts: Vec<String>
}
/// ## 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;
//// IMPLEMENTATION ////////////////////////////////////////////////////////////////////////////////
impl Computer {
pub fn oneshot(t: String) -> Result<ComputeResult> {
impl Calculator {
/// Do a single calculation without doing anything else
pub fn oneshot(t: String) -> Result<CalculateResult> {
trace!(orig=t, "parsing original string to Term");
let mut t = Term::new(t);
trace!("term has been parsed, starting computation");
let t = Term::new(t)?;
trace!("term has been parsed, starting Calculation");
debug!("parsed term: {t:#?}");
Self::compute(t)
Self::calc(t)
}
/// ## compute a [`Term`]
/// ## Calculate a [`Term`]
///
/// This method makes use of the
/// [shunting yard algorithm](https://en.wikipedia.org/wiki/Shunting_yard_algorithm) to
/// compute the final value of any term.
/// Calculate the final value of any term.
///
/// This method only processes a single term at a time, without caching.
pub fn compute(mut t: Term) -> Result<ComputeResult> {
trace!("computing term {t:?}");
return Ok(ComputeResult::from(0))
}
}
impl Term {
pub fn new(orig: String) -> Self {
Term {
original: orig,
result: None,
parts: Vec::new()
pub fn calc(mut t: Term) -> Result<CalculateResult> {
trace!("Calculating term {t:?}");
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())
}
}

View file

@ -1,4 +1,4 @@
//! # Results and Errors for the compute module
//! # Results and Errors for the calculate module
//!
//! This module defines the errors and results that can be processed from any given term.
@ -33,7 +33,7 @@ pub enum Error {
////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Debug)]
pub enum ComputeResult {
pub enum CalculateResult {
Variable(VarResult),
Numerical(NumericResult),
Complex(ComplexResult),
@ -78,7 +78,7 @@ impl<T: num_traits::PrimInt> From<T> for NumericResult where
}
////////////////////////////////////////////////////////////////////////////////////////////////////
impl<T: num_traits::PrimInt> From<T> for ComputeResult where
impl<T: num_traits::PrimInt> From<T> for CalculateResult where
u128: TryFrom<T>,
u128: TryFrom<T> {
fn from(value: T) -> Self {
@ -87,23 +87,23 @@ impl<T: num_traits::PrimInt> From<T> for ComputeResult where
}
////////////////////////////////////////////////////////////////////////////////////////////////////
impl From<NumericResult> for ComputeResult {
impl From<NumericResult> for CalculateResult {
fn from(value: NumericResult) -> Self {
ComputeResult::Numerical(value)
CalculateResult::Numerical(value)
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
impl Display for ComputeResult {
impl Display for CalculateResult {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ComputeResult::Numerical(val) => {
CalculateResult::Numerical(val) => {
write!(f, "{}", val)
}
ComputeResult::Complex(val) => {
CalculateResult::Complex(val) => {
write!(f, "{}", val)
}
ComputeResult::Variable(val) => {
CalculateResult::Variable(val) => {
write!(f, "{}", val)
}
}

144
src/math/calculator/term.rs Normal file
View file

@ -0,0 +1,144 @@
//! # A term that can be the input for calculation
//!
//! Short description
//!
//! Details
//!
//! ## Section 1
//!
//! ## Section 2
//// ATTRIBUTES ////////////////////////////////////////////////////////////////////////////////////
// we want docs
#![warn(missing_docs)]
#![warn(rustdoc::missing_crate_level_docs)]
// we want Debug everywhere.
#![warn(missing_debug_implementations)]
// enable clippy's extra lints, the pedantic version
#![warn(clippy::pedantic)]
use std::collections::VecDeque;
//// IMPORTS ///////////////////////////////////////////////////////////////////////////////////////
pub use super::{Error, Result, CalculateResult};
//// TYPES /////////////////////////////////////////////////////////////////////////////////////////
//// CONSTANTS /////////////////////////////////////////////////////////////////////////////////////
//// STATICS ///////////////////////////////////////////////////////////////////////////////////////
//// 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<CalculateResult>,
/////////////////////////////////////
///// internal values following /////
/////////////////////////////////////
operator_stack: Vec<Operator>,
output_queue: VecDeque<Token>
}
//// IMPLEMENTATION ////////////////////////////////////////////////////////////////////////////////
impl Term {
/// Build a new term from an expression
///
/// Invalid terms will result in an [`Err`].
pub fn new(orig: String) -> Result<Term> {
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 //////////////////////////////////////////////////////////////////////////////
//// PRIVATE FUNCTIONS /////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

View file

@ -1,40 +0,0 @@
//! # A term that can be the input for computation
//!
//! Short description
//!
//! Details
//!
//! ## Section 1
//!
//! ## Section 2
//// ATTRIBUTES ////////////////////////////////////////////////////////////////////////////////////
// we want docs
#![warn(missing_docs)]
#![warn(rustdoc::missing_crate_level_docs)]
// we want Debug everywhere.
#![warn(missing_debug_implementations)]
// enable clippy's extra lints, the pedantic version
#![warn(clippy::pedantic)]
//// IMPORTS ///////////////////////////////////////////////////////////////////////////////////////
//// TYPES /////////////////////////////////////////////////////////////////////////////////////////
//// CONSTANTS /////////////////////////////////////////////////////////////////////////////////////
//// STATICS ///////////////////////////////////////////////////////////////////////////////////////
//// MACROS ////////////////////////////////////////////////////////////////////////////////////////
//// ENUMS /////////////////////////////////////////////////////////////////////////////////////////
//// STRUCTS ///////////////////////////////////////////////////////////////////////////////////////
//// IMPLEMENTATION ////////////////////////////////////////////////////////////////////////////////
//// PUBLIC FUNCTIONS //////////////////////////////////////////////////////////////////////////////
//// PRIVATE FUNCTIONS /////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

View file

@ -18,7 +18,7 @@
#![warn(clippy::pedantic)]
//// IMPORTS ///////////////////////////////////////////////////////////////////////////////////////
pub mod computer;
pub mod calculator;
//// TYPES /////////////////////////////////////////////////////////////////////////////////////////