diff options
author | NerdyPepper <[email protected]> | 2019-03-19 17:16:36 +0000 |
---|---|---|
committer | NerdyPepper <[email protected]> | 2019-03-19 17:16:36 +0000 |
commit | e4a077e175eee58516c7335c97f4985d26138e61 (patch) | |
tree | e02585b798dddfdcbb8674fbf24ca1c296f849c8 /src/main.rs | |
parent | 770bef9bdbc6185ba08d2881f0cf7b98f68af95d (diff) |
add postfix eval fn, more lexing features
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 50 |
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 | ||
33 | fn main() { | 33 | fn 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 | ||
41 | fn lexer(input: &str) -> Result<Vec<Token>, String> { | 44 | fn 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 | |||
172 | fn 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 | } | ||