Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions src/Core/Evaluation.vala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ namespace PantheonCalculator.Core {
private errordomain EVAL_ERROR {
NO_FUNCTION,
NO_OPERATOR,
NO_CONSTANT
NO_CONSTANT,
NO_NUMBER
}

private errordomain SHUNTING_ERROR {
Expand Down Expand Up @@ -61,7 +62,11 @@ namespace PantheonCalculator.Core {
Operator () { symbol = "mod", inputs = 2, prec = 2, fixity = "LEFT", eval = (a, b) => a % b },
Operator () { symbol = "^", inputs = 2, prec = 3, fixity = "RIGHT", eval = (a, b) => Math.pow (a, b) },
Operator () { symbol = "E", inputs = 2, prec = 4, fixity = "RIGHT", eval = (a, b) => a * Math.pow (10, b) },
Operator () { symbol = "%", inputs = 1, prec = 5, fixity = "LEFT", eval = (a, b) => b / 100.0 }
//Internal use only
//Hgh precedence multiply and divide for percentage evaluation
//Percentage always evaluates first as if it has parens around it
Operator () { symbol = "<*>", inputs = 2, prec = 7, fixity = "LEFT", eval = (a, b) => a * b },
Operator () { symbol = "<÷>", inputs = 2, prec = 6, fixity = "LEFT", eval = (a, b) => a / b }
};

private struct Function { string symbol; int inputs; Eval eval;}
Expand Down Expand Up @@ -127,6 +132,9 @@ namespace PantheonCalculator.Core {
case TokenType.CONSTANT:
output.append (t);
break;
case TokenType.CURRENT_LEFT_VALUE:
output.append (t);
break;
case TokenType.FUNCTION:
op_stack.push_tail (t);
break;
Expand Down Expand Up @@ -208,6 +216,20 @@ namespace PantheonCalculator.Core {
foreach (Token t in token_list) {
if (t.token_type == TokenType.NUMBER) {
stack.push_tail (t);
} else if (t.token_type == TokenType.CURRENT_LEFT_VALUE) {
var t1 = stack.pop_tail ();
Token t2;
if (!stack.is_empty () && stack.peek_tail ().token_type == TokenType.NUMBER) {
t2 = stack.peek_tail ().dup ();
} else if (stack.is_empty ()) {
t2 = new Token ("1", TokenType.NUMBER);
} else {
throw new EVAL_ERROR.NO_NUMBER ("");
}

stack.push_tail (t2);
stack.push_tail (t1);

} else if (t.token_type == TokenType.CONSTANT) {
try {
Constant c = get_constant (t);
Expand Down Expand Up @@ -306,6 +328,7 @@ namespace PantheonCalculator.Core {
if (fabs (d) - 0.0 < double.EPSILON) {
d = 0.0;
}

return new Token (d.to_string (), TokenType.NUMBER);
}

Expand Down
25 changes: 21 additions & 4 deletions src/Core/Scanner.vala
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ namespace PantheonCalculator.Core {
public errordomain SCANNER_ERROR {
UNKNOWN_TOKEN,
ALPHA_INVALID,
MISMATCHED_PARENTHESES
MISMATCHED_PARENTHESES,
INVALID_PERCENT
}

public class Scanner : Object {
Expand Down Expand Up @@ -70,7 +71,7 @@ namespace PantheonCalculator.Core {
} else if (t.token_type == TokenType.OPERATOR && (t.content in "-−")) {
/* Define last_tokens, where a next minus is a number, not an operator */
if (last_token == null || (
(last_token.token_type == TokenType.OPERATOR && last_token.content != "%") ||
(last_token.token_type == TokenType.OPERATOR) ||
(last_token.token_type == TokenType.FUNCTION) ||
(last_token.token_type == TokenType.P_LEFT)
)) {
Expand All @@ -82,6 +83,20 @@ namespace PantheonCalculator.Core {
//Insert a leading zero to make complete number e.g. .5 -> 0.5
t.content = "0" + t.content;
t.token_type = TokenType.NUMBER;
} else if (t.token_type == TokenType.PERCENT) {
if (last_token == null || (
(last_token.token_type == TokenType.OPERATOR) ||
(last_token.token_type == TokenType.FUNCTION) ||
(last_token.token_type == TokenType.P_LEFT))) {
throw new SCANNER_ERROR.INVALID_PERCENT (_("'%' must follow a value."));
} else {
token_list.append (new Token ("<*>", TokenType.OPERATOR));
token_list.append (new Token ("<CLV>", TokenType.CURRENT_LEFT_VALUE));
token_list.append (new Token ("<÷>", TokenType.OPERATOR));
last_token = new Token ("100", TokenType.NUMBER);
token_list.append (last_token);
continue;
}
}

if (next_number_negative && t.token_type == TokenType.NUMBER) {
Expand Down Expand Up @@ -122,7 +137,6 @@ namespace PantheonCalculator.Core {
private Token next_token () throws SCANNER_ERROR {
ssize_t start = pos;
TokenType type;

if (uc[pos] == decimal_symbol.get_char (0)) {
pos++;
while (uc[pos].isdigit () && pos < uc.length) {
Expand All @@ -141,10 +155,13 @@ namespace PantheonCalculator.Core {
}
type = TokenType.NUMBER;
} else if (uc[pos] == '+' || uc[pos] == '-' || uc[pos] == '*' ||
uc[pos] == '/' || uc[pos] == '^' || uc[pos] == '%' ||
uc[pos] == '/' || uc[pos] == '^' ||
uc[pos] == '÷' || uc[pos] == '×' || uc[pos] == '−') {
pos++;
type = TokenType.OPERATOR;
} else if (uc[pos] == '%') {
pos++;
type = TokenType.PERCENT;
} else if (uc[pos] == '√') {
pos++;
type = TokenType.FUNCTION;
Expand Down
6 changes: 6 additions & 0 deletions src/Core/Token.vala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ namespace PantheonCalculator.Core {
NUMBER,
OPERATOR,
FUNCTION,
PERCENT,
CURRENT_LEFT_VALUE,
SEPARATOR,
CONSTANT,
P_LEFT,
Expand All @@ -42,5 +44,9 @@ namespace PantheonCalculator.Core {
token_type: in_token_type
);
}

public Token dup () {
return new Token (content, token_type);
}
}
}
4 changes: 2 additions & 2 deletions test/CoreTest.vala
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ class PantheonCalculator.Core.CoreTest : Object {
assert_equal ("e^5.25 / exp(5.25)", "1");
assert_equal ("10^(log(2.2))", "2.2");
assert_equal ("3.141592654*3.141592654", "9.869604404"); // https://github.com/elementary/calculator/issues/7
assert_equal ("10 + 5 - 10%", "14.9"); // https://github.com/elementary/calculator/issues/44
assert_equal ("10 - 10% + 5", "14.9"); // https://github.com/elementary/calculator/issues/44
assert_equal ("10 + 5 - 10%", "13.5"); // https://github.com/elementary/calculator/issues/44
assert_equal ("10 - 10% + 5", "14"); // https://github.com/elementary/calculator/issues/44

assert_equal ("25,123 - 234,2", "-209,077", ",", "."); // https://github.com/elementary/calculator/issues/48
assert_equal ("25.000,123 - 234000,2", "-209.000,077", ",", "."); // https://github.com/elementary/calculator/issues/48
Expand Down