aboutsummaryrefslogtreecommitdiff
path: root/src/parse
diff options
context:
space:
mode:
authorNerdyPepper <[email protected]>2019-03-23 09:22:27 +0000
committerNerdyPepper <[email protected]>2019-03-23 09:22:27 +0000
commit5af8b2df43f33e5d0b12398ffa6ad9d51a2a97ff (patch)
tree9a60904e713e183e0a41ab4e541abbb069d1f87e /src/parse
parent0312bb8037d5b8092abfb8593884be32f2a1d295 (diff)
handle unreachable match cases, error handling
Diffstat (limited to 'src/parse')
-rw-r--r--src/parse/mod.rs35
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 @@
1use crate::lex::Token; 1use crate::lex::Token;
2use crate::error::CalcError;
2 3
3pub fn to_postfix(tokens: Vec<Token>) -> Result<Vec<Token>, String> { 4pub 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
63pub fn eval_postfix(postfixed: Vec<Token>) -> Result<f64, String> { 62pub 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}