Skip to content

Commit

Permalink
Evaluate a + b% and a - b% correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeremy Wootten committed Nov 30, 2023
1 parent 98085d8 commit b6a3e82
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 7 deletions.
25 changes: 22 additions & 3 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 @@ -60,8 +61,7 @@ namespace PantheonCalculator.Core {
Operator () { symbol = "÷", inputs = 2, prec = 2, fixity = "LEFT", eval = (a, b) => a / b },
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 }
Operator () { symbol = "E", inputs = 2, prec = 4, fixity = "RIGHT", eval = (a, b) => a * Math.pow (10, b) }
};

private struct Function { string symbol; int inputs; Eval eval;}
Expand Down Expand Up @@ -120,13 +120,17 @@ namespace PantheonCalculator.Core {
Queue<Token> op_stack = new Queue<Token> ();

foreach (Token t in token_list) {
warning ("Shunting found '%s', Type %s", t.content, t.token_type.to_string ());
switch (t.token_type) {
case TokenType.NUMBER:
output.append (t);
break;
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 +212,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 +324,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);
}
}
}

0 comments on commit b6a3e82

Please sign in to comment.