Merge lp:~embik/pantheon-calculator/bug-1412890 into lp:~elementary-apps/pantheon-calculator/trunk

Proposed by Marvin Beckers
Status: Merged
Approved by: Marvin Beckers
Approved revision: 89
Merged at revision: 88
Proposed branch: lp:~embik/pantheon-calculator/bug-1412890
Merge into: lp:~elementary-apps/pantheon-calculator/trunk
Diff against target: 129 lines (+34/-19)
2 files modified
src/Core/Evaluation.vala (+28/-17)
src/Core/Scanner.vala (+6/-2)
To merge this branch: bzr merge lp:~embik/pantheon-calculator/bug-1412890
Reviewer Review Type Date Requested Status
Marvin Beckers (community) Approve
Review via email: mp+247069@code.launchpad.net

Commit message

fixes bug 1412890 (segfault on specific scenario) and corrects the way Shunting Yard works

Description of the change

This branch fixes bug 1412890 [segfault on sin(1/4pi)] and a subsequently discovered bug in Shunting Yard which did the token reorder wrong.

To post a comment you must log in.
88. By Marvin Beckers

some little code beautifying

89. By Marvin Beckers

removed kind of redundant do-while-construction

Revision history for this message
Marvin Beckers (embik) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/Core/Evaluation.vala'
--- src/Core/Evaluation.vala 2015-01-14 19:50:02 +0000
+++ src/Core/Evaluation.vala 2015-01-20 22:04:30 +0000
@@ -83,10 +83,10 @@
83 tokenlist = e.shunting_yard (tokenlist);83 tokenlist = e.shunting_yard (tokenlist);
84 try {84 try {
85 d = e.eval_postfix (tokenlist);85 d = e.eval_postfix (tokenlist);
86 } catch (EVAL_ERROR e) { throw new OUT_ERROR.EVAL_ERROR (e.message); }86 } catch (Error e) { throw new OUT_ERROR.EVAL_ERROR (e.message); }
87 } catch (SHUNTING_ERROR e) { throw new OUT_ERROR.SHUNTING_ERROR (e.message); }87 } catch (Error e) { throw new OUT_ERROR.SHUNTING_ERROR (e.message); }
88 return e.cut (d, d_places);88 return e.cut (d, d_places);
89 } catch (SCANNER_ERROR e) { throw new OUT_ERROR.SCANNER_ERROR (e.message); }89 } catch (Error e) { throw new OUT_ERROR.SCANNER_ERROR (e.message); }
90 }90 }
9191
92 //Djikstra's Shunting Yard algorithm for ordering a tokenized list into Reverse Polish Notation92 //Djikstra's Shunting Yard algorithm for ordering a tokenized list into Reverse Polish Notation
@@ -107,9 +107,8 @@
107 break;107 break;
108108
109 case TokenType.SEPARATOR:109 case TokenType.SEPARATOR:
110 while (opStack.peek ().token_type != TokenType.P_LEFT && !opStack.empty ()) {110 while (opStack.peek ().token_type != TokenType.P_LEFT && !opStack.empty ())
111 output.append (opStack.pop ());111 output.append (opStack.pop ());
112 }
113112
114 if (opStack.peek ().token_type != TokenType.P_LEFT)113 if (opStack.peek ().token_type != TokenType.P_LEFT)
115 throw new SHUNTING_ERROR.MISMATCHED_P ("Content of parentheses is mismatched.");114 throw new SHUNTING_ERROR.MISMATCHED_P ("Content of parentheses is mismatched.");
@@ -119,16 +118,21 @@
119 if (!opStack.empty ()) {118 if (!opStack.empty ()) {
120 Operator op1 = get_operator (t);119 Operator op1 = get_operator (t);
121 Operator op2 = Operator ();120 Operator op2 = Operator ();
122 try { op2 = get_operator (opStack.peek ());121
122 try {
123 op2 = get_operator (opStack.peek ());
123 } catch (SHUNTING_ERROR e) { }124 } catch (SHUNTING_ERROR e) { }
124125
125 while (!opStack.empty () &&126 while (!opStack.empty () && opStack.peek ().token_type == TokenType.OPERATOR &&
126 ((op2.fixity == "LEFT" && op1.prec <= op2.prec) ||127 ((op2.fixity == "LEFT" && op1.prec <= op2.prec) ||
127 (op2.fixity == "RIGHT" && op1.prec < op2.prec))) {128 (op2.fixity == "RIGHT" && op1.prec < op2.prec))) {
128 output.append (opStack.pop ());129 output.append (opStack.pop ());
129 if (!opStack.empty ())130
130 try { op2 = get_operator (opStack.peek ());131 if (!opStack.empty ()) {
132 try {
133 op2 = get_operator (opStack.peek ());
131 } catch (SHUNTING_ERROR e) { }134 } catch (SHUNTING_ERROR e) { }
135 }
132 }136 }
133 }137 }
134 opStack.push (t);138 opStack.push (t);
@@ -139,25 +143,32 @@
139 break;143 break;
140144
141 case TokenType.P_RIGHT:145 case TokenType.P_RIGHT:
142 while (!(opStack.peek ().token_type == TokenType.P_LEFT) && !opStack.empty ())146 while (!opStack.empty ()) {
143 output.append (opStack.pop ());147 if (!(opStack.peek ().token_type == TokenType.P_LEFT))
148 output.append (opStack.pop ());
149 else
150 break;
151 }
144152
145 if (!(opStack.empty ()))153 if (!(opStack.empty ()) && opStack.peek ().token_type == TokenType.P_LEFT)
146 opStack.pop ();154 opStack.pop ();
147155
148 if (!opStack.empty () && opStack.peek ().token_type == TokenType.FUNCTION) 156 if (!opStack.empty () && opStack.peek ().token_type == TokenType.FUNCTION)
149 output.append (opStack.pop ());157 output.append (opStack.pop ());
158
150 break;159 break;
151 default:160 default:
152 throw new SHUNTING_ERROR.UNKNOWN_TOKEN ("'%s' is unknown.", t.content);161 throw new SHUNTING_ERROR.UNKNOWN_TOKEN ("'%s' is unknown.", t.content);
153 }162 }
154 }163 }
164
155 while (!opStack.empty ()) {165 while (!opStack.empty ()) {
156 if (opStack.peek ().token_type == TokenType.P_LEFT)166 if (opStack.peek ().token_type == TokenType.P_LEFT || opStack.peek ().token_type == TokenType.P_RIGHT)
157 throw new SHUNTING_ERROR.MISMATCHED_P ("Mismatched left parenthesis.");167 throw new SHUNTING_ERROR.MISMATCHED_P ("Mismatched parenthesis.");
158 else168 else
159 output.append (opStack.pop ());169 output.append (opStack.pop ());
160 }170 }
171
161 return output;172 return output;
162 }173 }
163174
@@ -201,7 +212,7 @@
201 //checks for real TokenType (which are TokenType.ALPHA at the moment)212 //checks for real TokenType (which are TokenType.ALPHA at the moment)
202 public bool is_operator (Token t) {213 public bool is_operator (Token t) {
203 foreach (Operator o in operators) {214 foreach (Operator o in operators) {
204 if (t.content == o.symbol) 215 if (t.content == o.symbol)
205 return true;216 return true;
206 }217 }
207 return false;218 return false;
@@ -209,7 +220,7 @@
209220
210 public bool is_function (Token t) {221 public bool is_function (Token t) {
211 foreach (Function f in functions) {222 foreach (Function f in functions) {
212 if (t.content == f.symbol) 223 if (t.content == f.symbol)
213 return true;224 return true;
214 }225 }
215 return false;226 return false;
216227
=== modified file 'src/Core/Scanner.vala'
--- src/Core/Scanner.vala 2015-01-14 19:50:02 +0000
+++ src/Core/Scanner.vala 2015-01-20 22:04:30 +0000
@@ -84,8 +84,12 @@
84 next_number_negative = false;84 next_number_negative = false;
85 }85 }
8686
87 //checking if last token was a number and token now is a function, constant or parenthesis (left)87 /*
88 if (last_token != null && last_token.token_type == TokenType.NUMBER && 88 * checking if last token was a number or parenthesis right
89 * and token now is a function, constant or parenthesis (left)
90 */
91 if (last_token != null &&
92 (last_token.token_type == TokenType.NUMBER || last_token.token_type == TokenType.P_RIGHT) &&
89 (t.token_type == TokenType.FUNCTION || t.token_type == TokenType.CONSTANT || t.token_type == TokenType.P_LEFT))93 (t.token_type == TokenType.FUNCTION || t.token_type == TokenType.CONSTANT || t.token_type == TokenType.P_LEFT))
90 tokenlist.append (new Token ("*", TokenType.OPERATOR));94 tokenlist.append (new Token ("*", TokenType.OPERATOR));
9195

Subscribers

People subscribed via source and target branches

to all changes: