calc accessors and reset
This commit is contained in:
68
src/calc.rs
68
src/calc.rs
@@ -55,11 +55,38 @@ impl From<Infallible> for StackCalcError {
|
|||||||
impl<F: FloatCore, const STACK: usize, const DSIZE: usize, EXP: PrimInt + Unsigned>
|
impl<F: FloatCore, const STACK: usize, const DSIZE: usize, EXP: PrimInt + Unsigned>
|
||||||
StackCalc<F, STACK, DSIZE, EXP>
|
StackCalc<F, STACK, DSIZE, EXP>
|
||||||
{
|
{
|
||||||
|
pub fn is_full(&self) -> bool {
|
||||||
|
self.index == STACK
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.index == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.index
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset(&mut self) {
|
||||||
|
self.index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn last(&self) -> Option<Decimal<DSIZE, EXP>> {
|
||||||
|
if self.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(self.stack[self.index - 1])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> impl Iterator<Item = &Decimal<DSIZE, EXP>> {
|
||||||
|
self.stack.iter().take(self.index)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn push(
|
pub fn push(
|
||||||
&mut self,
|
&mut self,
|
||||||
val: impl TryInto<Decimal<DSIZE, EXP>, Error: Into<StackCalcError>>,
|
val: impl TryInto<Decimal<DSIZE, EXP>, Error: Into<StackCalcError>>,
|
||||||
) -> Result<(), StackCalcError> {
|
) -> Result<(), StackCalcError> {
|
||||||
if self.index == STACK {
|
if self.is_full() {
|
||||||
return Err(StackCalcError::StackOverflow);
|
return Err(StackCalcError::StackOverflow);
|
||||||
}
|
}
|
||||||
self.stack[self.index] = val.try_into().map_err(Into::into)?;
|
self.stack[self.index] = val.try_into().map_err(Into::into)?;
|
||||||
@@ -68,22 +95,46 @@ impl<F: FloatCore, const STACK: usize, const DSIZE: usize, EXP: PrimInt + Unsign
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop(&mut self) -> Result<Decimal<DSIZE, EXP>, StackCalcError> {
|
pub fn pop(&mut self) -> Result<Decimal<DSIZE, EXP>, StackCalcError> {
|
||||||
if self.index == 0 {
|
if self.is_empty() {
|
||||||
return Err(StackCalcError::StackUnderflow);
|
return Err(StackCalcError::StackUnderflow);
|
||||||
}
|
}
|
||||||
self.index -= 1;
|
self.index -= 1;
|
||||||
Ok(self.stack[self.index])
|
Ok(self.stack[self.index])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(&mut self) -> Result<Decimal<DSIZE, EXP>, StackCalcError> {
|
fn pop_pair_float(&mut self) -> Result<(F, F), StackCalcError> {
|
||||||
let a = self.pop()?;
|
let a = self.pop()?;
|
||||||
let b = self.pop()?;
|
let b = self.pop()?;
|
||||||
let a = a.to_float::<F>()?;
|
let a = a.to_float::<F>()?;
|
||||||
let b = b.to_float::<F>()?;
|
let b = b.to_float::<F>()?;
|
||||||
let res = Decimal::from_float(a + b)?;
|
Ok((a, b))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calc_pair_float(
|
||||||
|
&mut self,
|
||||||
|
f: impl FnOnce(F, F) -> Result<F, StackCalcError>,
|
||||||
|
) -> Result<Decimal<DSIZE, EXP>, StackCalcError> {
|
||||||
|
let (a, b) = self.pop_pair_float()?;
|
||||||
|
let res = Decimal::from_float(f(a, b)?)?;
|
||||||
self.push(res)?;
|
self.push(res)?;
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add(&mut self) -> Result<Decimal<DSIZE, EXP>, StackCalcError> {
|
||||||
|
self.calc_pair_float(|a, b| Ok(b + a))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sub(&mut self) -> Result<Decimal<DSIZE, EXP>, StackCalcError> {
|
||||||
|
self.calc_pair_float(|a, b| Ok(b - a))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mul(&mut self) -> Result<Decimal<DSIZE, EXP>, StackCalcError> {
|
||||||
|
self.calc_pair_float(|a, b| Ok(b * a))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn div(&mut self) -> Result<Decimal<DSIZE, EXP>, StackCalcError> {
|
||||||
|
self.calc_pair_float(|a, b| Ok(b / a))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -103,8 +154,13 @@ mod tests {
|
|||||||
calc.push(3.0).unwrap_err(),
|
calc.push(3.0).unwrap_err(),
|
||||||
StackCalcError::StackOverflow
|
StackCalcError::StackOverflow
|
||||||
));
|
));
|
||||||
assert_eq!(calc.add()?, Decimal::try_from(5.0)?);
|
calc.add()?;
|
||||||
assert_eq!(calc.add()?, Decimal::try_from(1337.42 * 2.0 + 5.0)?);
|
assert_eq!(calc.last().unwrap(), Decimal::try_from(5.0)?);
|
||||||
|
calc.add()?;
|
||||||
|
assert_eq!(
|
||||||
|
calc.last().unwrap(),
|
||||||
|
Decimal::try_from(1337.42 * 2.0 + 5.0)?
|
||||||
|
);
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
calc.add().unwrap_err(),
|
calc.add().unwrap_err(),
|
||||||
StackCalcError::StackUnderflow
|
StackCalcError::StackUnderflow
|
||||||
|
|||||||
Reference in New Issue
Block a user