rpn(1): made evaluation function more readable
This commit is contained in:
parent
f50bfeea92
commit
731e62ee7e
49
src/rpn.rs
49
src/rpn.rs
@ -138,6 +138,33 @@ fn err<T: StrError>(argv0: &String, e: &T, code: Option<u8>) -> ExitCode {
|
||||
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(
|
||||
input: &str,
|
||||
initial_stack: VecDeque<f64>,
|
||||
@ -170,27 +197,9 @@ fn eval(
|
||||
},
|
||||
op => {
|
||||
ops.push_back(op.clone());
|
||||
|
||||
oper = true; /* this is an operation */
|
||||
|
||||
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,
|
||||
})
|
||||
}
|
||||
return operate(stack, op).map(|s| (s, oper));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user