Skip to content

Instantly share code, notes, and snippets.

@pollyzoid
Created February 22, 2017 20:45
Show Gist options
  • Save pollyzoid/6a93e62120994e33287193c276da7091 to your computer and use it in GitHub Desktop.
Save pollyzoid/6a93e62120994e33287193c276da7091 to your computer and use it in GitHub Desktop.
fn execute(tokens: Vec<Token>) -> Result<f64, String> {
use Token::*;
let mut stack = Vec::<f64>::new();
for token in tokens {
match token {
Number(val) => {
stack.push(val);
}
Identifier(ref op) => {
// First, check constants, then functions
match CONSTS.get(op) {
Some(&val) => {
stack.push(val);
}
None => {
match OPERATORS.get(op) {
Some(&Operator::Binary(cb)) => {
if stack.len() < 2 {
return Err("not enough operands, expected 2".into());
}
let val2 = stack.pop().unwrap();
let val1 = stack.pop().unwrap();
stack.push(cb(val1, val2));
}
Some(&Operator::Unary(cb)) => {
if stack.len() < 1 {
return Err("not enough operands, expected 1".into());
}
let val1 = stack.pop().unwrap();
stack.push(cb(val1));
}
None => {
return Err(format!("invalid operator {}", op));
}
}
}
}
}
}
}
match stack.len() {
0 => Err("empty expression".into()),
1 => Ok(stack.pop().unwrap()),
_ => Err("too many operands".into())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment