From e4a077e175eee58516c7335c97f4985d26138e61 Mon Sep 17 00:00:00 2001 From: NerdyPepper Date: Tue, 19 Mar 2019 22:46:36 +0530 Subject: add postfix eval fn, more lexing features --- src/main.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index 66faaee..78a05b0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,11 +31,14 @@ impl Operator { } fn main() { - let input = "1 + 2 * 3"; + let input = "1 + 5 * 6 + 2"; + println!("{}", input); let input = input.replace(" ", ""); let lexed = lexer(&input); let postfixed = to_postfix(lexed.unwrap()); - println!("{:?}", postfixed); + let evaled = eval_postfix(postfixed.unwrap()); + + println!("{:?}", evaled); } fn lexer(input: &str) -> Result, String> { @@ -72,6 +75,14 @@ fn lexer(input: &str) -> Result, String> { result.push(Operator::token_from_op('*', |x, y| x * y, 3, true)); num_vec.clear(); } + if let Some(x) = result.last() { + match x { + Token::RParen => { + result.push(Operator::token_from_op('*', |x, y| x * y, 3, true)); + }, + _ => {} + }; + } // finish result.push(Token::LParen); }, @@ -106,20 +117,18 @@ fn to_postfix(tokens: Vec) -> Result, String> { match token { Token::Num(_) => { postfixed.push(token); - println!("pushed a number {:?}", token); }, Token::Operator(current_op) => { while let Some(top_op) = op_stack.last() { match top_op { Token::LParen => { - return Err(format!("Mismatched Parentheses!")) + break; } Token::Operator(top_op) => { let tp = top_op.precedence; let cp = current_op.precedence; if tp > cp || (tp == cp && top_op.is_left_associative) { postfixed.push(op_stack.pop().unwrap()); - println!("pushed an operator special {:?}", token); } else { break; } @@ -130,7 +139,6 @@ fn to_postfix(tokens: Vec) -> Result, String> { } } op_stack.push(token); - println!("pushed an operator {:?}", token); }, Token::LParen => { op_stack.push(token); @@ -160,3 +168,33 @@ fn to_postfix(tokens: Vec) -> Result, String> { } Ok(postfixed) } + +fn eval_postfix(postfixed: Vec) -> Result { + let mut num_stack: Vec = vec![]; + for token in postfixed { + match token { + Token::Num(n) => { + num_stack.push(n); + }, + Token::Operator(op) => { + if let Some(n2) = num_stack.pop() { + if let Some(n1) = num_stack.pop() { + num_stack.push(op.operate(n1, n2)) + } else { + return Err(format!("Too many operators, Too little operands")) + } + } else { + return Err(format!("Too many operators, Too little operands")) + } + } + _ => { + return Err(format!("Yo nibba how did this get here")) + } + } + } + if num_stack.len() == 1 { + Ok(num_stack.pop().unwrap()) + } else { + Err(format!("Parser Error")) + } +} -- cgit v1.2.3