Change Java whitespace handling in .editorconfig (#425)

* Change whitespace handling in .editorconfig

* Reformat code

* fix format error

* Reformat code

---------

Co-authored-by: Zoë Gidiere <duplexsys@protonmail.com>
This commit is contained in:
Astrashh
2023-11-13 11:57:01 +11:00
committed by GitHub
parent a73fda7d04
commit defd775f13
793 changed files with 7579 additions and 7577 deletions

View File

@@ -25,40 +25,40 @@ import com.dfsek.terra.api.util.StringUtil;
public class TerraScriptAddon implements AddonInitializer {
@Inject
private Platform platform;
@Inject
private BaseAddon addon;
@Override
public void initialize() {
platform.getEventManager()
.getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class)
.then(event -> {
CheckedRegistry<Structure> structureRegistry = event.getPack().getOrCreateRegistry(Structure.class);
CheckedRegistry<LootTable> lootRegistry = event.getPack().getOrCreateRegistry(LootTable.class);
event.getPack().getLoader().open("", ".tesf").thenEntries(
entries ->
entries.stream()
.parallel()
.map(entry -> {
try {
String id = StringUtil.fileName(entry.getKey());
return new StructureScript(entry.getValue(),
addon.key(id),
platform,
structureRegistry,
lootRegistry,
event.getPack().getOrCreateRegistry(FunctionBuilder.class));
} catch(ParseException e) {
throw new RuntimeException("Failed to load script \"" + entry.getKey() + "\"", e);
}
})
.toList()
.forEach(structureRegistry::register))
.close();
})
.priority(100)
.failThrough();
.getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class)
.then(event -> {
CheckedRegistry<Structure> structureRegistry = event.getPack().getOrCreateRegistry(Structure.class);
CheckedRegistry<LootTable> lootRegistry = event.getPack().getOrCreateRegistry(LootTable.class);
event.getPack().getLoader().open("", ".tesf").thenEntries(
entries ->
entries.stream()
.parallel()
.map(entry -> {
try {
String id = StringUtil.fileName(entry.getKey());
return new StructureScript(entry.getValue(),
addon.key(id),
platform,
structureRegistry,
lootRegistry,
event.getPack().getOrCreateRegistry(FunctionBuilder.class));
} catch(ParseException e) {
throw new RuntimeException("Failed to load script \"" + entry.getKey() + "\"", e);
}
})
.toList()
.forEach(structureRegistry::register))
.close();
})
.priority(100)
.failThrough();
}
}

View File

