diff options
Diffstat (limited to 'src/parse')
-rw-r--r-- | src/parse/mod.rs | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/src/parse/mod.rs b/src/parse/mod.rs index e5c28e6..4238e3b 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs | |||
@@ -1,6 +1,7 @@ | |||
1 | use crate::lex::Token; | 1 | use crate::lex::Token; |
2 | use crate::error::CalcError; | ||
2 | 3 | ||
3 | pub fn to_postfix(tokens: Vec<Token>) -> Result<Vec<Token>, String> { | 4 | pub fn to_postfix(tokens: Vec<Token>) -> Result<Vec<Token>, CalcError> { |
4 | let mut postfixed: Vec<Token> = vec![]; | 5 | let mut postfixed: Vec<Token> = vec![]; |
5 | let mut op_stack: Vec<Token> = vec![]; | 6 | let mut op_stack: Vec<Token> = vec![]; |
6 | for token in tokens { | 7 | for token in tokens { |
@@ -29,9 +30,7 @@ pub fn to_postfix(tokens: Vec<Token>) -> Result<Vec<Token>, String> { | |||
29 | Token::Function(_) => { | 30 | Token::Function(_) => { |
30 | postfixed.push(op_stack.pop().unwrap()); | 31 | postfixed.push(op_stack.pop().unwrap()); |
31 | } | 32 | } |
32 | _ => { | 33 | _ => { unreachable!(); } |
33 | return Err(format!("{:?} must not be on operator stack", top_op)) | ||
34 | } | ||
35 | } | 34 | } |
36 | } | 35 | } |
37 | op_stack.push(token); | 36 | op_stack.push(token); |
@@ -49,7 +48,7 @@ pub fn to_postfix(tokens: Vec<Token>) -> Result<Vec<Token>, String> { | |||
49 | postfixed.push(token) | 48 | postfixed.push(token) |
50 | } | 49 | } |
51 | if !push_until_paren { | 50 | if !push_until_paren { |
52 | return Err(String::from("Mismatched ')'")); | 51 | return Err(CalcError::Syntax("Mismatched parentheses!".into())); |
53 | } | 52 | } |
54 | } | 53 | } |
55 | } | 54 | } |
@@ -60,7 +59,7 @@ pub fn to_postfix(tokens: Vec<Token>) -> Result<Vec<Token>, String> { | |||
60 | Ok(postfixed) | 59 | Ok(postfixed) |
61 | } | 60 | } |
62 | 61 | ||
63 | pub fn eval_postfix(postfixed: Vec<Token>) -> Result<f64, String> { | 62 | pub fn eval_postfix(postfixed: Vec<Token>) -> Result<f64, CalcError> { |
64 | let mut num_stack: Vec<f64> = vec![]; | 63 | let mut num_stack: Vec<f64> = vec![]; |
65 | for token in postfixed { | 64 | for token in postfixed { |
66 | match token { | 65 | match token { |
@@ -70,27 +69,39 @@ pub fn eval_postfix(postfixed: Vec<Token>) -> Result<f64, String> { | |||
70 | Token::Operator(op) => { | 69 | Token::Operator(op) => { |
71 | if let Some(n2) = num_stack.pop() { | 70 | if let Some(n2) = num_stack.pop() { |
72 | if let Some(n1) = num_stack.pop() { | 71 | if let Some(n1) = num_stack.pop() { |
73 | num_stack.push(op.operate(n1, n2)) | 72 | num_stack.push(op.operate(n1, n2)?); |
74 | } else { | 73 | } else { |
75 | return Err(format!("Too many operators, Too little operands")) | 74 | return Err( |
75 | CalcError::Parser( | ||
76 | format!("Too many operators, Too little operands") | ||
77 | ) | ||
78 | ) | ||
76 | } | 79 | } |
77 | } else { | 80 | } else { |
78 | return Err(format!("Too many operators, Too little operands")) | 81 | return Err( |
82 | CalcError::Parser( | ||
83 | format!("Too many operators, Too little operands") | ||
84 | ) | ||
85 | ) | ||
79 | } | 86 | } |
80 | }, | 87 | }, |
81 | Token::Function(funct) => { | 88 | Token::Function(funct) => { |
82 | if let Some(arg) = num_stack.pop() { | 89 | if let Some(arg) = num_stack.pop() { |
83 | num_stack.push(funct.apply(arg)) | 90 | num_stack.push(funct.apply(arg)?) |
84 | } | 91 | } |
85 | } | 92 | } |
86 | _ => { | 93 | _ => { |
87 | return Err(format!("Yo nibba how did this get here")) | 94 | unreachable!("nah nigga") |
88 | } | 95 | } |
89 | } | 96 | } |
90 | } | 97 | } |
91 | if num_stack.len() == 1 { | 98 | if num_stack.len() == 1 { |
92 | Ok(num_stack.pop().unwrap()) | 99 | Ok(num_stack.pop().unwrap()) |
93 | } else { | 100 | } else { |
94 | Err(format!("Parser Error")) | 101 | return Err( |
102 | CalcError::Parser( | ||
103 | format!("Too many operators, Too little operands") | ||
104 | ) | ||
105 | ) | ||
95 | } | 106 | } |
96 | } | 107 | } |