aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java23
1 files changed, 15 insertions, 8 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java
index 54636791..4d57d92f 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java
@@ -33,12 +33,10 @@ public class Calculator {
source = source.toLowerCase(Locale.ROOT);
return evaluate(shuntingYard(lex(source)));
}
-
///<editor-fold desc="Lexing Time">
public enum TokenType {
- NUMBER, BINOP, LPAREN, RPAREN, POSTOP
+ NUMBER, BINOP, LPAREN, RPAREN, POSTOP, PREOP
}
-
public static class Token {
public TokenType type;
String operatorValue;
@@ -89,6 +87,7 @@ public class Calculator {
public static List<Token> lex(String source) throws CalculatorException {
List<Token> tokens = new ArrayList<>();
+ boolean justParsedNumber = false;
for (int i = 0; i < source.length(); ) {
char c = source.charAt(i);
if (Character.isWhitespace(c)) {
@@ -97,7 +96,11 @@ public class Calculator {
}
Token token = new Token();
token.tokenStart = i;
- if (binops.indexOf(c) != -1) {
+ if (!justParsedNumber && c == '-') {
+ token.tokenLength = 1;
+ token.type = TokenType.PREOP;
+ token.operatorValue = "-";
+ } else if (binops.indexOf(c) != -1) {
token.tokenLength = 1;
token.type = TokenType.BINOP;
token.operatorValue = c + "";
@@ -137,6 +140,7 @@ public class Calculator {
} else {
throw new CalculatorException("Unknown thing " + c, i, 1);
}
+ justParsedNumber = token.type == TokenType.NUMBER;
tokens.add(token);
i += token.tokenLength;
}
@@ -188,6 +192,9 @@ public class Calculator {
}
op.push(currentlyShunting);
break;
+ case PREOP:
+ op.push(currentlyShunting);
+ break;
case LPAREN:
op.push(currentlyShunting);
break;
@@ -223,12 +230,14 @@ public class Calculator {
/// </editor-fold>
///<editor-fold desc="Evaluating Time">
-
public static BigDecimal evaluate(List<Token> rpnTokens) throws CalculatorException {
Deque<BigDecimal> values = new ArrayDeque<>();
try {
for (Token command : rpnTokens) {
switch (command.type) {
+ case PREOP:
+ values.push(values.pop().negate());
+ break;
case NUMBER:
values.push(new BigDecimal(command.numericValue).scaleByPowerOfTen(command.exponent));
break;
@@ -317,7 +326,5 @@ public class Calculator {
throw new CalculatorException("Unfinished expression", 0, 0);
}
}
-
- ///</editor-fold>
-
+ /// </editor-fold>
}