generated from PlexSheep/baserepo
tokens and terms
This commit is contained in:
parent
34578c0b11
commit
8fc8432bdb
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
//// IMPORTS ///////////////////////////////////////////////////////////////////////////////////////
|
//// IMPORTS ///////////////////////////////////////////////////////////////////////////////////////
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use num_traits;
|
pub use num_traits::PrimInt;
|
||||||
|
|
||||||
//// TYPES /////////////////////////////////////////////////////////////////////////////////////////
|
//// TYPES /////////////////////////////////////////////////////////////////////////////////////////
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
|
@ -25,6 +25,50 @@ pub type Result<T> = std::result::Result<T, Error>;
|
||||||
//// MACROS ////////////////////////////////////////////////////////////////////////////////////////
|
//// MACROS ////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
//// ENUMS /////////////////////////////////////////////////////////////////////////////////////////
|
//// 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,
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
@ -33,15 +77,15 @@ pub enum Error {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum CalculateResult {
|
pub enum Value {
|
||||||
Variable(VarResult),
|
Variable(VarVal),
|
||||||
Numerical(NumericResult),
|
Numerical(NumVal),
|
||||||
Complex(ComplexResult),
|
Complex(ComplVal),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum NumericResult {
|
pub enum NumVal {
|
||||||
Signed(i128),
|
Signed(i128),
|
||||||
Unsigned(u128),
|
Unsigned(u128),
|
||||||
Float(f64)
|
Float(f64)
|
||||||
|
@ -49,61 +93,61 @@ pub enum NumericResult {
|
||||||
|
|
||||||
//// STRUCTS ///////////////////////////////////////////////////////////////////////////////////////
|
//// STRUCTS ///////////////////////////////////////////////////////////////////////////////////////
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct VarResult {
|
pub struct VarVal {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ComplexResult {
|
pub struct ComplVal {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//// IMPLEMENTATION ////////////////////////////////////////////////////////////////////////////////
|
//// IMPLEMENTATION ////////////////////////////////////////////////////////////////////////////////
|
||||||
impl<T: num_traits::PrimInt> From<T> for NumericResult where
|
impl<T: num_traits::PrimInt> From<T> for NumVal where
|
||||||
u128: TryFrom<T>,
|
u128: TryFrom<T>,
|
||||||
u128: TryFrom<T> {
|
u128: TryFrom<T> {
|
||||||
fn from(value: T) -> Self {
|
fn from(value: T) -> Self {
|
||||||
if T::min_value().is_zero() {
|
if T::min_value().is_zero() {
|
||||||
// unsigned data types
|
// unsigned data types
|
||||||
// `u128` is the largest unsigned datatype, any other type will fit.
|
// `u128` is the largest unsigned datatype, any other type will fit.
|
||||||
NumericResult::Unsigned(value.to_u128().unwrap())
|
NumVal::Unsigned(value.to_u128().unwrap())
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// signed data types
|
// signed data types
|
||||||
// `i128` is the largest unsigned datatype, any other type will fit.
|
// `i128` is the largest unsigned datatype, any other type will fit.
|
||||||
NumericResult::Signed(value.to_i128().unwrap())
|
NumVal::Signed(value.to_i128().unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
impl<T: num_traits::PrimInt> From<T> for CalculateResult where
|
impl<T: PrimInt> From<T> for Value where
|
||||||
u128: TryFrom<T>,
|
u128: TryFrom<T>,
|
||||||
u128: TryFrom<T> {
|
u128: TryFrom<T> {
|
||||||
fn from(value: T) -> Self {
|
fn from(value: T) -> Self {
|
||||||
NumericResult::from(value).into()
|
NumVal::from(value).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
impl From<NumericResult> for CalculateResult {
|
impl From<NumVal> for Value {
|
||||||
fn from(value: NumericResult) -> Self {
|
fn from(value: NumVal) -> Self {
|
||||||
CalculateResult::Numerical(value)
|
Value::Numerical(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
impl Display for CalculateResult {
|
impl Display for Value {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
CalculateResult::Numerical(val) => {
|
Value::Numerical(val) => {
|
||||||
write!(f, "{}", val)
|
write!(f, "{}", val)
|
||||||
}
|
}
|
||||||
CalculateResult::Complex(val) => {
|
Value::Complex(val) => {
|
||||||
write!(f, "{}", val)
|
write!(f, "{}", val)
|
||||||
}
|
}
|
||||||
CalculateResult::Variable(val) => {
|
Value::Variable(val) => {
|
||||||
write!(f, "{}", val)
|
write!(f, "{}", val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,16 +155,16 @@ impl Display for CalculateResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
impl Display for NumericResult {
|
impl Display for NumVal {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
NumericResult::Float(val) => {
|
NumVal::Float(val) => {
|
||||||
write!(f, "{val}")
|
write!(f, "{val}")
|
||||||
}
|
}
|
||||||
NumericResult::Signed(val) => {
|
NumVal::Signed(val) => {
|
||||||
write!(f, "{val}")
|
write!(f, "{val}")
|
||||||
}
|
}
|
||||||
NumericResult::Unsigned(val) => {
|
NumVal::Unsigned(val) => {
|
||||||
write!(f, "{val}")
|
write!(f, "{val}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,14 +172,14 @@ impl Display for NumericResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
impl Display for ComplexResult {
|
impl Display for ComplVal {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "")
|
write!(f, "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
impl Display for VarResult {
|
impl Display for VarVal {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "")
|
write!(f, "")
|
||||||
}
|
}
|
|
@ -16,8 +16,8 @@
|
||||||
#![warn(clippy::pedantic)]
|
#![warn(clippy::pedantic)]
|
||||||
|
|
||||||
//// IMPORTS ///////////////////////////////////////////////////////////////////////////////////////
|
//// IMPORTS ///////////////////////////////////////////////////////////////////////////////////////
|
||||||
pub mod result;
|
pub mod base;
|
||||||
pub use result::{Error, Result, CalculateResult};
|
pub use base::{Error, Result, Value};
|
||||||
pub mod term;
|
pub mod term;
|
||||||
pub use term::*;
|
pub use term::*;
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ pub struct Calculator;
|
||||||
//// IMPLEMENTATION ////////////////////////////////////////////////////////////////////////////////
|
//// IMPLEMENTATION ////////////////////////////////////////////////////////////////////////////////
|
||||||
impl Calculator {
|
impl Calculator {
|
||||||
/// Do a single calculation without doing anything else
|
/// Do a single calculation without doing anything else
|
||||||
pub fn oneshot(t: String) -> Result<CalculateResult> {
|
pub fn oneshot(t: String) -> Result<Value> {
|
||||||
trace!(orig=t, "parsing original string to Term");
|
trace!(orig=t, "parsing original string to Term");
|
||||||
let t = Term::new(t)?;
|
let t = Term::new(t)?;
|
||||||
trace!("term has been parsed, starting Calculation");
|
trace!("term has been parsed, starting Calculation");
|
||||||
|
@ -60,7 +60,7 @@ impl Calculator {
|
||||||
/// Calculate 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.
|
/// This method only processes a single term at a time, without caching.
|
||||||
pub fn calc(mut t: Term) -> Result<CalculateResult> {
|
pub fn calc(mut t: Term) -> Result<Value> {
|
||||||
trace!("Calculating term {t:?}");
|
trace!("Calculating term {t:?}");
|
||||||
t.prepare();
|
t.prepare();
|
||||||
t.process();
|
t.process();
|
||||||
|
@ -68,7 +68,7 @@ impl Calculator {
|
||||||
error!("Term was processed but no result was assigned.");
|
error!("Term was processed but no result was assigned.");
|
||||||
return Err(Error::SyntaxError)
|
return Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
return Ok(t.result.unwrap())
|
return t.result.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,8 @@
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
//// IMPORTS ///////////////////////////////////////////////////////////////////////////////////////
|
//// IMPORTS ///////////////////////////////////////////////////////////////////////////////////////
|
||||||
pub use super::{Error, Result, CalculateResult};
|
pub use super::{Error, Result, Value, base::{self, *}};
|
||||||
|
use crate::logger::*;
|
||||||
|
|
||||||
//// TYPES /////////////////////////////////////////////////////////////////////////////////////////
|
//// TYPES /////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -31,49 +32,6 @@ pub use super::{Error, Result, CalculateResult};
|
||||||
//// MACROS ////////////////////////////////////////////////////////////////////////////////////////
|
//// MACROS ////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
//// ENUMS /////////////////////////////////////////////////////////////////////////////////////////
|
//// 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
|
/// ## Parsed value to be calculated
|
||||||
|
@ -86,7 +44,7 @@ enum Token {
|
||||||
Operator(Operator),
|
Operator(Operator),
|
||||||
/// A concrete value that we can calculate something with. May be a constant, integer, float,
|
/// A concrete value that we can calculate something with. May be a constant, integer, float,
|
||||||
/// etc.
|
/// etc.
|
||||||
Value(),
|
Value(super::base::Value),
|
||||||
/// A variable of some kind that will be present in the result
|
/// A variable of some kind that will be present in the result
|
||||||
Variable(char),
|
Variable(char),
|
||||||
}
|
}
|
||||||
|
@ -101,7 +59,7 @@ pub struct Term {
|
||||||
/// the original expression to calculate
|
/// the original expression to calculate
|
||||||
pub original: String,
|
pub original: String,
|
||||||
/// the calculated result, may be of diffrent types, see [`crate::math::calculator::result`].
|
/// the calculated result, may be of diffrent types, see [`crate::math::calculator::result`].
|
||||||
pub result: Option<CalculateResult>,
|
pub result: Option<Result<Value>>,
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
///// internal values following /////
|
///// internal values following /////
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
|
@ -126,16 +84,60 @@ impl Term {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prepare the term for the processing.
|
/// Prepare the term for the processing.
|
||||||
pub fn prepare(&mut self) {
|
pub fn prepare(&mut self) -> Result<()> {
|
||||||
// TODO: shunting yard
|
// TODO: shunting yard
|
||||||
|
|
||||||
|
// Storage for unfinished tokens
|
||||||
|
let mut unfinished_chars: Vec<char> = Vec::new();
|
||||||
|
|
||||||
|
for c in self.original.chars() {
|
||||||
|
// FIXME: this completely ignores shunting yard,
|
||||||
|
// only being on the lookout for values
|
||||||
|
if Self::is_tok(&unfinished_chars) {
|
||||||
|
let tok = Self::to_tok(unfinished_chars)?;
|
||||||
|
// TODO: handle the token, depending on type, precedence and so on
|
||||||
|
self.output_queue.push_front(tok);
|
||||||
|
unfinished_chars = Vec::new();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
unfinished_chars.push(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process(&mut self) {
|
/// Process a prepared term, calculating it's result
|
||||||
|
pub fn process(&mut self) -> Result<()> {
|
||||||
|
debug!("processing term: {:#?}", self);
|
||||||
|
debug!("queue: {:#?}", self.output_queue);
|
||||||
// TODO: process RPN and set result
|
// TODO: process RPN and set result
|
||||||
self.result = Some(CalculateResult::Numerical(19.into()))
|
self.result = Some(Ok(19.into()));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a character into a token
|
||||||
|
///
|
||||||
|
/// Returns: A tuple with a [`Token`] and a [`bool`]. If the bool is false, the [`Token`] is
|
||||||
|
/// marked as "incomplete", meaning that the character cannot be used yet.
|
||||||
|
fn to_tok(s: Vec<char>) -> Result<Token> {
|
||||||
|
Ok(19.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_tok(s: &Vec<char>) -> bool {
|
||||||
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
impl<T> From<T> for Token where
|
||||||
|
T: Into<Value>,
|
||||||
|
T: PrimInt,
|
||||||
|
u128: TryFrom<T>
|
||||||
|
{
|
||||||
|
fn from(value: T) -> Self {
|
||||||
|
Token::Value(base::Value::from(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//// PUBLIC FUNCTIONS //////////////////////////////////////////////////////////////////////////////
|
//// PUBLIC FUNCTIONS //////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
Reference in New Issue