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>
|
||||
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(
|
||||
&mut self,
|
||||
val: impl TryInto<Decimal<DSIZE, EXP>, Error: Into<StackCalcError>>,
|
||||
) -> Result<(), StackCalcError> {
|
||||
if self.index == STACK {
|
||||
if self.is_full() {
|
||||
return Err(StackCalcError::StackOverflow);
|
||||
}
|
||||
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> {
|
||||
if self.index == 0 {
|
||||
if self.is_empty() {
|
||||
return Err(StackCalcError::StackUnderflow);
|
||||
}
|
||||
self.index -= 1;
|
||||
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 b = self.pop()?;
|
||||
let a = a.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)?;
|
||||
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)]
|
||||
@@ -103,8 +154,13 @@ mod tests {
|
||||
calc.push(3.0).unwrap_err(),
|
||||
StackCalcError::StackOverflow
|
||||
));
|
||||
assert_eq!(calc.add()?, Decimal::try_from(5.0)?);
|
||||
assert_eq!(calc.add()?, Decimal::try_from(1337.42 * 2.0 + 5.0)?);
|
||||
calc.add()?;
|
||||
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!(
|
||||
calc.add().unwrap_err(),
|
||||
StackCalcError::StackUnderflow
|
||||
|
||||
Reference in New Issue
Block a user