Skip to content
This repository was archived by the owner on Jun 30, 2024. It is now read-only.

Commit 64b8cf6

Browse files
committed
- rewrote the entire function system to let me have multivariable functions
- your input will not compute rather than giving back "NaN" if your syntax is incorrect - added cfg? to give you a list of the config options - fixed existing code that had logic issues, "1+2)/3" is now equal to 1 instead of 3
1 parent 796ff39 commit 64b8cf6

File tree

8 files changed

+274
-74
lines changed

8 files changed

+274
-74
lines changed

src/main/java/ca/rttv/chatcalc/ChatCalc.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,47 @@
11
package ca.rttv.chatcalc;
22

3+
import ca.rttv.chatcalc.tokens.Token;
34
import com.mojang.logging.LogUtils;
45
import net.minecraft.client.MinecraftClient;
56
import net.minecraft.client.gui.widget.TextFieldWidget;
67
import net.minecraft.text.Text;
78
import net.minecraft.util.Pair;
89
import org.jetbrains.annotations.Contract;
910
import org.slf4j.Logger;
11+
import oshi.util.tuples.Triplet;
1012

13+
import java.util.List;
14+
import java.util.Optional;
1115
import java.util.regex.Pattern;
1216

1317
public class ChatCalc {
1418
public static final Logger LOGGER = LogUtils.getLogger();
15-
public static final Pattern NUMBER = Pattern.compile("[-+]?\\d*\\.?\\d+([eE][-+]?\\d+)?");
19+
public static final Pattern NUMBER = Pattern.compile("[-+]?\\d+(\\.\\d+)?");
20+
public static final String SEPARATOR = ";";
1621

1722
@Contract(value = "_->_", mutates = "param1")
1823
public static boolean tryParse(TextFieldWidget field) {
1924
final MinecraftClient client = MinecraftClient.getInstance();
2025
String originalText = field.getText();
2126
int cursor = field.getCursor();
2227
String text = originalText.substring(0, cursor);
28+
if ((text.equals("config?") || text.equals("cfg?") || text.equals("?")) && client.player != null) {
29+
client.player.sendMessage(Text.translatable("chatcalc.config.description"));
30+
return false;
31+
}
2332
String[] split = text.split("=");
2433
if (split.length == 2) {
2534
if (Config.JSON.has(split[0])) {
2635
Config.JSON.addProperty(split[0], split[1]);
2736
Config.refreshJson();
2837
return ChatHelper.replaceWord(field, "");
29-
} else if (split[0].matches("[A-Za-z]+\\([A-Za-z]+\\)")) {
30-
Config.FUNCTIONS.put(split[0].split("\\(")[0], new Pair<>(MathEngine.tokenize(split[1]), split[0].split("[()]")[1]));
31-
Config.refreshJson();
32-
return ChatHelper.replaceWord(field, "");
38+
} else {
39+
Optional<Triplet<String, List<Token>, String[]>> parsedFunction = Config.parseFunction(text);
40+
if (parsedFunction.isPresent()) {
41+
Config.FUNCTIONS.put(parsedFunction.get().getA(), new Pair<>(parsedFunction.get().getB(), parsedFunction.get().getC()));
42+
Config.refreshJson();
43+
return ChatHelper.replaceWord(field, "");
44+
}
3345
}
3446
} else if (Config.JSON.has(split[0])) {
3547
return ChatHelper.replaceWord(field, Config.JSON.get(split[0]).getAsString());

src/main/java/ca/rttv/chatcalc/Config.java

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.google.gson.*;
77
import net.minecraft.client.MinecraftClient;
88
import net.minecraft.util.Pair;
9+
import oshi.util.tuples.Triplet;
910

1011
import java.io.*;
1112
import java.text.DecimalFormat;
@@ -16,7 +17,7 @@ public class Config {
1617
public static final JsonObject JSON;
1718
public static final Gson GSON;
1819
public static final File CONFIG_FILE;
19-
public static final Map<String, Pair<List<Token>, String>> FUNCTIONS;
20+
public static final Map<String, Pair<List<Token>, String[]>> FUNCTIONS;
2021
public static final ImmutableMap<String, String> DEFAULTS;
2122

2223
static {
@@ -71,7 +72,7 @@ public static boolean logExceptions() {
7172
public static void refreshJson() {
7273
try {
7374
FileWriter writer = new FileWriter(CONFIG_FILE);
74-
JSON.add("functions", FUNCTIONS.entrySet().stream().map(x -> x.getKey() + "(" + x.getValue().getRight() + ")=" + x.getValue().getLeft().stream().map(Object::toString).collect(Collectors.joining())).collect(JsonArray::new, JsonArray::add, JsonArray::addAll));
75+
JSON.add("functions", FUNCTIONS.entrySet().stream().map(x -> x.getKey() + "(" + String.join(ChatCalc.SEPARATOR, x.getValue().getRight()) + ")=" + x.getValue().getLeft().stream().map(Object::toString).collect(Collectors.joining())).collect(JsonArray::new, JsonArray::add, JsonArray::addAll));
7576
writer.write(GSON.toJson(JSON));
7677
JSON.remove("functions");
7778
writer.close();
@@ -89,11 +90,38 @@ public static void readJson() {
8990
JsonObject json = tempJson; // annoying lambda requirement
9091
DEFAULTS.forEach((key, defaultValue) -> JSON.add(key, json.get(key) instanceof JsonPrimitive primitive && primitive.isString() ? primitive : new JsonPrimitive(defaultValue)));
9192
if (json.get("functions") instanceof JsonArray array) {
92-
array.forEach(e -> FUNCTIONS.put(e.getAsString().split("\\(")[0], new Pair<>(MathEngine.tokenize(e.getAsString().split("=")[1]), e.getAsString().split("[()]")[1])));
93+
array.forEach(e -> {
94+
if (e instanceof JsonPrimitive primitive && primitive.isString()) {
95+
parseFunction(e.getAsString()).ifPresent(parsedFunction -> FUNCTIONS.put(parsedFunction.getA(), new Pair<>(parsedFunction.getB(), parsedFunction.getC())));
96+
}
97+
});
9398
}
9499
} catch (Exception ignored) { }
95100
}
96101

102+
public static Optional<Triplet<String, List<Token>, String[]>> parseFunction(String function) {
103+
int functionNameEnd = function.indexOf('(');
104+
if (functionNameEnd > 0) {
105+
String functionName = function.substring(0, functionNameEnd);
106+
int paramsEnd = function.substring(functionNameEnd).indexOf(')') + functionNameEnd;
107+
if (functionName.matches("[A-Za-z]+") && paramsEnd > 0 && function.substring(paramsEnd + 1).startsWith("=") && function.length() > paramsEnd + 2) { // I'm not commenting why this works, I know it, It's just hard to explain
108+
String[] params = function.substring(functionNameEnd + 1, paramsEnd).split(ChatCalc.SEPARATOR);
109+
for (String param : params) {
110+
if (!param.matches("[A-Za-z]")) {
111+
return Optional.empty();
112+
}
113+
}
114+
String rest = function.substring(paramsEnd + 2);
115+
try {
116+
List<Token> tokens = MathEngine.tokenize(rest);
117+
return Optional.of(new Triplet<>(functionName, tokens, params));
118+
// System.out.printf("fn: %s, params: %s, rest: %s%n", functionName, params, rest);
119+
} catch (Exception ignored) { }
120+
}
121+
}
122+
return Optional.empty();
123+
}
124+
97125
public static boolean debugTokens() {
98126
return Boolean.parseBoolean(JSON.get("debug_tokens").getAsString());
99127
}
@@ -105,13 +133,26 @@ public static void saveToChatHud(String input) {
105133
}
106134
}
107135

108-
public static double func(String name, double value) {
136+
public static double func(String name, double... values) {
109137
if (FUNCTIONS.containsKey(name)) {
138+
if (values.length != FUNCTIONS.get(name).getRight().length) {
139+
throw new IllegalArgumentException();
140+
}
110141
List<Token> tokens = new ArrayList<>(FUNCTIONS.get(name).getLeft());
111-
MathEngine.simplify(tokens, false, Optional.of(new Pair<>(FUNCTIONS.get(name).getRight(), value)));
112-
return ((NumberToken) tokens.get(0)).val;
142+
FunctionParameter[] parameters = new FunctionParameter[values.length];
143+
for (int i = 0; i < parameters.length; i++) {
144+
parameters[i] = new FunctionParameter(FUNCTIONS.get(name).getRight()[i], values[i]);
145+
}
146+
MathEngine.simplify(tokens, false, Optional.of(parameters));
147+
if (tokens.get(0) instanceof NumberToken numberToken) {
148+
return numberToken.val;
149+
}
150+
throw new IllegalArgumentException();
113151
} else {
114-
return value;
152+
if (values.length == 0) {
153+
throw new IllegalArgumentException();
154+
}
155+
return values[0];
115156
}
116157
}
117158

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package ca.rttv.chatcalc;
2+
3+
public record FunctionParameter(String name, double value) {
4+
5+
}

0 commit comments

Comments
 (0)