forked from bonsai/harakit
		
	rpn(1): rewrote parser for the second time
This commit is contained in:
		
							parent
							
								
									4cb5e8e2b0
								
							
						
					
					
						commit
						fb2a164507
					
				
							
								
								
									
										83
									
								
								src/rpn.rs
									
									
									
									
									
								
							
							
						
						
									
										83
									
								
								src/rpn.rs
									
									
									
									
									
								
							| @ -67,7 +67,7 @@ enum CalcType { | ||||
| 	Floor, | ||||
| 	Modulo, | ||||
| 	Val(f64), | ||||
| 	Empty, | ||||
| 	Invalid, | ||||
| } | ||||
| 
 | ||||
| impl From<&str> for CalcType { | ||||
| @ -83,7 +83,7 @@ impl From<&str> for CalcType { | ||||
| 			_ => { | ||||
| 				match value.parse::<f64>() { | ||||
| 					Ok(x) => Val(x), | ||||
| 					Err(_) => Empty, | ||||
| 					Err(_) => Invalid, | ||||
| 				} | ||||
| 			}, | ||||
| 		} | ||||
| @ -104,7 +104,7 @@ impl Display for CalcType { | ||||
| 			Val(x) => { | ||||
| 				y = x.to_string(); &y | ||||
| 			}, | ||||
| 			Empty => "", | ||||
| 			Invalid => "", | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @ -122,6 +122,7 @@ impl Display for EvaluationError { | ||||
| // repeating and it seems this can give it to me
 | ||||
| const PRECISION_MOD: f64 = 0.9 + f64::EPSILON * 100.0; | ||||
| 
 | ||||
| 
 | ||||
| fn eval( | ||||
| 	input: &str, | ||||
| 	initial_stack: VecDeque<f64>, | ||||
| @ -135,64 +136,45 @@ fn eval( | ||||
| 	} | ||||
| 
 | ||||
| 	// Split the input into tokens.
 | ||||
| 	let toks = input.split(' ').collect::<Vec<&str>>(); | ||||
| 	let mut toks: VecDeque<CalcType> = input | ||||
| 		.split(' ') | ||||
| 		.map(|t| CalcType::from(t)) | ||||
| 		.collect(); | ||||
| 	let mut ops: VecDeque<CalcType> = VecDeque::new(); | ||||
| 
 | ||||
| 	for tok in toks { | ||||
| 		let x: CalcType = match CalcType::from(tok) { | ||||
| 			Empty => { | ||||
| 	while let Some(n) = toks.pop_back() { | ||||
| 		match n { | ||||
| 			Val(v) => stack.push_back(v), | ||||
| 			Invalid => { | ||||
| 				return Err(EvaluationError { | ||||
| 					message: format!("{}: Invalid token", tok), | ||||
| 					message: format!("{}: Invalid token", n) | ||||
| 				}) | ||||
| 			}, | ||||
| 			x => x, | ||||
| 		}; | ||||
| 			op => { | ||||
| 				ops.push_back(op); | ||||
| 				oper = true; | ||||
| 
 | ||||
| 		match x { | ||||
| 			Val(v) => stack.push_back(v), | ||||
| 			_ => ops.push_back(x), | ||||
| 		} | ||||
| 	} | ||||
| 				let vals = ( | ||||
| 					stack.pop_back(), | ||||
| 					stack.pop_back(), | ||||
| 				); | ||||
| 
 | ||||
| 	for op in &ops { | ||||
| 		match op { | ||||
| 			Val(_) => { | ||||
| 				return Err(EvaluationError { message: format!( | ||||
| 					"{}: Unexpected value in the operator stack.", | ||||
| 					op, | ||||
| 				)}); | ||||
| 			}, | ||||
| 			_ => { | ||||
| 
 | ||||
| 				if stack.len() < 2 { | ||||
| 				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(x.powf(y)), | ||||
| 						Floor => stack.push_back((y / x).floor()), | ||||
| 						Modulo => stack.push_back(y % x), | ||||
| 						_ => {}, | ||||
| 					}; | ||||
| 				} else { | ||||
| 					return Err(EvaluationError { | ||||
| 						message: format!("{}: Unexpected operation.", op) | ||||
| 					}) | ||||
| 				} | ||||
| 
 | ||||
| 				if stack.len() > ops.len() + 1 { | ||||
| 					return Err( | ||||
| 						EvaluationError { message: format!("Syntax error.")} | ||||
| 					); | ||||
| 				} | ||||
| 
 | ||||
| 				oper = true; | ||||
| 
 | ||||
| 				let (x, y) = ( | ||||
| 					stack.pop_back().unwrap(), | ||||
| 					stack.pop_back().unwrap(), | ||||
| 				); | ||||
| 
 | ||||
| 				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(x.powf(y)), | ||||
| 					Floor => stack.push_back((y / x).floor()), | ||||
| 					Modulo => stack.push_back(y % x), | ||||
| 					_ => {}, | ||||
| 				}; | ||||
| 			}, | ||||
| 		}; | ||||
| 	} | ||||
| @ -240,6 +222,7 @@ fn main() -> ExitCode { | ||||
| 		let input = argv | ||||
| 			.iter() | ||||
| 			.skip(1) | ||||
| 			.rev() | ||||
| 			.map(|x| x.to_owned()) | ||||
| 			.collect::<Vec<String>>() | ||||
| 			.join(" "); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user