Skip to content
Merged
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
5 changes: 5 additions & 0 deletions src/main/interpreter/Interpreter.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import interpreter.antlr.MineScriptLexer;
import interpreter.antlr.MineScriptParser;
import interpreter.exceptions.ThreadInterruptedException;
import interpreter.types.MSMessageType;
import minescript.network.TurtleCommands;
import net.minecraft.server.MinecraftServer;
Expand All @@ -27,6 +28,7 @@ public Interpreter(String program, MinecraftServer server, ServerWorld world, Bl

@Override
public void run() {
System.out.println("Thread started");
try {
// Create a CharStream that reads from standard input
CharStream input = CharStreams.fromString(program + System.lineSeparator());
Expand All @@ -43,8 +45,11 @@ public void run() {
ParseTree tree = parser.program(); // Begin parsing at init rule
Visitor visitor = new Visitor(server, world, turtlePos, new SymbolTable());
visitor.visit(tree);
} catch (ThreadInterruptedException e) {
System.out.println(e.getMessage());
} catch (Exception e) {
TurtleCommands.print(server, e.getMessage(), MSMessageType.ERROR);
}
System.out.println("Thread finished");
}
}
41 changes: 23 additions & 18 deletions src/main/interpreter/SymbolTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,13 @@ public void enterSymbol(String name, MSType value) {
Symbol newSymbol = new Symbol(name, value);
checkRestrictedKeyWords(newSymbol);

/*If the variable is already in the current scope, update it*/
if (isVarInNewScope(name)) {
Symbol oldSymbol = hashMap.get(getPrefixName(name));
/*If a prefixed version of the variable already exists, update it*/
String shadowedSymbolName = getShadowedSymbolName(name);
if (shadowedSymbolName != null) {
Symbol oldSymbol = hashMap.get(shadowedSymbolName);
delete(oldSymbol.name);
Symbol prefixSymbol = new Symbol(oldSymbol.name, value);
add(prefixSymbol);
Symbol newShadowedSymbol = new Symbol(oldSymbol.name, value);
add(newShadowedSymbol);
return;
}

Expand Down Expand Up @@ -77,8 +78,9 @@ else if (symbol.name.equals(funcName.name())){
* @return symbol from the hash table
*/
public Symbol retrieveSymbol(String name) {
if (isVarInNewScope(name)) {
return hashMap.get(getPrefixName(name));
String shadowedSymbolName = getShadowedSymbolName(name);
if (shadowedSymbolName != null) {
return hashMap.get(shadowedSymbolName);
} else if (hashMap.containsKey(name)) {
return hashMap.get(name);
} else {
Expand Down Expand Up @@ -108,20 +110,23 @@ private void add(Symbol symbol) {
hashMap.put(symbol.name, symbol);
}

/**
* @param name name of the variable
* @return true if the variable is in the current scope
*/
private boolean isVarInNewScope(String name) {
return scopeStack.peek().stream().anyMatch(s -> s.endsWith("." + name));
}

/**
* @param name id of the variable
* @return prefix of the variable
* @return name of the symbol if a prefixed version of it exists in any of the scopes, otherwise null
*/
private String getPrefixName(String name) {
return scopeStack.peek().stream().filter(s -> s.contains("." + name)).findFirst().orElseThrow();
private String getShadowedSymbolName(String name) {
if (scopeStack.empty()) return null;

ArrayList<String> currentScope = scopeStack.peek();
if (currentScope.stream().anyMatch(s -> s.endsWith("." + name))) {
return currentScope.stream().filter(s -> s.endsWith("." + name)).findFirst().orElseThrow();
}
else {
scopeStack.pop();
String res = getShadowedSymbolName(name);
scopeStack.push(currentScope);
return res;
}
}

private record Symbol(String name, MSType value) {
Expand Down
12 changes: 7 additions & 5 deletions src/main/interpreter/Visitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import interpreter.antlr.MineScriptBaseVisitor;
import interpreter.antlr.MineScriptParser;
import interpreter.exceptions.SymbolNotFoundException;
import interpreter.exceptions.ThreadInterruptedException;
import interpreter.types.*;
import minescript.network.TurtleCommands;
import net.minecraft.block.Block;
Expand Down Expand Up @@ -446,7 +447,7 @@ public MSType visitFuncCall(MineScriptParser.FuncCallContext ctx) {
throw new RuntimeException(getFuncCallErrorMessage(id, new int[]{1}, "number", actualParams));
}

retVal = new MSNumber((int) Math.round(Math.sqrt(n.getValue())));
retVal = new MSNumber((int) Math.floor(Math.sqrt(n.getValue())));
}
case "Random" -> {
/*If no parameter is used returns a random unbounded int*/
Expand Down Expand Up @@ -477,21 +478,21 @@ public MSType visitFuncCall(MineScriptParser.FuncCallContext ctx) {

this.turtleDelay = 200 - n.getValue() * 20;
}
case "GetXPosition" -> {
case "GetXCoordinate" -> {
if (actualParams.size() != 0) {
throw new RuntimeException(getFuncCallErrorMessage(id, new int[]{0}, "", actualParams));
}

retVal = new MSNumber(pos.getX());
}
case "GetYPosition" -> {
case "GetYCoordinate" -> {
if (actualParams.size() != 0) {
throw new RuntimeException(getFuncCallErrorMessage(id, new int[]{0}, "", actualParams));
}

retVal = new MSNumber(pos.getY());
}
case "GetZPosition" -> {
case "GetZCoordinate" -> {
if (actualParams.size() != 0) {
throw new RuntimeException(getFuncCallErrorMessage(id, new int[]{0}, "", actualParams));
}
Expand Down Expand Up @@ -583,6 +584,7 @@ public MSType visitFuncCall(MineScriptParser.FuncCallContext ctx) {
} else {
TurtleCommands.print(server, expressionId + " is: " + text, messageType);
}
timeout(1);
});
}
default -> {
Expand Down Expand Up @@ -763,7 +765,7 @@ private void timeout(int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
throw new RuntimeException(e);
throw new ThreadInterruptedException("Thread was interrupted while waiting");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package interpreter.exceptions;

public class ThreadInterruptedException extends RuntimeException {
public ThreadInterruptedException(String message) { super(message); }
}
7 changes: 3 additions & 4 deletions src/main/java/minescript/block/custom/TurtleBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,9 @@ public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockSt
BlockEntity blockEntity = world.getBlockEntity(pos);

if (blockEntity instanceof TurtleBlockEntity entity) {
PacketByteBuf buf = PacketByteBufs.create();
buf.writeBlockPos(entity.getPos());

ClientPlayNetworking.send(MineScriptPackets.STOP_INTERPRETER_ID, buf);
if (entity.interpreterThread != null && entity.interpreterThread.isAlive()) {
entity.interpreterThread.interrupt();
}
}
}
super.onStateReplaced(state, world, pos, newState, moved);
Expand Down
24 changes: 21 additions & 3 deletions src/main/java/minescript/block/entity/TurtleBlockEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,37 @@ public void setTurtleInput(String input) {

@Override
public void writeNbt(NbtCompound nbt) {
nbt.putString("input", this.input.getString());
String text = input.getString();
int length = text.length();

int splits = (int) Math.ceil((double) length / 50000);
for (int i = 0; i < splits; i++) {
if (i == splits - 1)
nbt.putString("input" + i, text.substring(i * 50000));
else
nbt.putString("input" + i, text.substring(i * 50000, (i + 1) * 50000));
}

super.writeNbt(nbt);
}

@Override
public void readNbt(NbtCompound nbt) {
StringBuilder text = new StringBuilder();
int split = 0;
while (nbt.contains("input" + split)) {
text.append(nbt.getString("input" + split));
split++;
}
this.input = Text.of(text.toString());
super.readNbt(nbt);
this.input = Text.of(nbt.getString("input"));
}

@Override
public void writeScreenOpeningData(ServerPlayerEntity player, PacketByteBuf buf) {
buf.writeString(this.input.getString());
String text = this.input.getString();
buf.writeInt(text.length());
buf.writeString(text, text.length());
}

@Override
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/minescript/network/MineScriptPackets.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@
public class MineScriptPackets {

public static final Identifier START_INTERPRETER_ID = new Identifier("minescript", "start_interpreter");
public static final Identifier STOP_INTERPRETER_ID = new Identifier("minescript", "stop_interpreter");

public static void registerC2SPackets() {
ServerPlayNetworking.registerGlobalReceiver(START_INTERPRETER_ID, StartInterpreterC2SPacket::receive);
ServerPlayNetworking.registerGlobalReceiver(STOP_INTERPRETER_ID, StopInterpreterC2SPacket::receive);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class TextEditorScreenHandler extends ScreenHandler {

public TextEditorScreenHandler(int syncId, PlayerInventory inventory, PacketByteBuf buf) {
this(syncId, inventory, (TurtleBlockEntity) null);
inputText = buf.readString();
inputText = buf.readString(buf.readInt());
}

public TextEditorScreenHandler(int syncId, PlayerInventory inventory, @Nullable TurtleBlockEntity entity) {
Expand Down