rpn(1): made evaluation function more readable

This commit is contained in:
Emma Tebibyte 2024-08-28 18:24:49 -06:00
parent f50bfeea92
commit 731e62ee7e
Signed by: emma
GPG Key ID: 06FA419A1698C270

View File

@ -138,6 +138,33 @@ fn err<T: StrError>(argv0: &String, e: &T, code: Option<u8>) -> ExitCode {
ExitCode::from(code.unwrap_or(1 /* unknown error */)) ExitCode::from(code.unwrap_or(1 /* unknown error */))
} }
fn operate(
mut stack: VecDeque<f64>,
op: CalcType,
) -> Result<VecDeque<f64>, EvaluationError> {
let vals = (stack.pop_back(), stack.pop_back());
if let (Some(x), Some(y)) = vals {
match op {
Add => stack.push_back(y + x),
Subtract => stack.push_back(y - x),
Multiply => stack.push_back(y * x),
Divide => stack.push_back(y / x),
Power => stack.push_back(y.powf(x)),
Floor => stack.push_back((y / x).floor()),
Modulo => stack.push_back(y % x),
_ => {},
};
} else {
return Err(EvaluationError {
message: format!("{}: unexpected operation", op),
code: EX_DATAERR,
})
}
Ok(stack)
}
fn eval( fn eval(
input: &str, input: &str,
initial_stack: VecDeque<f64>, initial_stack: VecDeque<f64>,
@ -170,27 +197,9 @@ fn eval(
}, },
op => { op => {
ops.push_back(op.clone()); ops.push_back(op.clone());
oper = true; /* this is an operation */ oper = true; /* this is an operation */
return operate(stack, op).map(|s| (s, oper));
let vals = (stack.pop_back(), stack.pop_back());
if let (Some(x), Some(y)) = vals {
match op {
Add => stack.push_back(y + x),
Subtract => stack.push_back(y - x),
Multiply => stack.push_back(y * x),
Divide => stack.push_back(y / x),
Power => stack.push_back(y.powf(x)),
Floor => stack.push_back((y / x).floor()),
Modulo => stack.push_back(y % x),
_ => {},
};
} else {
return Err(EvaluationError {
message: format!("{}: unexpected operation", op),
code: EX_DATAERR,
})
}
}, },
}; };
} }