aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNerdyPepper <[email protected]>2019-03-19 17:16:36 +0000
committerNerdyPepper <[email protected]>2019-03-19 17:16:36 +0000
commite4a077e175eee58516c7335c97f4985d26138e61 (patch)
treee02585b798dddfdcbb8674fbf24ca1c296f849c8
parent770bef9bdbc6185ba08d2881f0cf7b98f68af95d (diff)
add postfix eval fn, more lexing features
-rw-r--r--src/main.rs50
1 files changed, 44 insertions, 6 deletions
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 {
31} 31}
32 32
33fn main() { 33fn main() {
34 let input = "1 + 2 * 3"; 34 let input = "1 + 5 * 6 + 2";
35 println!("{}", input);
35 let input = input.replace(" ", ""); 36 let input = input.replace(" ", "");
36 let lexed = lexer(&input); 37 let lexed = lexer(&input);
37 let postfixed = to_postfix(lexed.unwrap()); 38 let postfixed = to_postfix(lexed.unwrap());
38 println!("{:?}", postfixed); 39 let evaled = eval_postfix(postfixed.unwrap());
40
41 println!("{:?}", evaled);
39} 42}
40 43
41fn lexer(input: &str) -> Result<Vec<Token>, String> { 44fn lexer(input: &str) -> Result<Vec<Token>, String> {
@@ -72,6 +75,14 @@ fn lexer(input: &str) -> Result<Vec<Token>, String> {
72 result.push(Operator::token_from_op('*', |x, y| x * y, 3, true)); 75 result.push(Operator::token_from_op('*', |x, y| x * y, 3, true));
73 num_vec.clear(); 76 num_vec.clear();
74 } 77 }
78 if let Some(x) = result.last() {
79 match x {
80 Token::RParen => {
81 result.push(Operator::token_from_op('*', |x, y| x * y, 3, true));
82 },
83 _ => {}
84 };
85 }
75 // finish 86 // finish
76 result.push(Token::LParen); 87 result.push(Token::LParen);
77 }, 88 },
@@ -106,20 +117,18 @@ fn to_postfix(tokens: Vec<Token>) -> Result<Vec<Token>, String> {
106 match token { 117 match token {
107 Token::Num(_) => { 118 Token::Num(_) => {
108 postfixed.push(token); 119 postfixed.push(token);
109 println!("pushed a number {:?}", token);
110 }, 120 },
111 Token::Operator(current_op) => { 121 Token::Operator(current_op) => {
112 while let Some(top_op) = op_stack.last() { 122 while let Some(top_op) = op_stack.last() {
113 match top_op { 123 match top_op {
114 Token::LParen => { 124 Token::LParen => {
115 return Err(format!("Mismatched Parentheses!")) 125 break;
116 } 126 }
117 Token::Operator(top_op) => { 127 Token::Operator(top_op) => {
118 let tp = top_op.precedence; 128 let tp = top_op.precedence;
119 let cp = current_op.precedence; 129 let cp = current_op.precedence;
120 if tp > cp || (tp == cp && top_op.is_left_associative) { 130 if tp > cp || (tp == cp && top_op.is_left_associative) {
121 postfixed.push(op_stack.pop().unwrap()); 131 postfixed.push(op_stack.pop().unwrap());
122 println!("pushed an operator special {:?}", token);
123 } else { 132 } else {
124 break; 133 break;
125 } 134 }
@@ -130,7 +139,6 @@ fn to_postfix(tokens: Vec<Token>) -> Result<Vec<Token>, String> {
130 } 139 }
131 } 140 }
132 op_stack.push(token); 141 op_stack.push(token);
133 println!("pushed an operator {:?}", token);
134 }, 142 },
135 Token::LParen => { 143 Token::LParen => {
136 op_stack.push(token); 144 op_stack.push(token);
@@ -160,3 +168,33 @@ fn to_postfix(tokens: Vec<Token>) -> Result<Vec<Token>, String> {
160 } 168 }
161 Ok(postfixed) 169 Ok(postfixed)
162} 170}
171
172fn eval_postfix(postfixed: Vec<Token>) -> Result<f64, String> {
173 let mut num_stack: Vec<f64> = vec![];
174 for token in postfixed {
175 match token {
176 Token::Num(n) => {
177 num_stack.push(n);
178 },
179 Token::Operator(op) => {
180 if let Some(n2) = num_stack.pop() {
181 if let Some(n1) = num_stack.pop() {
182 num_stack.push(op.operate(n1, n2))
183 } else {
184 return Err(format!("Too many operators, Too little operands"))
185 }
186 } else {
187 return Err(format!("Too many operators, Too little operands"))
188 }
189 }
190 _ => {
191 return Err(format!("Yo nibba how did this get here"))
192 }
193 }
194 }
195 if num_stack.len() == 1 {
196 Ok(num_stack.pop().unwrap())
197 } else {
198 Err(format!("Parser Error"))
199 }
200}