@@ -69,21 +69,21 @@ public class Parser {
private final String data;
private final Map<String, FunctionBuilder<? extends Function<?>>> functions = new HashMap<>();
private final List<String> ignoredFunctions = new ArrayList<>();
public Parser(String data) {
this.data = data;
}
public Parser registerFunction(String name, FunctionBuilder<? extends Function<?>> functionBuilder) {
functions.put(name, functionBuilder);
return this;
}
public Parser ignoreFunction(String name) {
ignoredFunctions.add(name);
return this;
}
/**
* Parse input
*
@@ -95,43 +95,43 @@ public class Parser {
ScopeBuilder scopeBuilder = new ScopeBuilder();
return new Executable(parseBlock(new Tokenizer(data), false, scopeBuilder), scopeBuilder);
}
private Keyword<?> parseLoopLike(Tokenizer tokens, boolean loop, ScopeBuilder scopeBuilder) throws ParseException {
Token identifier = tokens.consume();
ParserUtil.checkType(identifier, Token.Type.IF_STATEMENT, Token.Type.WHILE_LOOP, Token.Type.FOR_LOOP);
ParserUtil.checkType(tokens.consume(), Token.Type.GROUP_BEGIN);
return switch(identifier.getType()) {
case FOR_LOOP -> parseForLoop(tokens, identifier.getPosition(), scopeBuilder);
case IF_STATEMENT -> parseIfStatement(tokens, identifier.getPosition(), loop, scopeBuilder);
case WHILE_LOOP -> parseWhileLoop(tokens, identifier.getPosition(), scopeBuilder);
default -> throw new UnsupportedOperationException(
"Unknown keyword " + identifier.getContent() + ": " + identifier.getPosition());
"Unknown keyword " + identifier.getContent() + ": " + identifier.getPosition());
};
}
private WhileKeyword parseWhileLoop(Tokenizer tokens, Position start, ScopeBuilder scopeBuilder) {
Returnable<?> first = parseExpression(tokens, true, scopeBuilder);
ParserUtil.checkReturnType(first, Returnable.ReturnType.BOOLEAN);
ParserUtil.checkType(tokens.consume(), Token.Type.GROUP_END);
return new WhileKeyword(parseStatementBlock(tokens, true, scopeBuilder), (Returnable<Boolean>) first, start); // While loop
}
private IfKeyword parseIfStatement(Tokenizer tokens, Position start, boolean loop, ScopeBuilder scopeBuilder) {
Returnable<?> condition = parseExpression(tokens, true, scopeBuilder);
ParserUtil.checkReturnType(condition, Returnable.ReturnType.BOOLEAN);
ParserUtil.checkType(tokens.consume(), Token.Type.GROUP_END);
Block elseBlock = null;
Block statement = parseStatementBlock(tokens, loop, scopeBuilder);
List<Pair<Returnable<Boolean>, Block>> elseIf = new ArrayList<>();
while(tokens.hasNext() && tokens.get().getType().equals(Token.Type.ELSE)) {
tokens.consume(); // Consume else.
if(tokens.get().getType().equals(Token.Type.IF_STATEMENT)) {
@@ -144,12 +144,12 @@ public class Parser {
break; // Else must be last.
}
}
return new IfKeyword(statement, (Returnable<Boolean>) condition, elseIf, elseBlock, start); // If statement
}
private Block parseStatementBlock(Tokenizer tokens, boolean loop, ScopeBuilder scopeBuilder) {
if(tokens.get().getType().equals(Token.Type.BLOCK_BEGIN)) {
ParserUtil.checkType(tokens.consume(), Token.Type.BLOCK_BEGIN);
Block block = parseBlock(tokens, loop, scopeBuilder);
@@ -162,7 +162,7 @@ public class Parser {
return block;
}
}
private ForKeyword parseForLoop(Tokenizer tokens, Position start, ScopeBuilder scopeBuilder) {
scopeBuilder = scopeBuilder.sub(); // new scope
Token f = tokens.get();
@@ -179,19 +179,19 @@ public class Parser {
Returnable<?> conditional = parseExpression(tokens, true, scopeBuilder);
ParserUtil.checkReturnType(conditional, Returnable.ReturnType.BOOLEAN);
ParserUtil.checkType(tokens.consume(), Token.Type.STATEMENT_END);
Item<?> incrementer;
Token token = tokens.get();
if(scopeBuilder.contains(token.getContent())) { // Assume variable assignment
incrementer = parseAssignment(tokens, scopeBuilder);
} else incrementer = parseFunction(tokens, true, scopeBuilder);
ParserUtil.checkType(tokens.consume(), Token.Type.GROUP_END);
return new ForKeyword(parseStatementBlock(tokens, true, scopeBuilder), initializer, (Returnable<Boolean>) conditional, incrementer,
start);
start);
}
private Returnable<?> parseExpression(Tokenizer tokens, boolean full, ScopeBuilder scopeBuilder) {
boolean booleanInverted = false; // Check for boolean not operator
boolean negate = false;
@@ -202,11 +202,11 @@ public class Parser {
negate = true;
tokens.consume();
}
Token id = tokens.get();
ParserUtil.checkType(id, Token.Type.IDENTIFIER, Token.Type.BOOLEAN, Token.Type.STRING, Token.Type.NUMBER, Token.Type.GROUP_BEGIN);
Returnable<?> expression;
if(id.isConstant()) {
expression = parseConstantExpression(tokens);
@@ -225,10 +225,10 @@ public class Parser {
case BOOLEAN -> new BoolVariableReferenceNode(id.getPosition(), varType, scopeBuilder.getIndex(varId));
default -> throw new ParseException("Illegal type for variable reference: " + varType, id.getPosition());
};
} else throw new ParseException("Unexpected token \" " + id.getContent() + "\"", id.getPosition());
}
if(booleanInverted) { // Invert operation if boolean not detected
ParserUtil.checkReturnType(expression, Returnable.ReturnType.BOOLEAN);
expression = new BooleanNotOperation((Returnable<Boolean>) expression, expression.getPosition());
@@ -236,13 +236,13 @@ public class Parser {
ParserUtil.checkReturnType(expression, Returnable.ReturnType.NUMBER);
expression = new NegationOperation((Returnable<Number>) expression, expression.getPosition());
}
if(full && tokens.get().isBinaryOperator()) { // Parse binary operations
return parseBinaryOperation(expression, tokens, scopeBuilder);
}
return expression;
}
private ConstantExpression<?> parseConstantExpression(Tokenizer tokens) {
Token constantToken = tokens.consume();
Position position = constantToken.getPosition();
@@ -256,24 +256,24 @@ public class Parser {
return new BooleanConstant(Boolean.parseBoolean(constantToken.getContent()), position);
default:
throw new UnsupportedOperationException(
"Unsupported constant token: " + constantToken.getType() + " at position: " + position);
"Unsupported constant token: " + constantToken.getType() + " at position: " + position);
}
}
private Returnable<?> parseGroup(Tokenizer tokens, ScopeBuilder scopeBuilder) {
ParserUtil.checkType(tokens.consume(), Token.Type.GROUP_BEGIN);
Returnable<?> expression = parseExpression(tokens, true, scopeBuilder); // Parse inside of group as a separate expression
ParserUtil.checkType(tokens.consume(), Token.Type.GROUP_END);
return expression;
}
private BinaryOperation<?, ?> parseBinaryOperation(Returnable<?> left, Tokenizer tokens,
ScopeBuilder scopeBuilder) {
Token binaryOperator = tokens.consume();
ParserUtil.checkBinaryOperator(binaryOperator);
Returnable<?> right = parseExpression(tokens, false, scopeBuilder);
Token other = tokens.get();
if(ParserUtil.hasPrecedence(binaryOperator.getType(), other.getType())) {
return assemble(left, parseBinaryOperation(right, tokens, scopeBuilder), binaryOperator);
@@ -282,7 +282,7 @@ public class Parser {
}
return assemble(left, right, binaryOperator);
}
private BinaryOperation<?, ?> assemble(Returnable<?> left, Returnable<?> right, Token binaryOperator) {
if(binaryOperator.isStrictNumericOperator())
ParserUtil.checkArithmeticOperation(left, right, binaryOperator); // Numeric type checking
@@ -309,7 +309,7 @@ public class Parser {
return new LessThanStatement((Returnable<Number>) left, (Returnable<Number>) right, binaryOperator.getPosition());
case GREATER_THAN_OR_EQUALS_OPERATOR:
return new GreaterOrEqualsThanStatement((Returnable<Number>) left, (Returnable<Number>) right,
binaryOperator.getPosition());
binaryOperator.getPosition());
case LESS_THAN_OR_EQUALS_OPERATOR:
return new LessThanOrEqualsStatement((Returnable<Number>) left, (Returnable<Number>) right, binaryOperator.getPosition());
case BOOLEAN_AND:
@@ -322,25 +322,25 @@ public class Parser {
throw new UnsupportedOperationException("Unsupported binary operator: " + binaryOperator.getType());
}
}
private VariableAssignmentNode<?> parseVariableDeclaration(Tokenizer tokens, ScopeBuilder scopeBuilder) {
Token type = tokens.consume();
ParserUtil.checkType(type, Token.Type.STRING_VARIABLE, Token.Type.BOOLEAN_VARIABLE, Token.Type.NUMBER_VARIABLE);
Returnable.ReturnType returnType = ParserUtil.getVariableReturnType(type);
ParserUtil.checkVarType(type, returnType); // Check for type mismatch
Token identifier = tokens.consume();
ParserUtil.checkType(identifier, Token.Type.IDENTIFIER);
if(functions.containsKey(identifier.getContent()) || scopeBuilder.contains(identifier.getContent()))
throw new ParseException(identifier.getContent() + " is already defined in this scope", identifier.getPosition());
ParserUtil.checkType(tokens.consume(), Token.Type.ASSIGNMENT);
Returnable<?> value = parseExpression(tokens, true, scopeBuilder);
ParserUtil.checkReturnType(value, returnType);
String id = identifier.getContent();
return switch(value.returnType()) {
case NUMBER -> new NumAssignmentNode((Returnable<Number>) value, identifier.getPosition(), scopeBuilder.num(id));
case STRING -> new StrAssignmentNode((Returnable<String>) value, identifier.getPosition(), scopeBuilder.str(id));
@@ -348,14 +348,14 @@ public class Parser {
default -> throw new ParseException("Illegal type for variable declaration: " + type, value.getPosition());
};
}
private Block parseBlock(Tokenizer tokens, boolean loop, ScopeBuilder scopeBuilder) {
List<Item<?>> parsedItems = new ArrayList<>();
scopeBuilder = scopeBuilder.sub();
Token first = tokens.get();
while(tokens.hasNext()) {
Token token = tokens.get();
if(token.getType().equals(Token.Type.BLOCK_END)) break; // Stop parsing at block end.
@@ -367,16 +367,16 @@ public class Parser {
}
return new Block(parsedItems, first.getPosition());
}
private Item<?> parseItem(Tokenizer tokens, boolean loop, ScopeBuilder scopeBuilder) {
Token token = tokens.get();
if(loop) ParserUtil.checkType(token, Token.Type.IDENTIFIER, Token.Type.IF_STATEMENT, Token.Type.WHILE_LOOP, Token.Type.FOR_LOOP,
Token.Type.NUMBER_VARIABLE, Token.Type.STRING_VARIABLE, Token.Type.BOOLEAN_VARIABLE,
Token.Type.RETURN, Token.Type.BREAK, Token.Type.CONTINUE, Token.Type.FAIL);
Token.Type.NUMBER_VARIABLE, Token.Type.STRING_VARIABLE, Token.Type.BOOLEAN_VARIABLE,
Token.Type.RETURN, Token.Type.BREAK, Token.Type.CONTINUE, Token.Type.FAIL);
else ParserUtil.checkType(token, Token.Type.IDENTIFIER, Token.Type.IF_STATEMENT, Token.Type.WHILE_LOOP, Token.Type.FOR_LOOP,
Token.Type.NUMBER_VARIABLE, Token.Type.STRING_VARIABLE, Token.Type.BOOLEAN_VARIABLE, Token.Type.RETURN,
Token.Type.FAIL);
Token.Type.NUMBER_VARIABLE, Token.Type.STRING_VARIABLE, Token.Type.BOOLEAN_VARIABLE, Token.Type.RETURN,
Token.Type.FAIL);
if(token.isLoopLike()) { // Parse loop-like tokens (if, while, etc)
return parseLoopLike(tokens, loop, scopeBuilder);
} else if(token.isIdentifier()) { // Parse identifiers
@@ -384,31 +384,31 @@ public class Parser {
return parseAssignment(tokens, scopeBuilder);
} else return parseFunction(tokens, true, scopeBuilder);
} else if(token.isVariableDeclaration()) {
return parseVariableDeclaration(tokens, scopeBuilder);
} else if(token.getType().equals(Token.Type.RETURN)) return new ReturnKeyword(tokens.consume().getPosition());
else if(token.getType().equals(Token.Type.BREAK)) return new BreakKeyword(tokens.consume().getPosition());
else if(token.getType().equals(Token.Type.CONTINUE)) return new ContinueKeyword(tokens.consume().getPosition());
else if(token.getType().equals(Token.Type.FAIL)) return new FailKeyword(tokens.consume().getPosition());
else throw new UnsupportedOperationException("Unexpected token " + token.getType() + ": " + token.getPosition());
}
private VariableAssignmentNode<?> parseAssignment(Tokenizer tokens, ScopeBuilder scopeBuilder) {
Token identifier = tokens.consume();
ParserUtil.checkType(identifier, Token.Type.IDENTIFIER);
ParserUtil.checkType(tokens.consume(), Token.Type.ASSIGNMENT);
Returnable<?> value = parseExpression(tokens, true, scopeBuilder);
String id = identifier.getContent();
ParserUtil.checkReturnType(value, scopeBuilder.getType(id));
ReturnType type = value.returnType();
return switch(type) {
case NUMBER -> new NumAssignmentNode((Returnable<Number>) value, identifier.getPosition(), scopeBuilder.getIndex(id));
case STRING -> new StrAssignmentNode((Returnable<String>) value, identifier.getPosition(), scopeBuilder.getIndex(id));
@@ -416,48 +416,48 @@ public class Parser {
default -> throw new ParseException("Illegal type for variable assignment: " + type, value.getPosition());
};
}
private Function<?> parseFunction(Tokenizer tokens, boolean fullStatement, ScopeBuilder scopeBuilder) {
Token identifier = tokens.consume();
ParserUtil.checkType(identifier, Token.Type.IDENTIFIER); // First token must be identifier
if(!functions.containsKey(identifier.getContent()))
throw new ParseException("No such function \"" + identifier.getContent() + "\"", identifier.getPosition());
ParserUtil.checkType(tokens.consume(), Token.Type.GROUP_BEGIN); // Second is body begin
List<Returnable<?>> args = getArgs(tokens, scopeBuilder); // Extract arguments, consume the rest.
ParserUtil.checkType(tokens.consume(), Token.Type.GROUP_END); // Remove body end
if(fullStatement) ParserUtil.checkType(tokens.get(), Token.Type.STATEMENT_END);
if(ignoredFunctions.contains(identifier.getContent())) {
return Function.NULL;
}
if(functions.containsKey(identifier.getContent())) {
FunctionBuilder<?> builder = functions.get(identifier.getContent());
if(builder.argNumber() != -1 && args.size() != builder.argNumber())
throw new ParseException("Expected " + builder.argNumber() + " arguments, found " + args.size(), identifier.getPosition());
for(int i = 0; i < args.size(); i++) {
Returnable<?> argument = args.get(i);
if(builder.getArgument(i) == null)
throw new ParseException("Unexpected argument at position " + i + " in function " + identifier.getContent(),
identifier.getPosition());
identifier.getPosition());
ParserUtil.checkReturnType(argument, builder.getArgument(i));
}
return builder.build(args, identifier.getPosition());
}
throw new UnsupportedOperationException("Unsupported function: " + identifier.getContent());
}
private List<Returnable<?>> getArgs(Tokenizer tokens, ScopeBuilder scopeBuilder) {
List<Returnable<?>> args = new ArrayList<>();
while(!tokens.get().getType().equals(Token.Type.GROUP_END)) {
args.add(parseExpression(tokens, true, scopeBuilder));
ParserUtil.checkType(tokens.get(), Token.Type.SEPARATOR, Token.Type.GROUP_END);

View File

@@ -18,72 +18,72 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Token;
public class ParserUtil {
private static final Map<Token.Type, Map<Token.Type, Boolean>> PRECEDENCE = new HashMap<>(); // If second has precedence, true.
private static final List<Token.Type> ARITHMETIC = Arrays.asList(Token.Type.ADDITION_OPERATOR, Token.Type.SUBTRACTION_OPERATOR,
Token.Type.MULTIPLICATION_OPERATOR, Token.Type.DIVISION_OPERATOR,
Token.Type.MODULO_OPERATOR);
Token.Type.MULTIPLICATION_OPERATOR, Token.Type.DIVISION_OPERATOR,
Token.Type.MODULO_OPERATOR);
private static final List<Token.Type> COMPARISON = Arrays.asList(Token.Type.EQUALS_OPERATOR, Token.Type.NOT_EQUALS_OPERATOR,
Token.Type.LESS_THAN_OPERATOR, Token.Type.LESS_THAN_OR_EQUALS_OPERATOR,
Token.Type.GREATER_THAN_OPERATOR,
Token.Type.GREATER_THAN_OR_EQUALS_OPERATOR);
Token.Type.LESS_THAN_OPERATOR, Token.Type.LESS_THAN_OR_EQUALS_OPERATOR,
Token.Type.GREATER_THAN_OPERATOR,
Token.Type.GREATER_THAN_OR_EQUALS_OPERATOR);
static { // Setup precedence
Map<Token.Type, Boolean> add = new HashMap<>(); // Addition/subtraction before Multiplication/division.
add.put(Token.Type.MULTIPLICATION_OPERATOR, true);
add.put(Token.Type.DIVISION_OPERATOR, true);
PRECEDENCE.put(Token.Type.ADDITION_OPERATOR, add);
PRECEDENCE.put(Token.Type.SUBTRACTION_OPERATOR, add);
Map<Token.Type, Boolean> numericBoolean = new HashMap<>();
ARITHMETIC.forEach(op -> numericBoolean.put(op, true)); // Numbers before comparison
COMPARISON.forEach(op -> PRECEDENCE.put(op, numericBoolean));
Map<Token.Type, Boolean> booleanOps = new HashMap<>();
ARITHMETIC.forEach(op -> booleanOps.put(op, true)); // Everything before boolean
COMPARISON.forEach(op -> booleanOps.put(op, true));
PRECEDENCE.put(Token.Type.BOOLEAN_AND, booleanOps);
PRECEDENCE.put(Token.Type.BOOLEAN_OR, booleanOps);
}
public static void checkType(Token token, Token.Type... expected) {
for(Token.Type type : expected) if(token.getType().equals(type)) return;
throw new ParseException("Expected " + Arrays.toString(expected) + " but found " + token.getType(), token.getPosition());
}
public static void checkReturnType(Returnable<?> returnable, Returnable.ReturnType... types) {
for(Returnable.ReturnType type : types) if(returnable.returnType().equals(type)) return;
throw new ParseException("Expected " + Arrays.toString(types) + " but found " + returnable.returnType(), returnable.getPosition());
}
public static void checkArithmeticOperation(Returnable<?> left, Returnable<?> right, Token operation) {
if(!left.returnType().equals(Returnable.ReturnType.NUMBER) || !right.returnType().equals(Returnable.ReturnType.NUMBER)) {
throw new ParseException(
"Operation " + operation.getType() + " not supported between " + left.returnType() + " and " + right.returnType(),
operation.getPosition());
"Operation " + operation.getType() + " not supported between " + left.returnType() + " and " + right.returnType(),
operation.getPosition());
}
}
public static void checkBooleanOperation(Returnable<?> left, Returnable<?> right, Token operation) {
if(!left.returnType().equals(Returnable.ReturnType.BOOLEAN) || !right.returnType().equals(Returnable.ReturnType.BOOLEAN)) {
throw new ParseException(
"Operation " + operation.getType() + " not supported between " + left.returnType() + " and " + right.returnType(),
operation.getPosition());
"Operation " + operation.getType() + " not supported between " + left.returnType() + " and " + right.returnType(),
operation.getPosition());
}
}
public static void checkVarType(Token token, Returnable.ReturnType returnType) {
if(returnType.equals(Returnable.ReturnType.STRING) && token.getType().equals(Token.Type.STRING_VARIABLE)) return;
if(returnType.equals(Returnable.ReturnType.NUMBER) && token.getType().equals(Token.Type.NUMBER_VARIABLE)) return;
if(returnType.equals(Returnable.ReturnType.BOOLEAN) && token.getType().equals(Token.Type.BOOLEAN_VARIABLE)) return;
throw new ParseException("Type mismatch, cannot convert from " + returnType + " to " + token.getType(), token.getPosition());
}
/**
* Checks if token is a binary operator
*
@@ -95,17 +95,17 @@ public class ParserUtil {
if(!token.isBinaryOperator())
throw new ParseException("Expected binary operator, found " + token.getType(), token.getPosition());
}
public static Returnable.ReturnType getVariableReturnType(Token varToken) {
return switch(varToken.getType()) {
case NUMBER_VARIABLE -> Returnable.ReturnType.NUMBER;
case STRING_VARIABLE -> Returnable.ReturnType.STRING;
case BOOLEAN_VARIABLE -> Returnable.ReturnType.BOOLEAN;
default -> throw new ParseException("Unexpected token " + varToken.getType() + "; expected variable declaration",
varToken.getPosition());
varToken.getPosition());
};
}
public static boolean hasPrecedence(Token.Type first, Token.Type second) {
if(!PRECEDENCE.containsKey(first)) return false;
Map<Token.Type, Boolean> pre = PRECEDENCE.get(first);

View File

@@ -16,22 +16,22 @@ public class ParseException extends RuntimeException {
@Serial
private static final long serialVersionUID = 6744390543046766386L;
private final Position position;
public ParseException(String message, Position position) {
super(message);
this.position = position;
}
public ParseException(String message, Position position, Throwable cause) {
super(message, cause);
this.position = position;
}
@Override
public String getMessage() {
return super.getMessage() + ": " + position;
}
public Position getPosition() {
return position;
}

View File

@@ -15,12 +15,12 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class Block implements Item<Block.ReturnInfo<?>> {
private final List<Item<?>> items;
private final Position position;
public Block(List<Item<?>> items, Position position) {
this.items = items;
this.position = position;
}
@Override
public ReturnInfo<?> apply(ImplementationArguments implementationArguments, Scope scope) {
for(Item<?> item : items) {
@@ -31,44 +31,44 @@ public class Block implements Item<Block.ReturnInfo<?>> {
}
return new ReturnInfo<>(ReturnLevel.NONE, null);
}
@Override
public Position getPosition() {
return position;
}
public enum ReturnLevel {
NONE(false),
BREAK(false),
CONTINUE(false),
RETURN(true),
FAIL(true);
private final boolean returnFast;
ReturnLevel(boolean returnFast) {
this.returnFast = returnFast;
}
public boolean isReturnFast() {
return returnFast;
}
}
public static class ReturnInfo<T> {
private final ReturnLevel level;
private final T data;
public ReturnInfo(ReturnLevel level, T data) {
this.level = level;
this.data = data;
}
public ReturnLevel getLevel() {
return level;
}
public T getData() {
return data;
}

View File

@@ -7,12 +7,12 @@ import com.dfsek.terra.addons.terrascript.parser.lang.Scope.ScopeBuilder;
public class Executable {
private final Block script;
private final ThreadLocal<Scope> scope;
public Executable(Block script, ScopeBuilder scopeBuilder) {
this.script = script;
this.scope = ThreadLocal.withInitial(scopeBuilder::build);
}
public boolean execute(ImplementationArguments arguments) {
return script.apply(arguments, scope.get()).getLevel() != Block.ReturnLevel.FAIL;
}

View File

@@ -12,14 +12,14 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public interface Item<T> {
T apply(ImplementationArguments implementationArguments, Scope scope);
default double applyDouble(ImplementationArguments implementationArguments, Scope scope) {
throw new UnsupportedOperationException("Cannot apply " + this + " as double");
}
default boolean applyBoolean(ImplementationArguments implementationArguments, Scope scope) {
throw new UnsupportedOperationException("Cannot apply " + this + " as double");
}
Position getPosition();
}

View File

@@ -9,20 +9,20 @@ package com.dfsek.terra.addons.terrascript.parser.lang;
public interface Returnable<T> extends Item<T> {
ReturnType returnType();
enum ReturnType {
NUMBER(true),
STRING(true),
BOOLEAN(false),
VOID(false),
OBJECT(false);
private final boolean comparable;
ReturnType(boolean comparable) {
this.comparable = comparable;
}
public boolean isComparable() {
return comparable;
}

View File

@@ -12,46 +12,46 @@ public class Scope {
private final double[] num;
private final boolean[] bool;
private final String[] str;
private Scope(int numSize, int boolSize, int strSize) {
this.num = new double[numSize];
this.bool = new boolean[boolSize];
this.str = new String[strSize];
}
public double getNum(int index) {
return num[index];
}
public boolean getBool(int index) {
return bool[index];
}
public String getStr(int index) {
return str[index];
}
public void setNum(int index, double value) {
num[index] = value;
}
public void setBool(int index, boolean value) {
bool[index] = value;
}
public void setStr(int index, String value) {
str[index] = value;
}
public static final class ScopeBuilder {
private final Map<String, Pair<Integer, ReturnType>> indices;
private int numSize, boolSize, strSize = 0;
private ScopeBuilder parent;
public ScopeBuilder() {
this.indices = new HashMap<>();
}
private ScopeBuilder(ScopeBuilder parent) {
this.parent = parent;
this.numSize = parent.numSize;
@@ -59,22 +59,22 @@ public class Scope {
this.strSize = parent.strSize;
this.indices = new HashMap<>(parent.indices);
}
public Scope build() {
return new Scope(numSize, boolSize, strSize);
}
public ScopeBuilder sub() {
return new ScopeBuilder(this);
}
private String check(String id) {
if(indices.containsKey(id)) {
throw new IllegalArgumentException("Variable with ID " + id + " already registered.");
}
return id;
}
public int num(String id) {
int num = numSize;
indices.put(check(id), Pair.of(num, ReturnType.NUMBER));
@@ -82,7 +82,7 @@ public class Scope {
updateNumSize(numSize);
return num;
}
public int str(String id) {
int str = strSize;
indices.put(check(id), Pair.of(str, ReturnType.STRING));
@@ -90,7 +90,7 @@ public class Scope {
updateStrSize(strSize);
return str;
}
public int bool(String id) {
int bool = boolSize;
indices.put(check(id), Pair.of(bool, ReturnType.BOOLEAN));
@@ -98,37 +98,37 @@ public class Scope {
updateBoolSize(boolSize);
return bool;
}
private void updateBoolSize(int size) {
this.boolSize = Math.max(boolSize, size);
if(parent != null) {
parent.updateBoolSize(size);
}
}
private void updateNumSize(int size) {
this.numSize = Math.max(numSize, size);
if(parent != null) {
parent.updateNumSize(size);
}
}
private void updateStrSize(int size) {
this.strSize = Math.max(strSize, size);
if(parent != null) {
parent.updateStrSize(size);
}
}
public int getIndex(String id) {
return indices.get(id).getLeft();
}
public ReturnType getType(String id) {
return indices.get(id).getRight();
}
public boolean contains(String id) {
return indices.containsKey(id);
}

View File

@@ -14,17 +14,17 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class BooleanConstant extends ConstantExpression<Boolean> {
private final boolean constant;
public BooleanConstant(Boolean constant, Position position) {
super(constant, position);
this.constant = constant;
}
@Override
public boolean applyBoolean(ImplementationArguments implementationArguments, Scope scope) {
return constant;
}
@Override
public ReturnType returnType() {
return ReturnType.BOOLEAN;

View File

@@ -16,22 +16,22 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public abstract class ConstantExpression<T> implements Returnable<T> {
private final T constant;
private final Position position;
public ConstantExpression(T constant, Position position) {
this.constant = constant;
this.position = position;
}
@Override
public T apply(ImplementationArguments implementationArguments, Scope scope) {
return constant;
}
@Override
public Position getPosition() {
return position;
}
public T getConstant() {
return constant;
}

View File

@@ -15,17 +15,17 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class NumericConstant extends ConstantExpression<Number> {
private final double constant;
public NumericConstant(Number constant, Position position) {
super(constant, position);
this.constant = constant.doubleValue();
}
@Override
public double applyDouble(ImplementationArguments implementationArguments, Scope scope) {
return constant;
}
@Override
public Returnable.ReturnType returnType() {
return Returnable.ReturnType.NUMBER;

View File

@@ -15,7 +15,7 @@ public class StringConstant extends ConstantExpression<String> {
public StringConstant(String constant, Position position) {
super(constant, position);
}
@Override
public Returnable.ReturnType returnType() {
return Returnable.ReturnType.STRING;

View File

@@ -19,23 +19,23 @@ public interface Function<T> extends Returnable<T> {
public ReturnType returnType() {
return null;
}
@Override
public Object apply(ImplementationArguments implementationArguments, Scope scope) {
return null;
}
@Override
public Position getPosition() {
return null;
}
};
@Override
default double applyDouble(ImplementationArguments implementationArguments, Scope scope) {
return ((Number) apply(implementationArguments, scope)).doubleValue();
}
@Override
default boolean applyBoolean(ImplementationArguments implementationArguments, Scope scope) {
return (Boolean) apply(implementationArguments, scope);

View File

@@ -15,8 +15,8 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public interface FunctionBuilder<T extends Function<?>> {
T build(List<Returnable<?>> argumentList, Position position);
int argNumber();
Returnable.ReturnType getArgument(int position);
}

View File

@@ -16,21 +16,21 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class BreakKeyword implements Keyword<Block.ReturnInfo<?>> {
private final Position position;
public BreakKeyword(Position position) {
this.position = position;
}
@Override
public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments, Scope scope) {
return new Block.ReturnInfo<>(Block.ReturnLevel.BREAK, null);
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;

View File

@@ -16,21 +16,21 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class ContinueKeyword implements Keyword<Block.ReturnInfo<?>> {
private final Position position;
public ContinueKeyword(Position position) {
this.position = position;
}
@Override
public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments, Scope scope) {
return new Block.ReturnInfo<>(Block.ReturnLevel.CONTINUE, null);
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;

View File

@@ -16,21 +16,21 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class FailKeyword implements Keyword<Block.ReturnInfo<?>> {
private final Position position;
public FailKeyword(Position position) {
this.position = position;
}
@Override
public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments, Scope scope) {
return new Block.ReturnInfo<>(Block.ReturnLevel.FAIL, null);
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;

View File

@@ -16,21 +16,21 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class ReturnKeyword implements Keyword<Block.ReturnInfo<?>> {
private final Position position;
public ReturnKeyword(Position position) {
this.position = position;
}
@Override
public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments, Scope scope) {
return new Block.ReturnInfo<>(Block.ReturnLevel.RETURN, null);
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;

View File

@@ -22,7 +22,7 @@ public class ForKeyword implements Keyword<Block.ReturnInfo<?>> {
private final Returnable<Boolean> statement;
private final Item<?> incrementer;
private final Position position;
public ForKeyword(Block conditional, Item<?> initializer, Returnable<Boolean> statement, Item<?> incrementer, Position position) {
this.conditional = conditional;
this.initializer = initializer;
@@ -30,7 +30,7 @@ public class ForKeyword implements Keyword<Block.ReturnInfo<?>> {
this.incrementer = incrementer;
this.position = position;
}
@Override
public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments, Scope scope) {
for(initializer.apply(implementationArguments, scope);
@@ -42,12 +42,12 @@ public class ForKeyword implements Keyword<Block.ReturnInfo<?>> {
}
return new Block.ReturnInfo<>(Block.ReturnLevel.NONE, null);
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;

View File

@@ -26,7 +26,7 @@ public class IfKeyword implements Keyword<Block.ReturnInfo<?>> {
private final Position position;
private final List<Pair<Returnable<Boolean>, Block>> elseIf;
private final Block elseBlock;
public IfKeyword(Block conditional, Returnable<Boolean> statement, List<Pair<Returnable<Boolean>, Block>> elseIf,
@Nullable Block elseBlock, Position position) {
this.conditional = conditional;
@@ -35,7 +35,7 @@ public class IfKeyword implements Keyword<Block.ReturnInfo<?>> {
this.elseIf = elseIf;
this.elseBlock = elseBlock;
}
@Override
public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments, Scope scope) {
if(statement.apply(implementationArguments, scope)) return conditional.apply(implementationArguments, scope);
@@ -49,12 +49,12 @@ public class IfKeyword implements Keyword<Block.ReturnInfo<?>> {
}
return new Block.ReturnInfo<>(Block.ReturnLevel.NONE, null);
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;

View File

@@ -19,13 +19,13 @@ public class WhileKeyword implements Keyword<Block.ReturnInfo<?>> {
private final Block conditional;
private final Returnable<Boolean> statement;
private final Position position;
public WhileKeyword(Block conditional, Returnable<Boolean> statement, Position position) {
this.conditional = conditional;
this.statement = statement;
this.position = position;
}
@Override
public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments, Scope scope) {
while(statement.apply(implementationArguments, scope)) {
@@ -35,12 +35,12 @@ public class WhileKeyword implements Keyword<Block.ReturnInfo<?>> {
}
return new Block.ReturnInfo<>(Block.ReturnLevel.NONE, null);
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;

View File

@@ -15,13 +15,13 @@ public abstract class BinaryOperation<I, O> implements Returnable<O> {
protected final Returnable<I> left;
protected final Returnable<I> right;
private final Position start;
public BinaryOperation(Returnable<I> left, Returnable<I> right, Position start) {
this.left = left;
this.right = right;
this.start = start;
}
@Override
public Position getPosition() {
return start;

View File

@@ -17,17 +17,17 @@ public class BooleanAndOperation extends BinaryOperation<Boolean, Boolean> {
public BooleanAndOperation(Returnable<Boolean> left, Returnable<Boolean> right, Position start) {
super(left, right, start);
}
@Override
public ReturnType returnType() {
return ReturnType.BOOLEAN;
}
@Override
public Boolean apply(ImplementationArguments implementationArguments, Scope scope) {
return applyBoolean(implementationArguments, scope);
}
@Override
public boolean applyBoolean(ImplementationArguments implementationArguments, Scope scope) {
return left.applyBoolean(implementationArguments, scope) && right.applyBoolean(implementationArguments, scope);

View File

@@ -17,17 +17,17 @@ public class BooleanNotOperation extends UnaryOperation<Boolean> {
public BooleanNotOperation(Returnable<Boolean> input, Position position) {
super(input, position);
}
@Override
public Boolean apply(ImplementationArguments implementationArguments, Scope scope) {
return applyBoolean(implementationArguments, scope);
}
@Override
public boolean applyBoolean(ImplementationArguments implementationArguments, Scope scope) {
return !input.applyBoolean(implementationArguments, scope);
}
@Override
public ReturnType returnType() {
return ReturnType.BOOLEAN;

View File

@@ -17,17 +17,17 @@ public class BooleanOrOperation extends BinaryOperation<Boolean, Boolean> {
public BooleanOrOperation(Returnable<Boolean> left, Returnable<Boolean> right, Position start) {
super(left, right, start);
}
@Override
public Boolean apply(ImplementationArguments implementationArguments, Scope scope) {
return applyBoolean(implementationArguments, scope);
}
@Override
public boolean applyBoolean(ImplementationArguments implementationArguments, Scope scope) {
return left.applyBoolean(implementationArguments, scope) || right.applyBoolean(implementationArguments, scope);
}
@Override
public ReturnType returnType() {
return ReturnType.BOOLEAN;

View File

@@ -17,7 +17,7 @@ public class ConcatenationOperation extends BinaryOperation<Object, Object> {
public ConcatenationOperation(Returnable<Object> left, Returnable<Object> right, Position position) {
super(left, right, position);
}
private static String toString(Object object) {
String s = object.toString();
if(object instanceof Double) {
@@ -28,12 +28,12 @@ public class ConcatenationOperation extends BinaryOperation<Object, Object> {
}
return s;
}
@Override
public Returnable.ReturnType returnType() {
return Returnable.ReturnType.STRING;
}
@Override
public Object apply(ImplementationArguments implementationArguments, Scope scope) {
return toString(left.apply(implementationArguments, scope)) + toString(right.apply(implementationArguments, scope));

View File

@@ -17,17 +17,17 @@ public class DivisionOperation extends BinaryOperation<Number, Number> {
public DivisionOperation(Returnable<Number> left, Returnable<Number> right, Position position) {
super(left, right, position);
}
@Override
public Returnable.ReturnType returnType() {
return Returnable.ReturnType.NUMBER;
}
@Override
public Number apply(ImplementationArguments implementationArguments, Scope scope) {
return applyDouble(implementationArguments, scope);
}
@Override
public double applyDouble(ImplementationArguments implementationArguments, Scope scope) {
return left.applyDouble(implementationArguments, scope) / right.applyDouble(implementationArguments, scope);

View File

@@ -17,17 +17,17 @@ public class ModuloOperation extends BinaryOperation<Number, Number> {
public ModuloOperation(Returnable<Number> left, Returnable<Number> right, Position start) {
super(left, right, start);
}
@Override
public Number apply(ImplementationArguments implementationArguments, Scope scope) {
return applyDouble(implementationArguments, scope);
}
@Override
public double applyDouble(ImplementationArguments implementationArguments, Scope scope) {
return left.applyDouble(implementationArguments, scope) % right.applyDouble(implementationArguments, scope);
}
@Override
public ReturnType returnType() {
return ReturnType.NUMBER;

View File

@@ -17,17 +17,17 @@ public class MultiplicationOperation extends BinaryOperation<Number, Number> {
public MultiplicationOperation(Returnable<Number> left, Returnable<Number> right, Position position) {
super(left, right, position);
}
@Override
public Number apply(ImplementationArguments implementationArguments, Scope scope) {
return applyDouble(implementationArguments, scope);
}
@Override
public double applyDouble(ImplementationArguments implementationArguments, Scope scope) {
return left.applyDouble(implementationArguments, scope) * right.applyDouble(implementationArguments, scope);
}
@Override
public ReturnType returnType() {
return ReturnType.NUMBER;

View File

@@ -17,17 +17,17 @@ public class NegationOperation extends UnaryOperation<Number> {
public NegationOperation(Returnable<Number> input, Position position) {
super(input, position);
}
@Override
public ReturnType returnType() {
return ReturnType.NUMBER;
}
@Override
public Number apply(ImplementationArguments implementationArguments, Scope scope) {
return applyDouble(implementationArguments, scope);
}
@Override
public double applyDouble(ImplementationArguments implementationArguments, Scope scope) {
return -input.applyDouble(implementationArguments, scope);

View File

@@ -17,17 +17,17 @@ public class NumberAdditionOperation extends BinaryOperation<Number, Number> {
public NumberAdditionOperation(Returnable<Number> left, Returnable<Number> right, Position position) {
super(left, right, position);
}
@Override
public Number apply(ImplementationArguments implementationArguments, Scope scope) {
return applyDouble(implementationArguments, scope);
}
@Override
public double applyDouble(ImplementationArguments implementationArguments, Scope scope) {
return left.applyDouble(implementationArguments, scope) + right.applyDouble(implementationArguments, scope);
}
@Override
public ReturnType returnType() {
return ReturnType.NUMBER;

View File

@@ -17,17 +17,17 @@ public class SubtractionOperation extends BinaryOperation<Number, Number> {
public SubtractionOperation(Returnable<Number> left, Returnable<Number> right, Position position) {
super(left, right, position);
}
@Override
public Number apply(ImplementationArguments implementationArguments, Scope scope) {
return applyDouble(implementationArguments, scope);
}
@Override
public double applyDouble(ImplementationArguments implementationArguments, Scope scope) {
return left.applyDouble(implementationArguments, scope) - right.applyDouble(implementationArguments, scope);
}
@Override
public ReturnType returnType() {
return ReturnType.NUMBER;

View File

@@ -14,12 +14,12 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public abstract class UnaryOperation<T> implements Returnable<T> {
protected final Returnable<T> input;
private final Position position;
public UnaryOperation(Returnable<T> input, Position position) {
this.input = input;
this.position = position;
}
@Override
public Position getPosition() {
return position;

View File

@@ -17,22 +17,22 @@ import static com.dfsek.terra.api.util.MathUtil.EPSILON;
public class EqualsStatement extends BinaryOperation<Object, Boolean> {
public EqualsStatement(Returnable<Object> left, Returnable<Object> right, Position position) {
super(left, right, position);
}
@Override
public Returnable.ReturnType returnType() {
return Returnable.ReturnType.BOOLEAN;
}
@Override
public Boolean apply(ImplementationArguments implementationArguments, Scope scope) {
return applyBoolean(implementationArguments, scope);
}
@Override
public boolean applyBoolean(ImplementationArguments implementationArguments, Scope scope) {
Object leftValue = left.apply(implementationArguments, scope);
@@ -40,7 +40,7 @@ public class EqualsStatement extends BinaryOperation<Object, Boolean> {
if(leftValue instanceof Number l && rightValue instanceof Number r) {
return Math.abs(l.doubleValue() - r.doubleValue()) <= EPSILON;
}
return leftValue.equals(rightValue);
}
}

View File

@@ -18,17 +18,17 @@ public class GreaterOrEqualsThanStatement extends BinaryOperation<Number, Boolea
public GreaterOrEqualsThanStatement(Returnable<Number> left, Returnable<Number> right, Position position) {
super(left, right, position);
}
@Override
public Returnable.ReturnType returnType() {
return Returnable.ReturnType.BOOLEAN;
}
@Override
public Boolean apply(ImplementationArguments implementationArguments, Scope scope) {
return applyBoolean(implementationArguments, scope);
}
@Override
public boolean applyBoolean(ImplementationArguments implementationArguments, Scope scope) {
return left.applyDouble(implementationArguments, scope) >= right.applyDouble(implementationArguments, scope);

View File

@@ -18,18 +18,18 @@ public class GreaterThanStatement extends BinaryOperation<Number, Boolean> {
public GreaterThanStatement(Returnable<Number> left, Returnable<Number> right, Position position) {
super(left, right, position);
}
@Override
public Boolean apply(ImplementationArguments implementationArguments, Scope scope) {
return applyBoolean(implementationArguments, scope);
}
@Override
public boolean applyBoolean(ImplementationArguments implementationArguments, Scope scope) {
return left.applyDouble(implementationArguments, scope) > right.applyDouble(implementationArguments, scope);
}
@Override
public Returnable.ReturnType returnType() {
return Returnable.ReturnType.BOOLEAN;

View File

@@ -18,18 +18,18 @@ public class LessThanOrEqualsStatement extends BinaryOperation<Number, Boolean>
public LessThanOrEqualsStatement(Returnable<Number> left, Returnable<Number> right, Position position) {
super(left, right, position);
}
@Override
public Boolean apply(ImplementationArguments implementationArguments, Scope scope) {
return applyBoolean(implementationArguments, scope);
}
@Override
public boolean applyBoolean(ImplementationArguments implementationArguments, Scope scope) {
return left.applyDouble(implementationArguments, scope) <= right.applyDouble(implementationArguments, scope);
}
@Override
public Returnable.ReturnType returnType() {
return Returnable.ReturnType.BOOLEAN;

View File

@@ -18,18 +18,18 @@ public class LessThanStatement extends BinaryOperation<Number, Boolean> {
public LessThanStatement(Returnable<Number> left, Returnable<Number> right, Position position) {
super(left, right, position);
}
@Override
public Boolean apply(ImplementationArguments implementationArguments, Scope scope) {
return applyBoolean(implementationArguments, scope);
}
@Override
public boolean applyBoolean(ImplementationArguments implementationArguments, Scope scope) {
return left.applyDouble(implementationArguments, scope) < right.applyDouble(implementationArguments, scope);
}
@Override
public Returnable.ReturnType returnType() {
return Returnable.ReturnType.BOOLEAN;

View File

@@ -20,12 +20,12 @@ public class NotEqualsStatement extends BinaryOperation<Object, Boolean> {
public NotEqualsStatement(Returnable<Object> left, Returnable<Object> right, Position position) {
super(left, right, position);
}
@Override
public Boolean apply(ImplementationArguments implementationArguments, Scope scope) {
return applyBoolean(implementationArguments, scope);
}
@Override
public boolean applyBoolean(ImplementationArguments implementationArguments, Scope scope) {
Object leftValue = left.apply(implementationArguments, scope);
@@ -33,10 +33,10 @@ public class NotEqualsStatement extends BinaryOperation<Object, Boolean> {
if(leftValue instanceof Number l && rightValue instanceof Number r) {
return Math.abs(l.doubleValue() - r.doubleValue()) > EPSILON;
}
return !leftValue.equals(rightValue);
}
@Override
public Returnable.ReturnType returnType() {
return Returnable.ReturnType.BOOLEAN;

View File

@@ -14,27 +14,27 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class BooleanVariable implements Variable<Boolean> {
private final Position position;
private Boolean value;
public BooleanVariable(Boolean value, Position position) {
this.value = value;
this.position = position;
}
@Override
public Boolean getValue() {
return value;
}
@Override
public void setValue(Boolean value) {
this.value = value;
}
@Override
public Returnable.ReturnType getType() {
return Returnable.ReturnType.BOOLEAN;
}
@Override
public Position getPosition() {
return position;

View File

@@ -14,27 +14,27 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class NumberVariable implements Variable<Number> {
private final Position position;
private Number value;
public NumberVariable(Number value, Position position) {
this.value = value;
this.position = position;
}
@Override
public Number getValue() {
return value;
}
@Override
public void setValue(Number value) {
this.value = value;
}
@Override
public Returnable.ReturnType getType() {
return Returnable.ReturnType.NUMBER;
}
@Override
public Position getPosition() {
return position;

View File

@@ -14,27 +14,27 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class StringVariable implements Variable<String> {
private final Position position;
private String value;
public StringVariable(String value, Position position) {
this.value = value;
this.position = position;
}
@Override
public String getValue() {
return value;
}
@Override
public void setValue(String value) {
this.value = value;
}
@Override
public Returnable.ReturnType getType() {
return Returnable.ReturnType.STRING;
}
@Override
public Position getPosition() {
return position;

View File

@@ -13,10 +13,10 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public interface Variable<T> {
T getValue();
void setValue(T value);
Returnable.ReturnType getType();
Position getPosition();
}

View File

@@ -10,12 +10,12 @@ public class BoolAssignmentNode extends VariableAssignmentNode<Boolean> {
public BoolAssignmentNode(Returnable<Boolean> value, Position position, int index) {
super(value, position, index);
}
@Override
public Boolean apply(ImplementationArguments implementationArguments, Scope scope) {
return applyBoolean(implementationArguments, scope);
}
@Override
public boolean applyBoolean(ImplementationArguments implementationArguments, Scope scope) {
boolean val = value.applyBoolean(implementationArguments, scope);

View File

@@ -10,12 +10,12 @@ public class NumAssignmentNode extends VariableAssignmentNode<Number> {
public NumAssignmentNode(Returnable<Number> value, Position position, int index) {
super(value, position, index);
}
@Override
public Number apply(ImplementationArguments implementationArguments, Scope scope) {
return applyDouble(implementationArguments, scope);
}
@Override
public double applyDouble(ImplementationArguments implementationArguments, Scope scope) {
double val = value.applyDouble(implementationArguments, scope);

View File

@@ -10,12 +10,12 @@ public class StrAssignmentNode extends VariableAssignmentNode<String> {
public StrAssignmentNode(Returnable<String> value, Position position, int index) {
super(value, position, index);
}
@Override
public String apply(ImplementationArguments implementationArguments, Scope scope) {
String val = value.apply(implementationArguments, scope);
scope.setStr(index, val);
return val;
}
}

View File

@@ -16,14 +16,14 @@ public abstract class VariableAssignmentNode<T> implements Item<T> {
protected final Returnable<T> value;
protected final int index;
private final Position position;
public VariableAssignmentNode(Returnable<T> value, Position position, int index) {
this.value = value;
this.index = index;
this.position = position;
}
@Override
public Position getPosition() {
return position;

View File

@@ -9,12 +9,12 @@ public class BoolVariableReferenceNode extends VariableReferenceNode<Boolean> {
public BoolVariableReferenceNode(Position position, ReturnType type, int index) {
super(position, type, index);
}
@Override
public Boolean apply(ImplementationArguments implementationArguments, Scope scope) {
return scope.getBool(index);
}
@Override
public boolean applyBoolean(ImplementationArguments implementationArguments, Scope scope) {
return scope.getBool(index);

View File

@@ -9,12 +9,12 @@ public class NumVariableReferenceNode extends VariableReferenceNode<Number> {
public NumVariableReferenceNode(Position position, ReturnType type, int index) {
super(position, type, index);
}
@Override
public Number apply(ImplementationArguments implementationArguments, Scope scope) {
return scope.getNum(index);
}
@Override
public double applyDouble(ImplementationArguments implementationArguments, Scope scope) {
return scope.getNum(index);

View File

@@ -9,7 +9,7 @@ public class StrVariableReferenceNode extends VariableReferenceNode<String> {
public StrVariableReferenceNode(Position position, ReturnType type, int index) {
super(position, type, index);
}
@Override
public String apply(ImplementationArguments implementationArguments, Scope scope) {
return scope.getStr(index);

View File

@@ -15,18 +15,18 @@ public abstract class VariableReferenceNode<T> implements Returnable<T> {
protected final int index;
private final Position position;
private final ReturnType type;
public VariableReferenceNode(Position position, ReturnType type, int index) {
this.position = position;
this.type = type;
this.index = index;
}
@Override
public ReturnType returnType() {
return type;
}
@Override
public Position getPosition() {
return position;

View File

@@ -53,10 +53,10 @@ public class StructureScript implements Structure, Keyed<StructureScript> {
private static final Logger LOGGER = LoggerFactory.getLogger(StructureScript.class);
private final Executable block;
private final RegistryKey id;
private final String profile;
private final Platform platform;
@SuppressWarnings("rawtypes")
public StructureScript(InputStream inputStream, RegistryKey id, Platform platform, Registry<Structure> registry,
Registry<LootTable> lootRegistry,
@@ -69,66 +69,66 @@ public class StructureScript implements Structure, Keyed<StructureScript> {
}
this.id = id;
this.profile = "terrascript_direct:" + id;
//noinspection unchecked
functionRegistry.forEach((key, function) -> parser.registerFunction(key.getID(), function)); // Register registry functions.
parser
.registerFunction("block", new BlockFunctionBuilder(platform))
.registerFunction("debugBlock", new BlockFunctionBuilder(platform))
.registerFunction("structure", new StructureFunctionBuilder(registry, platform))
.registerFunction("randomInt", new RandomFunctionBuilder())
.registerFunction("recursions", new RecursionsFunctionBuilder())
.registerFunction("setMark", new SetMarkFunctionBuilder())
.registerFunction("getMark", new GetMarkFunctionBuilder())
.registerFunction("pull", new PullFunctionBuilder(platform))
.registerFunction("loot", new LootFunctionBuilder(platform, lootRegistry, this))
.registerFunction("entity", new EntityFunctionBuilder(platform))
.registerFunction("getBiome", new BiomeFunctionBuilder(platform))
.registerFunction("getBlock", new CheckBlockFunctionBuilder())
.registerFunction("state", new StateFunctionBuilder(platform))
.registerFunction("setWaterlog", new UnaryBooleanFunctionBuilder((waterlog, args) -> args.setWaterlog(waterlog)))
.registerFunction("originX", new ZeroArgFunctionBuilder<Number>(arguments -> arguments.getOrigin().getX(),
Returnable.ReturnType.NUMBER))
.registerFunction("originY", new ZeroArgFunctionBuilder<Number>(arguments -> arguments.getOrigin().getY(),
Returnable.ReturnType.NUMBER))
.registerFunction("originZ", new ZeroArgFunctionBuilder<Number>(arguments -> arguments.getOrigin().getZ(),
Returnable.ReturnType.NUMBER))
.registerFunction("rotation", new ZeroArgFunctionBuilder<>(arguments -> arguments.getRotation().toString(),
Returnable.ReturnType.STRING))
.registerFunction("rotationDegrees", new ZeroArgFunctionBuilder<>(arguments -> arguments.getRotation().getDegrees(),
Returnable.ReturnType.NUMBER))
.registerFunction("print",
new UnaryStringFunctionBuilder(string -> LOGGER.info("[TerraScript:{}] {}", id, string)))
.registerFunction("abs", new UnaryNumberFunctionBuilder(number -> Math.abs(number.doubleValue())))
.registerFunction("pow2", new UnaryNumberFunctionBuilder(number -> Math.pow(number.doubleValue(), 2)))
.registerFunction("pow", new BinaryNumberFunctionBuilder(
(number, number2) -> Math.pow(number.doubleValue(), number2.doubleValue())))
.registerFunction("sqrt", new UnaryNumberFunctionBuilder(number -> Math.sqrt(number.doubleValue())))
.registerFunction("rsqrt", new UnaryNumberFunctionBuilder(number -> MathUtil.invSqrt(number.doubleValue())))
.registerFunction("floor", new UnaryNumberFunctionBuilder(number -> Math.floor(number.doubleValue())))
.registerFunction("ceil", new UnaryNumberFunctionBuilder(number -> Math.ceil(number.doubleValue())))
.registerFunction("log", new UnaryNumberFunctionBuilder(number -> Math.log(number.doubleValue())))
.registerFunction("round", new UnaryNumberFunctionBuilder(number -> Math.round(number.doubleValue())))
.registerFunction("sin", new UnaryNumberFunctionBuilder(number -> MathUtil.sin(number.doubleValue())))
.registerFunction("cos", new UnaryNumberFunctionBuilder(number -> MathUtil.cos(number.doubleValue())))
.registerFunction("tan", new UnaryNumberFunctionBuilder(number -> MathUtil.tan(number.doubleValue())))
.registerFunction("asin", new UnaryNumberFunctionBuilder(number -> Math.asin(number.doubleValue())))
.registerFunction("acos", new UnaryNumberFunctionBuilder(number -> Math.acos(number.doubleValue())))
.registerFunction("atan", new UnaryNumberFunctionBuilder(number -> Math.atan(number.doubleValue())))
.registerFunction("max", new BinaryNumberFunctionBuilder(
(number, number2) -> Math.max(number.doubleValue(), number2.doubleValue())))
.registerFunction("min", new BinaryNumberFunctionBuilder(
(number, number2) -> Math.min(number.doubleValue(), number2.doubleValue())));
.registerFunction("block", new BlockFunctionBuilder(platform))
.registerFunction("debugBlock", new BlockFunctionBuilder(platform))
.registerFunction("structure", new StructureFunctionBuilder(registry, platform))
.registerFunction("randomInt", new RandomFunctionBuilder())
.registerFunction("recursions", new RecursionsFunctionBuilder())
.registerFunction("setMark", new SetMarkFunctionBuilder())
.registerFunction("getMark", new GetMarkFunctionBuilder())
.registerFunction("pull", new PullFunctionBuilder(platform))
.registerFunction("loot", new LootFunctionBuilder(platform, lootRegistry, this))
.registerFunction("entity", new EntityFunctionBuilder(platform))
.registerFunction("getBiome", new BiomeFunctionBuilder(platform))
.registerFunction("getBlock", new CheckBlockFunctionBuilder())
.registerFunction("state", new StateFunctionBuilder(platform))
.registerFunction("setWaterlog", new UnaryBooleanFunctionBuilder((waterlog, args) -> args.setWaterlog(waterlog)))
.registerFunction("originX", new ZeroArgFunctionBuilder<Number>(arguments -> arguments.getOrigin().getX(),
Returnable.ReturnType.NUMBER))
.registerFunction("originY", new ZeroArgFunctionBuilder<Number>(arguments -> arguments.getOrigin().getY(),
Returnable.ReturnType.NUMBER))
.registerFunction("originZ", new ZeroArgFunctionBuilder<Number>(arguments -> arguments.getOrigin().getZ(),
Returnable.ReturnType.NUMBER))
.registerFunction("rotation", new ZeroArgFunctionBuilder<>(arguments -> arguments.getRotation().toString(),
Returnable.ReturnType.STRING))
.registerFunction("rotationDegrees", new ZeroArgFunctionBuilder<>(arguments -> arguments.getRotation().getDegrees(),
Returnable.ReturnType.NUMBER))
.registerFunction("print",
new UnaryStringFunctionBuilder(string -> LOGGER.info("[TerraScript:{}] {}", id, string)))
.registerFunction("abs", new UnaryNumberFunctionBuilder(number -> Math.abs(number.doubleValue())))
.registerFunction("pow2", new UnaryNumberFunctionBuilder(number -> Math.pow(number.doubleValue(), 2)))
.registerFunction("pow", new BinaryNumberFunctionBuilder(
(number, number2) -> Math.pow(number.doubleValue(), number2.doubleValue())))
.registerFunction("sqrt", new UnaryNumberFunctionBuilder(number -> Math.sqrt(number.doubleValue())))
.registerFunction("rsqrt", new UnaryNumberFunctionBuilder(number -> MathUtil.invSqrt(number.doubleValue())))
.registerFunction("floor", new UnaryNumberFunctionBuilder(number -> Math.floor(number.doubleValue())))
.registerFunction("ceil", new UnaryNumberFunctionBuilder(number -> Math.ceil(number.doubleValue())))
.registerFunction("log", new UnaryNumberFunctionBuilder(number -> Math.log(number.doubleValue())))
.registerFunction("round", new UnaryNumberFunctionBuilder(number -> Math.round(number.doubleValue())))
.registerFunction("sin", new UnaryNumberFunctionBuilder(number -> MathUtil.sin(number.doubleValue())))
.registerFunction("cos", new UnaryNumberFunctionBuilder(number -> MathUtil.cos(number.doubleValue())))
.registerFunction("tan", new UnaryNumberFunctionBuilder(number -> MathUtil.tan(number.doubleValue())))
.registerFunction("asin", new UnaryNumberFunctionBuilder(number -> Math.asin(number.doubleValue())))
.registerFunction("acos", new UnaryNumberFunctionBuilder(number -> Math.acos(number.doubleValue())))
.registerFunction("atan", new UnaryNumberFunctionBuilder(number -> Math.atan(number.doubleValue())))
.registerFunction("max", new BinaryNumberFunctionBuilder(
(number, number2) -> Math.max(number.doubleValue(), number2.doubleValue())))
.registerFunction("min", new BinaryNumberFunctionBuilder(
(number, number2) -> Math.min(number.doubleValue(), number2.doubleValue())));
if(!platform.getTerraConfig().isDebugScript()) {
parser.ignoreFunction("debugBlock");
}
block = parser.parse();
this.platform = platform;
}
@Override
@SuppressWarnings("try")
public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) {
@@ -137,14 +137,14 @@ public class StructureScript implements Structure, Keyed<StructureScript> {
platform.getProfiler().pop(profile);
return result;
}
public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation, int recursions) {
platform.getProfiler().push(profile);
boolean result = applyBlock(new TerraImplementationArguments(location, rotation, random, world, recursions));
platform.getProfiler().pop(profile);
return result;
}
private boolean applyBlock(TerraImplementationArguments arguments) {
try {
return block.execute(arguments);
@@ -153,7 +153,7 @@ public class StructureScript implements Structure, Keyed<StructureScript> {
return false;
}
}
@Override
public RegistryKey getRegistryKey() {
return id;

View File

@@ -26,7 +26,7 @@ public class TerraImplementationArguments implements ImplementationArguments {
private final int recursions;
private final Vector3Int origin;
private boolean waterlog = false;
public TerraImplementationArguments(Vector3Int origin, Rotation rotation, Random random, WritableWorld world, int recursions) {
this.rotation = rotation;
this.random = random;
@@ -34,39 +34,39 @@ public class TerraImplementationArguments implements ImplementationArguments {
this.recursions = recursions;
this.origin = origin;
}
public int getRecursions() {
return recursions;
}
public Random getRandom() {
return random;
}
public Rotation getRotation() {
return rotation;
}
public boolean isWaterlog() {
return waterlog;
}
public void setWaterlog(boolean waterlog) {
this.waterlog = waterlog;
}
public WritableWorld getWorld() {
return world;
}
public Vector3Int getOrigin() {
return origin;
}
public void setMark(Vector3 pos, String mark) {
marks.put(pos, mark);
}
public String getMark(Vector3 pos) {
return marks.get(pos);
}

View File

@@ -19,13 +19,13 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class BinaryNumberFunctionBuilder implements FunctionBuilder<Function<Number>> {
private final BiFunction<Number, Number, Number> function;
public BinaryNumberFunctionBuilder(BiFunction<Number, Number, Number> function) {
this.function = function;
}
@Override
public Function<Number> build(List<Returnable<?>> argumentList, Position position) {
return new Function<>() {
@@ -33,26 +33,26 @@ public class BinaryNumberFunctionBuilder implements FunctionBuilder<Function<Num
public ReturnType returnType() {
return ReturnType.NUMBER;
}
@SuppressWarnings("unchecked")
@Override
public Number apply(ImplementationArguments implementationArguments, Scope scope) {
return function.apply(((Returnable<Number>) argumentList.get(0)).apply(implementationArguments, scope),
((Returnable<Number>) argumentList.get(1)).apply(implementationArguments, scope));
((Returnable<Number>) argumentList.get(1)).apply(implementationArguments, scope));
}
@Override
public Position getPosition() {
return position;
}
};
}
@Override
public int argNumber() {
return 2;
}
@Override
public Returnable.ReturnType getArgument(int position) {
if(position == 0 || position == 1) return Returnable.ReturnType.NUMBER;

View File

@@ -18,23 +18,23 @@ import com.dfsek.terra.api.Platform;
public class BiomeFunctionBuilder implements FunctionBuilder<BiomeFunction> {
private final Platform platform;
public BiomeFunctionBuilder(Platform platform) {
this.platform = platform;
}
@SuppressWarnings("unchecked")
@Override
public BiomeFunction build(List<Returnable<?>> argumentList, Position position) {
return new BiomeFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1),
(Returnable<Number>) argumentList.get(2), position);
(Returnable<Number>) argumentList.get(2), position);
}
@Override
public int argNumber() {
return 3;
}
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {

View File

@@ -21,11 +21,11 @@ import com.dfsek.terra.api.Platform;
public class BlockFunctionBuilder implements FunctionBuilder<BlockFunction> {
private final Platform platform;
public BlockFunctionBuilder(Platform platform) {
this.platform = platform;
}
@SuppressWarnings("unchecked")
@Override
public BlockFunction build(List<Returnable<?>> argumentList, Position position) {
@@ -36,19 +36,19 @@ public class BlockFunctionBuilder implements FunctionBuilder<BlockFunction> {
if(argumentList.size() == 6) physics = (Returnable<Boolean>) argumentList.get(5);
if(argumentList.get(3) instanceof StringConstant) {
return new BlockFunction.Constant((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1),
(Returnable<Number>) argumentList.get(2), (StringConstant) argumentList.get(3),
overwrite, physics, platform, position);
(Returnable<Number>) argumentList.get(2), (StringConstant) argumentList.get(3),
overwrite, physics, platform, position);
}
return new BlockFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1),
(Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), overwrite, physics,
platform, position);
(Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), overwrite, physics,
platform, position);
}
@Override
public int argNumber() {
return -1;
}
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {

View File

@@ -20,14 +20,14 @@ public class CheckBlockFunctionBuilder implements FunctionBuilder<CheckBlockFunc
@Override
public CheckBlockFunction build(List<Returnable<?>> argumentList, Position position) {
return new CheckBlockFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1),
(Returnable<Number>) argumentList.get(2), position);
(Returnable<Number>) argumentList.get(2), position);
}
@Override
public int argNumber() {
return 3;
}
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {

View File

@@ -18,23 +18,23 @@ import com.dfsek.terra.api.Platform;
public class EntityFunctionBuilder implements FunctionBuilder<EntityFunction> {
private final Platform platform;
public EntityFunctionBuilder(Platform platform) {
this.platform = platform;
}
@SuppressWarnings("unchecked")
@Override
public EntityFunction build(List<Returnable<?>> argumentList, Position position) {
return new EntityFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1),
(Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), platform, position);
(Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), platform, position);
}
@Override
public int argNumber() {
return 4;
}
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {

View File

@@ -16,22 +16,22 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class GetMarkFunctionBuilder implements FunctionBuilder<GetMarkFunction> {
public GetMarkFunctionBuilder() {
}
@SuppressWarnings("unchecked")
@Override
public GetMarkFunction build(List<Returnable<?>> argumentList, Position position) {
return new GetMarkFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1),
(Returnable<Number>) argumentList.get(2), position);
(Returnable<Number>) argumentList.get(2), position);
}
@Override
public int argNumber() {
return 3;
}
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {

View File

@@ -23,26 +23,26 @@ public class LootFunctionBuilder implements FunctionBuilder<LootFunction> {
private final Platform platform;
private final Registry<LootTable> registry;
private final StructureScript script;
public LootFunctionBuilder(Platform platform, Registry<LootTable> registry, StructureScript script) {
this.platform = platform;
this.registry = registry;
this.script = script;
}
@SuppressWarnings("unchecked")
@Override
public LootFunction build(List<Returnable<?>> argumentList, Position position) {
return new LootFunction(registry, (Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1),
(Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), platform, position,
script);
(Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), platform, position,
script);
}
@Override
public int argNumber() {
return 4;
}
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {

View File

@@ -18,23 +18,23 @@ import com.dfsek.terra.api.Platform;
public class PullFunctionBuilder implements FunctionBuilder<PullFunction> {
private final Platform platform;
public PullFunctionBuilder(Platform platform) {
this.platform = platform;
}
@SuppressWarnings("unchecked")
@Override
public PullFunction build(List<Returnable<?>> argumentList, Position position) {
return new PullFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1),
(Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), platform, position);
(Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), platform, position);
}
@Override
public int argNumber() {
return 4;
}
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {

View File

@@ -21,12 +21,12 @@ public class RandomFunctionBuilder implements FunctionBuilder<RandomFunction> {
public RandomFunction build(List<Returnable<?>> argumentList, Position position) {
return new RandomFunction((Returnable<Number>) argumentList.get(0), position);
}
@Override
public int argNumber() {
return 1;
}
@Override
public Returnable.ReturnType getArgument(int position) {
if(position == 0) return Returnable.ReturnType.NUMBER;

View File

@@ -20,12 +20,12 @@ public class RecursionsFunctionBuilder implements FunctionBuilder<RecursionsFunc
public RecursionsFunction build(List<Returnable<?>> argumentList, Position position) {
return new RecursionsFunction(position);
}
@Override
public int argNumber() {
return 0;
}
@Override
public Returnable.ReturnType getArgument(int position) {
return null;

View File

@@ -16,22 +16,22 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class SetMarkFunctionBuilder implements FunctionBuilder<SetMarkFunction> {
public SetMarkFunctionBuilder() {
}
@SuppressWarnings("unchecked")
@Override
public SetMarkFunction build(List<Returnable<?>> argumentList, Position position) {
return new SetMarkFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1),
(Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), position);
(Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), position);
}
@Override
public int argNumber() {
return 4;
}
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {

View File

@@ -19,24 +19,24 @@ import com.dfsek.terra.api.Platform;
public class StateFunctionBuilder implements FunctionBuilder<StateFunction> {
private final Platform platform;
public StateFunctionBuilder(Platform platform) {
this.platform = platform;
}
@SuppressWarnings("unchecked")
@Override
public StateFunction build(List<Returnable<?>> argumentList, Position position) {
if(argumentList.size() < 4) throw new ParseException("Expected data", position);
return new StateFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1),
(Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), position);
(Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), position);
}
@Override
public int argNumber() {
return 4;
}
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {

View File

@@ -23,28 +23,28 @@ import com.dfsek.terra.api.structure.Structure;
public class StructureFunctionBuilder implements FunctionBuilder<StructureFunction> {
private final Registry<Structure> registry;
private final Platform platform;
public StructureFunctionBuilder(Registry<Structure> registry, Platform platform) {
this.registry = registry;
this.platform = platform;
}
@SuppressWarnings("unchecked")
@Override
public StructureFunction build(List<Returnable<?>> argumentList, Position position) {
if(argumentList.size() < 5) throw new ParseException("Expected rotations", position);
return new StructureFunction((Returnable<Number>) argumentList.remove(0), (Returnable<Number>) argumentList.remove(0),
(Returnable<Number>) argumentList.remove(0), (Returnable<String>) argumentList.remove(0),
argumentList.stream().map(item -> ((Returnable<String>) item)).collect(Collectors.toList()), registry,
position, platform);
(Returnable<Number>) argumentList.remove(0), (Returnable<String>) argumentList.remove(0),
argumentList.stream().map(item -> ((Returnable<String>) item)).collect(Collectors.toList()), registry,
position, platform);
}
@Override
public int argNumber() {
return -1;
}
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {

View File

@@ -20,13 +20,13 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class UnaryBooleanFunctionBuilder implements FunctionBuilder<Function<Void>> {
private final BiConsumer<Boolean, TerraImplementationArguments> function;
public UnaryBooleanFunctionBuilder(BiConsumer<Boolean, TerraImplementationArguments> function) {
this.function = function;
}
@Override
public Function<Void> build(List<Returnable<?>> argumentList, Position position) {
return new Function<>() {
@@ -34,27 +34,27 @@ public class UnaryBooleanFunctionBuilder implements FunctionBuilder<Function<Voi
public ReturnType returnType() {
return ReturnType.VOID;
}
@SuppressWarnings("unchecked")
@Override
public Void apply(ImplementationArguments implementationArguments, Scope scope) {
function.accept(((Returnable<Boolean>) argumentList.get(0)).apply(implementationArguments, scope),
(TerraImplementationArguments) implementationArguments);
(TerraImplementationArguments) implementationArguments);
return null;
}
@Override
public Position getPosition() {
return position;
}
};
}
@Override
public int argNumber() {
return 1;
}
@Override
public Returnable.ReturnType getArgument(int position) {
if(position == 0) return Returnable.ReturnType.BOOLEAN;

View File

@@ -18,13 +18,13 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class UnaryNumberFunctionBuilder implements FunctionBuilder<Function<Number>> {
private final java.util.function.Function<Number, Number> function;
public UnaryNumberFunctionBuilder(java.util.function.Function<Number, Number> function) {
this.function = function;
}
@Override
public Function<Number> build(List<Returnable<?>> argumentList, Position position) {
return new Function<>() {
@@ -32,25 +32,25 @@ public class UnaryNumberFunctionBuilder implements FunctionBuilder<Function<Numb
public ReturnType returnType() {
return ReturnType.NUMBER;
}
@SuppressWarnings("unchecked")
@Override
public Number apply(ImplementationArguments implementationArguments, Scope scope) {
return function.apply(((Returnable<Number>) argumentList.get(0)).apply(implementationArguments, scope));
}
@Override
public Position getPosition() {
return position;
}
};
}
@Override
public int argNumber() {
return 1;
}
@Override
public Returnable.ReturnType getArgument(int position) {
if(position == 0) return Returnable.ReturnType.NUMBER;

View File

@@ -18,13 +18,13 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class UnaryStringFunctionBuilder implements FunctionBuilder<Function<Void>> {
private final java.util.function.Consumer<String> function;
public UnaryStringFunctionBuilder(java.util.function.Consumer<String> function) {
this.function = function;
}
@Override
public Function<Void> build(List<Returnable<?>> argumentList, Position position) {
return new Function<>() {
@@ -32,26 +32,26 @@ public class UnaryStringFunctionBuilder implements FunctionBuilder<Function<Void
public ReturnType returnType() {
return ReturnType.VOID;
}
@SuppressWarnings("unchecked")
@Override
public Void apply(ImplementationArguments implementationArguments, Scope scope) {
function.accept(((Returnable<String>) argumentList.get(0)).apply(implementationArguments, scope));
return null;
}
@Override
public Position getPosition() {
return position;
}
};
}
@Override
public int argNumber() {
return 1;
}
@Override
public Returnable.ReturnType getArgument(int position) {
if(position == 0) return Returnable.ReturnType.STRING;

View File

@@ -21,12 +21,12 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class ZeroArgFunctionBuilder<T> implements FunctionBuilder<Function<T>> {
private final java.util.function.Function<TerraImplementationArguments, T> function;
private final Returnable.ReturnType type;
public ZeroArgFunctionBuilder(java.util.function.Function<TerraImplementationArguments, T> function, Returnable.ReturnType type) {
this.function = function;
this.type = type;
}
@Override
public Function<T> build(List<Returnable<?>> argumentList, Position position) {
return new Function<>() {
@@ -34,24 +34,24 @@ public class ZeroArgFunctionBuilder<T> implements FunctionBuilder<Function<T>> {
public ReturnType returnType() {
return type;
}
@Override
public T apply(ImplementationArguments implementationArguments, Scope scope) {
return function.apply((TerraImplementationArguments) implementationArguments);
}
@Override
public Position getPosition() {
return position;
}
};
}
@Override
public int argNumber() {
return 0;
}
@Override
public Returnable.ReturnType getArgument(int position) {
if(position == 0) return type;

View File

@@ -22,40 +22,40 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class BiomeFunction implements Function<String> {
private final Returnable<Number> x, y, z;
private final Position position;
public BiomeFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Position position) {
this.x = x;
this.y = y;
this.z = z;
this.position = position;
}
@Override
public String apply(ImplementationArguments implementationArguments, Scope scope) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = RotationUtil.rotateVector(Vector2.of(x.apply(implementationArguments, scope).doubleValue(),
z.apply(implementationArguments, scope).doubleValue()),
arguments.getRotation());
z.apply(implementationArguments, scope).doubleValue()),
arguments.getRotation());
BiomeProvider grid = arguments.getWorld().getBiomeProvider();
return grid.getBiome(arguments.getOrigin()
.toVector3()
.mutable()
.add(Vector3.of((int) Math.round(xz.getX()),
y.apply(implementationArguments, scope).intValue(),
(int) Math.round(xz.getZ()))).immutable(), arguments.getWorld().getSeed()).getID();
.toVector3()
.mutable()
.add(Vector3.of((int) Math.round(xz.getX()),
y.apply(implementationArguments, scope).intValue(),
(int) Math.round(xz.getZ()))).immutable(), arguments.getWorld().getSeed()).getID();
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.STRING;

View File

@@ -7,8 +7,6 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.terra.addons.terrascript.parser.lang.constants.BooleanConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -18,6 +16,7 @@ import java.util.Map;
import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.parser.lang.Returnable;
import com.dfsek.terra.addons.terrascript.parser.lang.Scope;
import com.dfsek.terra.addons.terrascript.parser.lang.constants.BooleanConstant;
import com.dfsek.terra.addons.terrascript.parser.lang.constants.StringConstant;
import com.dfsek.terra.addons.terrascript.parser.lang.functions.Function;
import com.dfsek.terra.addons.terrascript.script.TerraImplementationArguments;
@@ -38,7 +37,7 @@ public class BlockFunction implements Function<Void> {
private final Returnable<Boolean> overwrite;
private final Returnable<Boolean> physics;
private final Position position;
public BlockFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> blockData,
Returnable<Boolean> overwrite, Platform platform, Position position) {
this.x = x;
@@ -48,9 +47,9 @@ public class BlockFunction implements Function<Void> {
this.overwrite = overwrite;
this.platform = platform;
this.position = position;
this.physics = new BooleanConstant(false, position);;
this.physics = new BooleanConstant(false, position);
}
public BlockFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> blockData,
Returnable<Boolean> overwrite, Returnable<Boolean> physics, Platform platform, Position position) {
this.x = x;
@@ -62,7 +61,7 @@ public class BlockFunction implements Function<Void> {
this.position = position;
this.physics = physics;
}
@Override
public Void apply(ImplementationArguments implementationArguments, Scope scope) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
@@ -70,25 +69,25 @@ public class BlockFunction implements Function<Void> {
setBlock(implementationArguments, scope, arguments, rot);
return null;
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;
}
void setBlock(ImplementationArguments implementationArguments, Scope scope,
TerraImplementationArguments arguments, BlockState rot) {
Vector2 xz = RotationUtil.rotateVector(Vector2.of(x.apply(implementationArguments, scope).doubleValue(),
z.apply(implementationArguments, scope).doubleValue()), arguments.getRotation());
z.apply(implementationArguments, scope).doubleValue()), arguments.getRotation());
try {
Vector3.Mutable set = Vector3.of((int) Math.round(xz.getX()),
y.apply(implementationArguments, scope).doubleValue(),
(int) Math.round(xz.getZ())).mutable().add(arguments.getOrigin());
y.apply(implementationArguments, scope).doubleValue(),
(int) Math.round(xz.getZ())).mutable().add(arguments.getOrigin());
BlockState current = arguments.getWorld().getBlockState(set);
if(overwrite.apply(implementationArguments, scope) || current.isAir()) {
arguments.getWorld().setBlockState(set, rot, physics.apply(implementationArguments, scope));
@@ -97,21 +96,21 @@ public class BlockFunction implements Function<Void> {
logger.error("Failed to place block at location {}", arguments.getOrigin(), e);
}
}
protected BlockState getBlockState(ImplementationArguments arguments, Scope scope) {
return data.computeIfAbsent(blockData.apply(arguments, scope), platform.getWorldHandle()::createBlockState);
}
public static class Constant extends BlockFunction {
private final BlockState state;
public Constant(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, StringConstant blockData,
Returnable<Boolean> overwrite, Returnable<Boolean> physics, Platform platform, Position position) {
super(x, y, z, blockData, overwrite, physics, platform, position);
this.state = platform.getWorldHandle().createBlockState(blockData.getConstant());
}
@Override
protected BlockState getBlockState(ImplementationArguments arguments, Scope scope) {
return state;

View File

@@ -21,41 +21,41 @@ import com.dfsek.terra.api.util.vector.Vector3;
public class CheckBlockFunction implements Function<String> {
private final Returnable<Number> x, y, z;
private final Position position;
public CheckBlockFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Position position) {
this.x = x;
this.y = y;
this.z = z;
this.position = position;
}
@Override
public String apply(ImplementationArguments implementationArguments, Scope scope) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = RotationUtil.rotateVector(Vector2.of(x.apply(implementationArguments, scope).doubleValue(),
z.apply(implementationArguments, scope).doubleValue()),
arguments.getRotation());
z.apply(implementationArguments, scope).doubleValue()),
arguments.getRotation());
String data = arguments.getWorld()
.getBlockState(arguments.getOrigin()
.toVector3()
.mutable()
.add(Vector3.of((int) Math.round(xz.getX()),
y.apply(implementationArguments, scope)
.doubleValue(), (int) Math.round(xz.getZ()))))
.getAsString();
.getBlockState(arguments.getOrigin()
.toVector3()
.mutable()
.add(Vector3.of((int) Math.round(xz.getX()),
y.apply(implementationArguments, scope)
.doubleValue(), (int) Math.round(xz.getZ()))))
.getAsString();
if(data.contains("[")) return data.substring(0, data.indexOf('[')); // Strip properties
else return data;
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.STRING;

View File

@@ -29,40 +29,40 @@ public class EntityFunction implements Function<Void> {
private final Returnable<Number> x, y, z;
private final Position position;
private final Platform platform;
public EntityFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> data, Platform platform,
Position position) {
this.position = position;
this.platform = platform;
if(!(data instanceof ConstantExpression)) throw new ParseException("Entity data must be constant", data.getPosition());
this.data = platform.getWorldHandle().getEntity(((ConstantExpression<String>) data).getConstant());
this.x = x;
this.y = y;
this.z = z;
}
@Override
public Void apply(ImplementationArguments implementationArguments, Scope scope) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = RotationUtil.rotateVector(Vector2.of(x.apply(implementationArguments, scope).doubleValue(),
z.apply(implementationArguments, scope).doubleValue()), arguments.getRotation());
z.apply(implementationArguments, scope).doubleValue()), arguments.getRotation());
Entity entity = arguments.getWorld().spawnEntity(Vector3.of(xz.getX(), y.apply(implementationArguments, scope).doubleValue(),
xz.getZ())
.mutable()
.add(arguments.getOrigin())
.add(0.5, 0, 0.5)
.immutable(), data);
xz.getZ())
.mutable()
.add(arguments.getOrigin())
.add(0.5, 0, 0.5)
.immutable(), data);
platform.getEventManager().callEvent(new EntitySpawnEvent(entity.world().getPack(), entity));
return null;
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;

View File

@@ -21,34 +21,34 @@ import com.dfsek.terra.api.util.vector.Vector3;
public class GetMarkFunction implements Function<String> {
private final Returnable<Number> x, y, z;
private final Position position;
public GetMarkFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Position position) {
this.position = position;
this.x = x;
this.y = y;
this.z = z;
}
@Override
public String apply(ImplementationArguments implementationArguments, Scope scope) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = RotationUtil.rotateVector(Vector2.of(x.apply(implementationArguments, scope).doubleValue(),
z.apply(implementationArguments, scope).doubleValue()), arguments.getRotation());
z.apply(implementationArguments, scope).doubleValue()), arguments.getRotation());
String mark = arguments.getMark(Vector3.of((int) Math.floor(xz.getX()), (int) Math.floor(
y.apply(implementationArguments, scope).doubleValue()),
(int) Math.floor(xz.getZ()))
.mutable()
.add(arguments.getOrigin())
.immutable());
y.apply(implementationArguments, scope).doubleValue()),
(int) Math.floor(xz.getZ()))
.mutable()
.add(arguments.getOrigin())
.immutable());
return mark == null ? "" : mark;
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.STRING;

View File

@@ -39,7 +39,7 @@ public class LootFunction implements Function<Void> {
private final Position position;
private final Platform platform;
private final StructureScript script;
public LootFunction(Registry<LootTable> registry, Returnable<Number> x, Returnable<Number> y, Returnable<Number> z,
Returnable<String> data, Platform platform, Position position, StructureScript script) {
this.registry = registry;
@@ -51,55 +51,55 @@ public class LootFunction implements Function<Void> {
this.platform = platform;
this.script = script;
}
@Override
public Void apply(ImplementationArguments implementationArguments, Scope scope) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = RotationUtil.rotateVector(Vector2.of(x.apply(implementationArguments, scope).doubleValue(),
z.apply(implementationArguments, scope).doubleValue()),
arguments.getRotation());
z.apply(implementationArguments, scope).doubleValue()),
arguments.getRotation());
String id = data.apply(implementationArguments, scope);
registry.get(RegistryKey.parse(id))
.ifPresentOrElse(table -> {
Vector3 apply = Vector3.of((int) Math.round(xz.getX()),
y.apply(implementationArguments, scope)
.intValue(),
(int) Math.round(xz.getZ())).mutable().add(arguments.getOrigin()).immutable();
try {
BlockEntity data = arguments.getWorld().getBlockEntity(apply);
if(!(data instanceof Container container)) {
LOGGER.error("Failed to place loot at {}; block {} is not a container",
apply, data);
return;
}
LootPopulateEvent event = new LootPopulateEvent(container, table,
arguments.getWorld().getPack(), script);
platform.getEventManager().callEvent(event);
if(event.isCancelled()) return;
event.getTable().fillInventory(container.getInventory(),
new Random(apply.hashCode()));
data.update(false);
} catch(Exception e) {
LOGGER.error("Could not apply loot at {}", apply, e);
e.printStackTrace();
}
},
() -> LOGGER.error("No such loot table {}", id));
.ifPresentOrElse(table -> {
Vector3 apply = Vector3.of((int) Math.round(xz.getX()),
y.apply(implementationArguments, scope)
.intValue(),
(int) Math.round(xz.getZ())).mutable().add(arguments.getOrigin()).immutable();
try {
BlockEntity data = arguments.getWorld().getBlockEntity(apply);
if(!(data instanceof Container container)) {
LOGGER.error("Failed to place loot at {}; block {} is not a container",
apply, data);
return;
}
LootPopulateEvent event = new LootPopulateEvent(container, table,
arguments.getWorld().getPack(), script);
platform.getEventManager().callEvent(event);
if(event.isCancelled()) return;
event.getTable().fillInventory(container.getInventory(),
new Random(apply.hashCode()));
data.update(false);
} catch(Exception e) {
LOGGER.error("Could not apply loot at {}", apply, e);
e.printStackTrace();
}
},
() -> LOGGER.error("No such loot table {}", id));
return null;
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;

View File

@@ -26,26 +26,26 @@ public class PullFunction implements Function<Void> {
private final BlockState data;
private final Returnable<Number> x, y, z;
private final Position position;
public PullFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> data, Platform platform,
Position position) {
this.position = position;
if(!(data instanceof ConstantExpression)) throw new ParseException("Block data must be constant", data.getPosition());
this.data = platform.getWorldHandle().createBlockState(((ConstantExpression<String>) data).getConstant());
this.x = x;
this.y = y;
this.z = z;
}
@Override
public Void apply(ImplementationArguments implementationArguments, Scope scope) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = RotationUtil.rotateVector(Vector2.of(x.apply(implementationArguments, scope).doubleValue(),
z.apply(implementationArguments, scope).doubleValue()), arguments.getRotation());
z.apply(implementationArguments, scope).doubleValue()), arguments.getRotation());
Vector3.Mutable mutable = Vector3.of((int) Math.round(xz.getX()), y.apply(implementationArguments, scope).intValue(),
(int) Math.round(xz.getZ())).mutable().add(arguments.getOrigin());
(int) Math.round(xz.getZ())).mutable().add(arguments.getOrigin());
while(mutable.getY() > arguments.getWorld().getMinHeight()) {
if(!arguments.getWorld().getBlockState(mutable).isAir()) {
arguments.getWorld().setBlockState(mutable, data);
@@ -55,12 +55,12 @@ public class PullFunction implements Function<Void> {
}
return null;
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;

View File

@@ -18,24 +18,24 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class RandomFunction implements Function<Integer> {
private final Returnable<Number> numberReturnable;
private final Position position;
public RandomFunction(Returnable<Number> numberReturnable, Position position) {
this.numberReturnable = numberReturnable;
this.position = position;
}
@Override
public ReturnType returnType() {
return ReturnType.NUMBER;
}
@Override
public Integer apply(ImplementationArguments implementationArguments, Scope scope) {
return ((TerraImplementationArguments) implementationArguments).getRandom().nextInt(
numberReturnable.apply(implementationArguments, scope).intValue());
numberReturnable.apply(implementationArguments, scope).intValue());
}
@Override
public Position getPosition() {
return position;

View File

@@ -16,21 +16,21 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class RecursionsFunction implements Function<Number> {
private final Position position;
public RecursionsFunction(Position position) {
this.position = position;
}
@Override
public ReturnType returnType() {
return ReturnType.NUMBER;
}
@Override
public Number apply(ImplementationArguments implementationArguments, Scope scope) {
return ((TerraImplementationArguments) implementationArguments).getRecursions();
}
@Override
public Position getPosition() {
return position;

View File

@@ -22,7 +22,7 @@ public class SetMarkFunction implements Function<Void> {
private final Returnable<Number> x, y, z;
private final Position position;
private final Returnable<String> mark;
public SetMarkFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> mark, Position position) {
this.position = position;
this.mark = mark;
@@ -30,27 +30,27 @@ public class SetMarkFunction implements Function<Void> {
this.y = y;
this.z = z;
}
@Override
public Void apply(ImplementationArguments implementationArguments, Scope scope) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = RotationUtil.rotateVector(Vector2.of(x.apply(implementationArguments, scope).doubleValue(),
z.apply(implementationArguments, scope).doubleValue()), arguments.getRotation());
z.apply(implementationArguments, scope).doubleValue()), arguments.getRotation());
arguments.setMark(Vector3.of((int) Math.floor(xz.getX()),
(int) Math.floor(
y.apply(implementationArguments, scope).doubleValue()),
(int) Math.floor(xz.getZ())).mutable().add(arguments.getOrigin()).immutable(),
mark.apply(implementationArguments, scope));
(int) Math.floor(
y.apply(implementationArguments, scope).doubleValue()),
(int) Math.floor(xz.getZ())).mutable().add(arguments.getOrigin()).immutable(),
mark.apply(implementationArguments, scope));
return null;
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;

View File

@@ -27,7 +27,7 @@ public class StateFunction implements Function<Void> {
private final Returnable<String> data;
private final Returnable<Number> x, y, z;
private final Position position;
public StateFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> data,
Position position) {
this.position = position;
@@ -36,16 +36,16 @@ public class StateFunction implements Function<Void> {
this.y = y;
this.z = z;
}
@Override
public Void apply(ImplementationArguments implementationArguments, Scope scope) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = RotationUtil.rotateVector(Vector2.of(x.apply(implementationArguments, scope).doubleValue(),
z.apply(implementationArguments, scope).doubleValue()), arguments.getRotation());
z.apply(implementationArguments, scope).doubleValue()), arguments.getRotation());
Vector3 origin = Vector3.of((int) Math.round(xz.getX()), y.apply(implementationArguments, scope).intValue(),
(int) Math.round(xz.getZ())).mutable().add(arguments.getOrigin()).immutable();
(int) Math.round(xz.getZ())).mutable().add(arguments.getOrigin()).immutable();
try {
BlockEntity state = arguments.getWorld().getBlockEntity(origin);
state.applyState(data.apply(implementationArguments, scope));
@@ -56,12 +56,12 @@ public class StateFunction implements Function<Void> {
}
return null;
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;

View File

@@ -35,7 +35,7 @@ public class StructureFunction implements Function<Boolean> {
private final Position position;
private final Platform platform;
private final List<Returnable<String>> rotations;
public StructureFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> id,
List<Returnable<String>> rotations, Registry<Structure> registry, Position position, Platform platform) {
this.registry = registry;
@@ -47,23 +47,23 @@ public class StructureFunction implements Function<Boolean> {
this.platform = platform;
this.rotations = rotations;
}
@Override
public ReturnType returnType() {
return ReturnType.BOOLEAN;
}
@Override
public Boolean apply(ImplementationArguments implementationArguments, Scope scope) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
if(arguments.getRecursions() > platform.getTerraConfig().getMaxRecursion())
throw new RuntimeException("Structure recursion too deep: " + arguments.getRecursions());
Vector2 xz = RotationUtil.rotateVector(Vector2.of(x.apply(implementationArguments, scope).doubleValue(),
z.apply(implementationArguments, scope).doubleValue()), arguments.getRotation());
z.apply(implementationArguments, scope).doubleValue()), arguments.getRotation());
String app = id.apply(implementationArguments, scope);
return registry.getByID(app).map(script -> {
Rotation rotation1;
@@ -74,29 +74,29 @@ public class StructureFunction implements Function<Boolean> {
LOGGER.warn("Invalid rotation {}", rotString);
return false;
}
if(script instanceof StructureScript structureScript) {
return structureScript.generate(arguments.getOrigin(),
arguments.getWorld()
.buffer((int) Math.round(xz.getX()),
y.apply(implementationArguments, scope).intValue(),
(int) Math.round(xz.getZ())),
arguments.getRandom(),
arguments.getRotation().rotate(rotation1), arguments.getRecursions() + 1);
arguments.getWorld()
.buffer((int) Math.round(xz.getX()),
y.apply(implementationArguments, scope).intValue(),
(int) Math.round(xz.getZ())),
arguments.getRandom(),
arguments.getRotation().rotate(rotation1), arguments.getRecursions() + 1);
}
return script.generate(arguments.getOrigin(),
arguments.getWorld()
.buffer((int) Math.round(xz.getX()),
y.apply(implementationArguments, scope).intValue(),
(int) Math.round(xz.getZ())),
arguments.getRandom(),
arguments.getRotation().rotate(rotation1));
arguments.getWorld()
.buffer((int) Math.round(xz.getX()),
y.apply(implementationArguments, scope).intValue(),
(int) Math.round(xz.getZ())),
arguments.getRandom(),
arguments.getRotation().rotate(rotation1));
}).orElseGet(() -> {
LOGGER.error("No such structure {}", app);
return false;
});
}
@Override
public Position getPosition() {
return position;

View File

@@ -11,14 +11,14 @@ public class Char {
private final char character;
private final int index;
private final int line;
public Char(char character, int index, int line) {
this.character = character;
this.index = index;
this.line = line;
}
public boolean is(char... tests) {
for(char test : tests) {
if(test == character && test != '\0') {
@@ -27,36 +27,36 @@ public class Char {
}
return false;
}
@Override
public String toString() {
return Character.toString(character);
}
public char getCharacter() {
return character;
}
public int getIndex() {
return index;
}
public int getLine() {
return line;
}
public boolean isWhitespace() {
return Character.isWhitespace(character);
}
public boolean isNewLine() {
return character == '\n';
}
public boolean isDigit() {
return Character.isDigit(character);
}
public boolean isEOF() {
return character == '\0';
}

View File

@@ -23,11 +23,11 @@ public class Lookahead {
private int index = 0;
private int line = 0;
private boolean end = false;
public Lookahead(Reader r) {
this.input = r;
}
/**
* Get the current character without consuming it.
*
@@ -36,8 +36,8 @@ public class Lookahead {
public Char current() {
return next(0);
}
/**
* Consume and return one character.
*
@@ -48,7 +48,7 @@ public class Lookahead {
consume(1);
return consumed;
}
/**
* Fetch a future character without consuming it.
*
@@ -58,19 +58,19 @@ public class Lookahead {
*/
public Char next(int ahead) {
if(ahead < 0) throw new IllegalArgumentException();
while(buffer.size() <= ahead && !end) {
Char item = fetch();
if(item != null) {
buffer.add(item);
} else end = true;
}
if(ahead >= buffer.size()) {
return null;
} else return buffer.get(ahead);
}
/**
* Consume an amount of characters
*
@@ -87,18 +87,18 @@ public class Lookahead {
}
}
}
public boolean matches(String check, boolean consume) {
if(check == null) return false;
for(int i = 0; i < check.length(); i++) {
if(!next(i).is(check.charAt(i))) return false;
}
if(consume) consume(check.length()); // Consume string
return true;
}
/**
* Fetch the next character.
*
@@ -119,11 +119,11 @@ public class Lookahead {
return null;
}
}
public int getLine() {
return line;
}
public int getIndex() {
return index;
}

View File

@@ -10,12 +10,12 @@ package com.dfsek.terra.addons.terrascript.tokenizer;
public class Position {
private final int line;
private final int index;
public Position(int line, int index) {
this.line = line;
this.index = index;
}
@Override
public String toString() {
return (line + 1) + ":" + index;

View File

@@ -11,34 +11,34 @@ public class Token {
private final String content;
private final Type type;
private final Position start;
public Token(String content, Type type, Position start) {
this.content = content;
this.type = type;
this.start = start;
}
@Override
public String toString() {
return type + ": '" + content + "'";
}
public Type getType() {
return type;
}
public String getContent() {
return content;
}
public Position getPosition() {
return start;
}
public boolean isConstant() {
return this.type.equals(Type.NUMBER) || this.type.equals(Type.STRING) || this.type.equals(Type.BOOLEAN);
}
public boolean isBinaryOperator() {
return type.equals(Type.ADDITION_OPERATOR)
|| type.equals(Type.SUBTRACTION_OPERATOR)
@@ -54,7 +54,7 @@ public class Token {
|| type.equals(Type.BOOLEAN_AND)
|| type.equals(Type.MODULO_OPERATOR);
}
public boolean isStrictNumericOperator() {
return type.equals(Type.SUBTRACTION_OPERATOR)
|| type.equals(Type.MULTIPLICATION_OPERATOR)
@@ -65,34 +65,34 @@ public class Token {
|| type.equals(Type.GREATER_THAN_OR_EQUALS_OPERATOR)
|| type.equals(Type.MODULO_OPERATOR);
}
public boolean isStrictBooleanOperator() {
return type.equals(Type.BOOLEAN_AND)
|| type.equals(Type.BOOLEAN_OR);
}
public boolean isVariableDeclaration() {
return type.equals(Type.STRING_VARIABLE)
|| type.equals(Type.BOOLEAN_VARIABLE)
|| type.equals(Type.NUMBER_VARIABLE);
}
public boolean isLoopLike() {
return type.equals(Type.IF_STATEMENT)
|| type.equals(Type.WHILE_LOOP)
|| type.equals(Type.FOR_LOOP);
}
public boolean isIdentifier() {
return type.equals(Type.IDENTIFIER);
}
public enum Type {
/**
* Function identifier or language keyword
*/
IDENTIFIER,
/**
* Numeric literal
*/

View File

@@ -21,17 +21,17 @@ import com.dfsek.terra.addons.terrascript.tokenizer.exceptions.TokenizerExceptio
public class Tokenizer {
public static final Set<Character> syntaxSignificant = Sets.newHashSet(';', '(', ')', '"', ',', '\\', '=', '{', '}', '+', '-', '*', '/',
'>', '<', '!'); // Reserved chars
'>', '<', '!'); // Reserved chars
private final Lookahead reader;
private final Stack<Token> brackets = new Stack<>();
private Token current;
private Token last;
public Tokenizer(String data) {
reader = new Lookahead(new StringReader(data + '\0'));
current = fetchCheck();
}
/**
* Get the first token.
*
@@ -43,7 +43,7 @@ public class Tokenizer {
if(!hasNext()) throw new ParseException("Unexpected end of input", last.getPosition());
return current;
}
/**
* Consume (get and remove) the first token.
*
@@ -57,7 +57,7 @@ public class Tokenizer {
current = fetchCheck();
return temp;
}
private Token fetchCheck() {
Token fetch = fetch();
if(fetch != null) {
@@ -72,16 +72,16 @@ public class Tokenizer {
}
return fetch;
}
private Token fetch() throws TokenizerException {
while(!reader.current().isEOF() && reader.current().isWhitespace()) reader.consume();
while(reader.matches("//", true)) skipLine(); // Skip line if comment
if(reader.matches("/*", true)) skipTo("*/"); // Skip multi line comment
if(reader.current().isEOF()) return null; // EOF
if(reader.matches("==", true))
return new Token("==", Token.Type.EQUALS_OPERATOR, new Position(reader.getLine(), reader.getIndex()));
if(reader.matches("!=", true))
@@ -94,14 +94,14 @@ public class Tokenizer {
return new Token(">", Token.Type.GREATER_THAN_OPERATOR, new Position(reader.getLine(), reader.getIndex()));
if(reader.matches("<", true))
return new Token("<", Token.Type.LESS_THAN_OPERATOR, new Position(reader.getLine(), reader.getIndex()));
if(reader.matches("||", true))
return new Token("||", Token.Type.BOOLEAN_OR, new Position(reader.getLine(), reader.getIndex()));
if(reader.matches("&&", true))
return new Token("&&", Token.Type.BOOLEAN_AND, new Position(reader.getLine(), reader.getIndex()));
if(isNumberStart()) {
StringBuilder num = new StringBuilder();
while(!reader.current().isEOF() && isNumberLike()) {
@@ -109,7 +109,7 @@ public class Tokenizer {
}
return new Token(num.toString(), Token.Type.NUMBER, new Position(reader.getLine(), reader.getIndex()));
}
if(reader.current().is('"')) {
reader.consume(); // Consume first quote
StringBuilder string = new StringBuilder();
@@ -125,10 +125,10 @@ public class Tokenizer {
string.append(reader.consume());
}
reader.consume(); // Consume last quote
return new Token(string.toString(), Token.Type.STRING, new Position(reader.getLine(), reader.getIndex()));
}
if(reader.current().is('('))
return new Token(reader.consume().toString(), Token.Type.GROUP_BEGIN, new Position(reader.getLine(), reader.getIndex()));
if(reader.current().is(')'))
@@ -147,38 +147,38 @@ public class Tokenizer {
return new Token(reader.consume().toString(), Token.Type.ADDITION_OPERATOR, new Position(reader.getLine(), reader.getIndex()));
if(reader.current().is('-'))
return new Token(reader.consume().toString(), Token.Type.SUBTRACTION_OPERATOR,
new Position(reader.getLine(), reader.getIndex()));
new Position(reader.getLine(), reader.getIndex()));
if(reader.current().is('*'))
return new Token(reader.consume().toString(), Token.Type.MULTIPLICATION_OPERATOR,
new Position(reader.getLine(), reader.getIndex()));
new Position(reader.getLine(), reader.getIndex()));
if(reader.current().is('/'))
return new Token(reader.consume().toString(), Token.Type.DIVISION_OPERATOR, new Position(reader.getLine(), reader.getIndex()));
if(reader.current().is('%'))
return new Token(reader.consume().toString(), Token.Type.MODULO_OPERATOR, new Position(reader.getLine(), reader.getIndex()));
if(reader.current().is('!'))
return new Token(reader.consume().toString(), Token.Type.BOOLEAN_NOT, new Position(reader.getLine(), reader.getIndex()));
StringBuilder token = new StringBuilder();
while(!reader.current().isEOF() && !isSyntaxSignificant(reader.current().getCharacter())) {
Char c = reader.consume();
if(c.isWhitespace()) break;
token.append(c);
}
String tokenString = token.toString();
if(tokenString.equals("true"))
return new Token(tokenString, Token.Type.BOOLEAN, new Position(reader.getLine(), reader.getIndex()));
if(tokenString.equals("false"))
return new Token(tokenString, Token.Type.BOOLEAN, new Position(reader.getLine(), reader.getIndex()));
if(tokenString.equals("num"))
return new Token(tokenString, Token.Type.NUMBER_VARIABLE, new Position(reader.getLine(), reader.getIndex()));
if(tokenString.equals("str"))
return new Token(tokenString, Token.Type.STRING_VARIABLE, new Position(reader.getLine(), reader.getIndex()));
if(tokenString.equals("bool"))
return new Token(tokenString, Token.Type.BOOLEAN_VARIABLE, new Position(reader.getLine(), reader.getIndex()));
if(tokenString.equals("if"))
return new Token(tokenString, Token.Type.IF_STATEMENT, new Position(reader.getLine(), reader.getIndex()));
if(tokenString.equals("else"))
@@ -187,7 +187,7 @@ public class Tokenizer {
return new Token(tokenString, Token.Type.WHILE_LOOP, new Position(reader.getLine(), reader.getIndex()));
if(tokenString.equals("for"))
return new Token(tokenString, Token.Type.FOR_LOOP, new Position(reader.getLine(), reader.getIndex()));
if(tokenString.equals("return"))
return new Token(tokenString, Token.Type.RETURN, new Position(reader.getLine(), reader.getIndex()));
if(tokenString.equals("continue"))
@@ -196,19 +196,19 @@ public class Tokenizer {
return new Token(tokenString, Token.Type.BREAK, new Position(reader.getLine(), reader.getIndex()));
if(tokenString.equals("fail"))
return new Token(tokenString, Token.Type.FAIL, new Position(reader.getLine(), reader.getIndex()));
return new Token(tokenString, Token.Type.IDENTIFIER, new Position(reader.getLine(), reader.getIndex()));
}
private void skipLine() {
while(!reader.current().isEOF() && !reader.current().isNewLine()) reader.consume();
consumeWhitespace();
}
private void consumeWhitespace() {
while(!reader.current().isEOF() && reader.current().isWhitespace()) reader.consume(); // Consume whitespace.
}
private void skipTo(String s) throws EOFException {
Position begin = new Position(reader.getLine(), reader.getIndex());
while(!reader.current().isEOF()) {
@@ -220,7 +220,7 @@ public class Tokenizer {
}
throw new EOFException("No end of expression found.", begin);
}
/**
* Whether this {@code Tokenizer} contains additional tokens.
*
@@ -229,19 +229,19 @@ public class Tokenizer {
public boolean hasNext() {
return !(current == null);
}
private boolean isNumberLike() {
return reader.current().isDigit()
|| reader.current().is('_', '.', 'E');
}
private boolean isNumberStart() {
return reader.current().isDigit()
|| reader.current().is('.') && reader.next(1).isDigit();
}
public boolean isSyntaxSignificant(char c) {
return syntaxSignificant.contains(c);
}
}

View File

@@ -13,14 +13,14 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class EOFException extends TokenizerException {
@Serial
private static final long serialVersionUID = 3980047409902809440L;
public EOFException(String message, Position position) {
super(message, position);
}
public EOFException(String message, Position position, Throwable cause) {
super(message, position, cause);
}

View File

@@ -13,14 +13,14 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public class FormatException extends TokenizerException {
@Serial
private static final long serialVersionUID = -791308012940744455L;
public FormatException(String message, Position position) {
super(message, position);
}
public FormatException(String message, Position position, Throwable cause) {
super(message, position, cause);
}

View File

@@ -14,14 +14,14 @@ import com.dfsek.terra.addons.terrascript.tokenizer.Position;
public abstract class TokenizerException extends ParseException {
@Serial
private static final long serialVersionUID = 2792384010083575420L;
public TokenizerException(String message, Position position) {
super(message, position);
}
public TokenizerException(String message, Position position, Throwable cause) {
super(message, position, cause);
}

View File

@@ -18,7 +18,7 @@ public class LookaheadTest {
@Test
public void lookahead() {
Lookahead lookahead = new Lookahead(new StringReader("Test string..."));
for(int i = 0; lookahead.next(i) != null; i++) {
System.out.print(lookahead.next(i).getCharacter());
}

View File

@@ -31,19 +31,19 @@ public class ParserTest {
@Test
public void parse() throws IOException, ParseException {
Parser parser = new Parser(
IOUtils.toString(Objects.requireNonNull(getClass().getResourceAsStream("/test.tesf")), Charset.defaultCharset()));
IOUtils.toString(Objects.requireNonNull(getClass().getResourceAsStream("/test.tesf")), Charset.defaultCharset()));
parser.registerFunction("test", new FunctionBuilder<Test1>() {
@Override
public Test1 build(List<Returnable<?>> argumentList, Position position) {
return new Test1(argumentList.get(0), argumentList.get(1), position);
}
@Override
public int argNumber() {
return 2;
}
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {
@@ -52,42 +52,42 @@ public class ParserTest {
default -> null;
};
}
});
long l = System.nanoTime();
Executable block = parser.parse();
long t = System.nanoTime() - l;
System.out.println("Took " + (double) t / 1000000);
block.execute(null);
block.execute(null);
}
private static class Test1 implements Function<Void> {
private final Returnable<?> a;
private final Returnable<?> b;
private final Position position;
public Test1(Returnable<?> a, Returnable<?> b, Position position) {
this.a = a;
this.b = b;
this.position = position;
}
@Override
public Void apply(ImplementationArguments implementationArguments, Scope scope) {
System.out.println("string: " + a.apply(implementationArguments, scope) + ", double: " +
b.apply(implementationArguments, scope));
return null;
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;