Skip to content

Commit

Permalink
Move to 1.20.4
Browse files Browse the repository at this point in the history
Refactored the calculator code for clarity.

Added Jacoco line to prvent issues with the bigger Material class.
  • Loading branch information
tastybento committed Dec 10, 2023
1 parent cfb3590 commit cec6201
Show file tree
Hide file tree
Showing 3 changed files with 603 additions and 545 deletions.
4 changes: 3 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
<!-- Non-minecraft related dependencies -->
<powermock.version>2.0.9</powermock.version>
<!-- More visible way how to change dependency versions -->
<spigot.version>1.19.4-R0.1-SNAPSHOT</spigot.version>
<spigot.version>1.20.4-R0.1-SNAPSHOT</spigot.version>
<bentobox.version>2.0.0-SNAPSHOT</bentobox.version>
<!-- Warps addon version -->
<warps.version>1.12.0</warps.version>
Expand Down Expand Up @@ -410,6 +410,8 @@
<!-- This is required to prevent Jacoco from adding
synthetic fields to a JavaBean class (causes errors in testing) -->
<exclude>**/*Names*</exclude>
<!-- Prevents the Material is too large to mock error -->
<exclude>org/bukkit/Material*</exclude>
</excludes>
</configuration>
<executions>
Expand Down
121 changes: 121 additions & 0 deletions src/main/java/world/bentobox/level/calculators/EquationEvaluator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package world.bentobox.level.calculators;

import java.text.ParseException;

/**
* @author tastybento
*/
public class EquationEvaluator {

private static class Parser {
private final String input;
private int pos = -1;
private int currentChar;

public Parser(String input) {
this.input = input;
moveToNextChar();
}

private void moveToNextChar() {
currentChar = (++pos < input.length()) ? input.charAt(pos) : -1;
}

private boolean tryToEat(int charToEat) {
while (currentChar == ' ')
moveToNextChar();
if (currentChar == charToEat) {
moveToNextChar();
return true;
}
return false;
}

public double evaluate() throws ParseException {
double result = parseExpression();
if (pos < input.length()) {
throw new ParseException("Unexpected character: " + (char) currentChar, pos);
}
return result;
}

private double parseExpression() throws ParseException {
double result = parseTerm();
while (true) {
if (tryToEat('+'))
result += parseTerm();
else if (tryToEat('-'))
result -= parseTerm();
else
return result;
}
}

private double parseFactor() throws ParseException {
if (tryToEat('+'))
return parseFactor(); // unary plus
if (tryToEat('-'))
return -parseFactor(); // unary minus

double x;
int startPos = this.pos;
if (tryToEat('(')) { // parentheses
x = parseExpression();
tryToEat(')');
} else if ((currentChar >= '0' && currentChar <= '9') || currentChar == '.') { // numbers
while ((currentChar >= '0' && currentChar <= '9') || currentChar == '.')
moveToNextChar();
x = Double.parseDouble(input.substring(startPos, this.pos));
} else if (currentChar >= 'a' && currentChar <= 'z') { // functions
while (currentChar >= 'a' && currentChar <= 'z')
moveToNextChar();
String func = input.substring(startPos, this.pos);
x = parseFactor();
switch (func) {
case "sqrt":
x = Math.sqrt(x);
break;
case "sin":
x = Math.sin(Math.toRadians(x));
break;
case "cos":
x = Math.cos(Math.toRadians(x));
break;
case "tan":
x = Math.tan(Math.toRadians(x));
break;
case "log":
x = Math.log(x);
break;
default:
throw new ParseException("Unknown function: " + func, startPos);
}
} else {
throw new ParseException("Unexpected: " + (char) currentChar, startPos);
}

if (tryToEat('^'))
x = Math.pow(x, parseFactor()); // exponentiation

return x;
}

private double parseTerm() throws ParseException {
double x = parseFactor();
for (;;) {
if (tryToEat('*'))
x *= parseFactor(); // multiplication
else if (tryToEat('/'))
x /= parseFactor(); // division
else
return x;
}
}

}

public static double eval(final String equation) throws ParseException {
return new Parser(equation).evaluate();
}

}

0 comments on commit cec6201

Please sign in to comment.