Skip to content

Instantly share code, notes, and snippets.

@corruptmem
Created November 21, 2014 14:56
Show Gist options
  • Save corruptmem/5fe7761b59321e3c3e8f to your computer and use it in GitHub Desktop.
Save corruptmem/5fe7761b59321e3c3e8f to your computer and use it in GitHub Desktop.
use std::io;
mod rpn {
pub struct Calculator {
stack: Vec<int>,
}
enum Token<'a> {
Number(int),
Plus,
Subtract,
Multiply,
Divide,
Unknown(&'a str)
}
impl Calculator {
pub fn new() -> Calculator {
Calculator {
stack: Vec::new()
}
}
pub fn push_input(&mut self, input: &str) -> Result<Option<int>, String> {
match parse_input(input) {
Token::Plus => self.execute_operator(add),
Token::Subtract => self.execute_operator(sub),
Token::Divide => self.execute_operator(div),
Token::Multiply => self.execute_operator(mul),
Number(x) => self.push_number(x),
Unknown(s) => Err(format!("didn't understand: {}", s)),
}
}
fn push_number(&mut self, input: int) -> Result<Option<int>, String> {
self.stack.push(input);
Ok(None)
}
fn execute_operator(&mut self, f: |int, int| -> int) -> Result<Option<int>, String> {
if self.stack.len() < 2 {
Err("must be at least two items on the stack!".to_string())
} else {
let b = self.stack.pop().unwrap();
let a = self.stack.pop().unwrap();
let result = f(a, b);
self.stack.push(result);
Ok(Some(result))
}
}
}
fn add(a: int, b: int) -> int { a + b }
fn sub(a: int, b: int) -> int { a - b }
fn mul(a: int, b: int) -> int { a * b }
fn div(a: int, b: int) -> int { a / b }
fn parse_input(input: &str) -> Token {
match input {
"+" => Token::Plus,
"*" => Token::Multiply,
"/" => Token::Divide,
"-" => Token::Subtract,
_ => match from_str::<int>(input) {
Some(x) => Token::Number(x),
None => Token::Unknown(input)
}
}
}
}
fn main() {
let mut calc = rpn::Calculator::new();
loop {
io::print("> ");
let line = io::stdin().read_line().ok().expect("failed to read line");
let line_s = line.as_slice().trim();
if line_s == "exit" || line_s == "quit" {
break
}
match calc.push_input(line_s) {
Ok(val) => match val {
Some(val) => println!("{}", val),
None => ()
},
Err(msg) => println!("Error: {}", msg)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment