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
1=== modified file 'src/Core/Evaluation.vala'
2--- src/Core/Evaluation.vala 2015-01-14 19:50:02 +0000
3+++ src/Core/Evaluation.vala 2015-01-20 22:04:30 +0000
4@@ -83,10 +83,10 @@
5 tokenlist = e.shunting_yard (tokenlist);
6 try {
7 d = e.eval_postfix (tokenlist);
8- } catch (EVAL_ERROR e) { throw new OUT_ERROR.EVAL_ERROR (e.message); }
9- } catch (SHUNTING_ERROR e) { throw new OUT_ERROR.SHUNTING_ERROR (e.message); }
10+ } catch (Error e) { throw new OUT_ERROR.EVAL_ERROR (e.message); }
11+ } catch (Error e) { throw new OUT_ERROR.SHUNTING_ERROR (e.message); }
12 return e.cut (d, d_places);
13- } catch (SCANNER_ERROR e) { throw new OUT_ERROR.SCANNER_ERROR (e.message); }
14+ } catch (Error e) { throw new OUT_ERROR.SCANNER_ERROR (e.message); }
15 }
16
17 //Djikstra's Shunting Yard algorithm for ordering a tokenized list into Reverse Polish Notation
18@@ -107,9 +107,8 @@
19 break;
20
21 case TokenType.SEPARATOR:
22- while (opStack.peek ().token_type != TokenType.P_LEFT && !opStack.empty ()) {
23+ while (opStack.peek ().token_type != TokenType.P_LEFT && !opStack.empty ())
24 output.append (opStack.pop ());
25- }
26
27 if (opStack.peek ().token_type != TokenType.P_LEFT)
28 throw new SHUNTING_ERROR.MISMATCHED_P ("Content of parentheses is mismatched.");
29@@ -119,16 +118,21 @@
30 if (!opStack.empty ()) {
31 Operator op1 = get_operator (t);
32 Operator op2 = Operator ();
33- try { op2 = get_operator (opStack.peek ());
34+
35+ try {
36+ op2 = get_operator (opStack.peek ());
37 } catch (SHUNTING_ERROR e) { }
38
39- while (!opStack.empty () &&
40+ while (!opStack.empty () && opStack.peek ().token_type == TokenType.OPERATOR &&
41 ((op2.fixity == "LEFT" && op1.prec <= op2.prec) ||
42 (op2.fixity == "RIGHT" && op1.prec < op2.prec))) {
43 output.append (opStack.pop ());
44- if (!opStack.empty ())
45- try { op2 = get_operator (opStack.peek ());
46+
47+ if (!opStack.empty ()) {
48+ try {
49+ op2 = get_operator (opStack.peek ());
50 } catch (SHUNTING_ERROR e) { }
51+ }
52 }
53 }
54 opStack.push (t);
55@@ -139,25 +143,32 @@
56 break;
57
58 case TokenType.P_RIGHT:
59- while (!(opStack.peek ().token_type == TokenType.P_LEFT) && !opStack.empty ())
60- output.append (opStack.pop ());
61+ while (!opStack.empty ()) {
62+ if (!(opStack.peek ().token_type == TokenType.P_LEFT))
63+ output.append (opStack.pop ());
64+ else
65+ break;
66+ }
67
68- if (!(opStack.empty ()))
69+ if (!(opStack.empty ()) && opStack.peek ().token_type == TokenType.P_LEFT)
70 opStack.pop ();
71
72- if (!opStack.empty () && opStack.peek ().token_type == TokenType.FUNCTION)
73+ if (!opStack.empty () && opStack.peek ().token_type == TokenType.FUNCTION)
74 output.append (opStack.pop ());
75+
76 break;
77 default:
78 throw new SHUNTING_ERROR.UNKNOWN_TOKEN ("'%s' is unknown.", t.content);
79 }
80 }
81+
82 while (!opStack.empty ()) {
83- if (opStack.peek ().token_type == TokenType.P_LEFT)
84- throw new SHUNTING_ERROR.MISMATCHED_P ("Mismatched left parenthesis.");
85+ if (opStack.peek ().token_type == TokenType.P_LEFT || opStack.peek ().token_type == TokenType.P_RIGHT)
86+ throw new SHUNTING_ERROR.MISMATCHED_P ("Mismatched parenthesis.");
87 else
88 output.append (opStack.pop ());
89 }
90+
91 return output;
92 }
93
94@@ -201,7 +212,7 @@
95 //checks for real TokenType (which are TokenType.ALPHA at the moment)
96 public bool is_operator (Token t) {
97 foreach (Operator o in operators) {
98- if (t.content == o.symbol)
99+ if (t.content == o.symbol)
100 return true;
101 }
102 return false;
103@@ -209,7 +220,7 @@
104
105 public bool is_function (Token t) {
106 foreach (Function f in functions) {
107- if (t.content == f.symbol)
108+ if (t.content == f.symbol)
109 return true;
110 }
111 return false;
112
113=== modified file 'src/Core/Scanner.vala'
114--- src/Core/Scanner.vala 2015-01-14 19:50:02 +0000
115+++ src/Core/Scanner.vala 2015-01-20 22:04:30 +0000
116@@ -84,8 +84,12 @@
117 next_number_negative = false;
118 }
119
120- //checking if last token was a number and token now is a function, constant or parenthesis (left)
121- if (last_token != null && last_token.token_type == TokenType.NUMBER &&
122+ /*
123+ * checking if last token was a number or parenthesis right
124+ * and token now is a function, constant or parenthesis (left)
125+ */
126+ if (last_token != null &&
127+ (last_token.token_type == TokenType.NUMBER || last_token.token_type == TokenType.P_RIGHT) &&
128 (t.token_type == TokenType.FUNCTION || t.token_type == TokenType.CONSTANT || t.token_type == TokenType.P_LEFT))
129 tokenlist.append (new Token ("*", TokenType.OPERATOR));
130

Subscribers

People subscribed via source and target branches

to all changes: