rpn(1): code cleanup
This commit is contained in:
		
							parent
							
								
									90ca10990f
								
							
						
					
					
						commit
						34b9519e03
					
				
							
								
								
									
										45
									
								
								src/rpn.rs
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								src/rpn.rs
									
									
									
									
									
								
							@ -69,9 +69,7 @@ enum CalcType {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone)]
 | 
					#[derive(Debug, Clone)]
 | 
				
			||||||
struct EvaluationError {
 | 
					struct EvaluationError { pub message: String }
 | 
				
			||||||
	pub message: String,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl fmt::Display for EvaluationError {
 | 
					impl fmt::Display for EvaluationError {
 | 
				
			||||||
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 | 
						fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 | 
				
			||||||
@ -91,9 +89,7 @@ fn str_to_calc_type(string: &str) -> Option<CalcType> {
 | 
				
			|||||||
		Err(_) => None,
 | 
							Err(_) => None,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if result.is_some() {
 | 
						if result.is_some() { return result; }
 | 
				
			||||||
		return result;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	match string {
 | 
						match string {
 | 
				
			||||||
		"+" => Some(Add),
 | 
							"+" => Some(Add),
 | 
				
			||||||
@ -132,16 +128,20 @@ fn eval(
 | 
				
			|||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		match x {
 | 
							match x {
 | 
				
			||||||
			Add | Divide | Multiply | Power | Subtract | Modulo => {
 | 
					 | 
				
			||||||
				ops.push_back(x)
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			Val(x_) => stack.push_back(x_),
 | 
								Val(x_) => stack.push_back(x_),
 | 
				
			||||||
 | 
								_ => ops.push_back(x),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for op in &ops {
 | 
						for op in &ops {
 | 
				
			||||||
		match op {
 | 
							match op {
 | 
				
			||||||
			Add | Subtract | Multiply | Divide | Power | Modulo => {
 | 
								Val(_) => {
 | 
				
			||||||
 | 
									return Err(EvaluationError {
 | 
				
			||||||
 | 
										message: "Unexpected value in the operator stack."
 | 
				
			||||||
 | 
											.to_string()
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								_ => {
 | 
				
			||||||
				let x = &stack.pop_back().ok_or(EvaluationError {
 | 
									let x = &stack.pop_back().ok_or(EvaluationError {
 | 
				
			||||||
					message: "Stack is empty.".to_string(),
 | 
										message: "Stack is empty.".to_string(),
 | 
				
			||||||
				})?;
 | 
									})?;
 | 
				
			||||||
@ -160,20 +160,13 @@ fn eval(
 | 
				
			|||||||
					_ => &{},
 | 
										_ => &{},
 | 
				
			||||||
				};
 | 
									};
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			Val(_) => {
 | 
					 | 
				
			||||||
				return Err(
 | 
					 | 
				
			||||||
					EvaluationError {
 | 
					 | 
				
			||||||
						message: "Unexpected value in the operator stack."
 | 
					 | 
				
			||||||
							.to_string()
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				)
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Ok(stack)
 | 
						Ok(stack)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Round a float to the given precision level
 | 
				
			||||||
fn round_precise(value: &f64, precision: usize) -> f64 {
 | 
					fn round_precise(value: &f64, precision: usize) -> f64 {
 | 
				
			||||||
	let multiplier = 10_f64.powi(precision as i32);
 | 
						let multiplier = 10_f64.powi(precision as i32);
 | 
				
			||||||
	(value * multiplier).round() / multiplier
 | 
						(value * multiplier).round() / multiplier
 | 
				
			||||||
@ -183,6 +176,8 @@ fn main() -> ExitCode {
 | 
				
			|||||||
	let argv = args().collect::<Vec<String>>();
 | 
						let argv = args().collect::<Vec<String>>();
 | 
				
			||||||
	let mut stack = VecDeque::new();
 | 
						let mut stack = VecDeque::new();
 | 
				
			||||||
	let mut buf = String::new();
 | 
						let mut buf = String::new();
 | 
				
			||||||
 | 
						// Set floating-point precision for correcting rounding errors based on
 | 
				
			||||||
 | 
						// machine epsilon
 | 
				
			||||||
	let precision = (-f64::EPSILON.log10() * PRECISION_MOD).ceil() as usize;
 | 
						let precision = (-f64::EPSILON.log10() * PRECISION_MOD).ceil() as usize;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	if argv.get(1).is_none() {
 | 
						if argv.get(1).is_none() {
 | 
				
			||||||
@ -196,8 +191,7 @@ fn main() -> ExitCode {
 | 
				
			|||||||
						None => break,
 | 
											None => break,
 | 
				
			||||||
					};
 | 
										};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					let precise = round_precise(val, precision);
 | 
										println!("{}", round_precise(val, precision).to_string());
 | 
				
			||||||
					println!("{}", precise.to_string());
 | 
					 | 
				
			||||||
					buf.clear();
 | 
										buf.clear();
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				Err(err) => {
 | 
									Err(err) => {
 | 
				
			||||||
@ -215,7 +209,16 @@ fn main() -> ExitCode {
 | 
				
			|||||||
			.join(" ");
 | 
								.join(" ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		match eval(&input, stack) {
 | 
							match eval(&input, stack) {
 | 
				
			||||||
			Ok(val) => println!("{}", val.iter().last().unwrap().to_string()),
 | 
								Ok(s) => {
 | 
				
			||||||
 | 
									stack = s.clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									let val = match stack.iter().last() {
 | 
				
			||||||
 | 
										Some(v) => v,
 | 
				
			||||||
 | 
										None => return ExitCode::from(0),
 | 
				
			||||||
 | 
									};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									println!("{}", round_precise(val, precision).to_string())
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
			Err(err) => {
 | 
								Err(err) => {
 | 
				
			||||||
				eprintln!("{}: {}", argv[0], err.message);
 | 
									eprintln!("{}: {}", argv[0], err.message);
 | 
				
			||||||
				return ExitCode::from(EX_DATAERR as u8);
 | 
									return ExitCode::from(EX_DATAERR as u8);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user