1
0
forked from bonsai/harakit

rpn(1): rewrote parser for the second time

This commit is contained in:
Emma Tebibyte 2024-02-02 15:35:36 -07:00
parent 4cb5e8e2b0
commit fb2a164507
Signed by untrusted user: emma
GPG Key ID: 06FA419A1698C270

View File

@ -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(" ");