implement ModuloOperation

This commit is contained in:
dfsek
2021-01-02 01:08:45 -07:00
parent b209c49877
commit 0fef1619d2
8 changed files with 52 additions and 9 deletions

View File

@@ -24,6 +24,7 @@ import com.dfsek.terra.api.structures.parser.lang.operations.BooleanNotOperation
import com.dfsek.terra.api.structures.parser.lang.operations.BooleanOrOperation;
import com.dfsek.terra.api.structures.parser.lang.operations.ConcatenationOperation;
import com.dfsek.terra.api.structures.parser.lang.operations.DivisionOperation;
import com.dfsek.terra.api.structures.parser.lang.operations.ModuloOperation;
import com.dfsek.terra.api.structures.parser.lang.operations.MultiplicationOperation;
import com.dfsek.terra.api.structures.parser.lang.operations.NumberAdditionOperation;
import com.dfsek.terra.api.structures.parser.lang.operations.SubtractionOperation;
@@ -321,6 +322,8 @@ public class Parser {
return new BooleanAndOperation((Returnable<Boolean>) left, (Returnable<Boolean>) right, binaryOperator.getPosition());
case BOOLEAN_OR:
return new BooleanOrOperation((Returnable<Boolean>) left, (Returnable<Boolean>) right, binaryOperator.getPosition());
case MODULO_OPERATOR:
return new ModuloOperation((Returnable<Number>) left, (Returnable<Number>) right, binaryOperator.getPosition());
default:
throw new UnsupportedOperationException("Unsupported binary operator: " + binaryOperator.getType());
}

View File

@@ -12,7 +12,7 @@ import java.util.Map;
public class ParserUtil {
private static final Map<Token.Type, List<Token.Type>> PRECEDENCE = new HashMap<>();
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);
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);
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);
static { // Setup precedence

View File

@@ -0,0 +1,20 @@
package com.dfsek.terra.api.structures.parser.lang.operations;
import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.tokenizer.Position;
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(Number left, Number right) {
return left.doubleValue() % right.doubleValue();
}
@Override
public ReturnType returnType() {
return ReturnType.NUMBER;
}
}

View File

@@ -3,6 +3,7 @@ package com.dfsek.terra.api.structures.script.builders;
import com.dfsek.terra.api.platform.TerraPlugin;
import com.dfsek.terra.api.structures.parser.exceptions.ParseException;
import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.constants.BooleanConstant;
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
import com.dfsek.terra.api.structures.script.functions.BlockFunction;
import com.dfsek.terra.api.structures.tokenizer.Position;
@@ -19,12 +20,15 @@ public class BlockFunctionBuilder implements FunctionBuilder<BlockFunction> {
@SuppressWarnings("unchecked")
@Override
public BlockFunction build(List<Returnable<?>> argumentList, Position position) throws ParseException {
return new BlockFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), main, position);
if(argumentList.size() < 4) throw new ParseException("Expected data", position);
Returnable<Boolean> booleanReturnable = new BooleanConstant(true, position);
if(argumentList.size() == 5) booleanReturnable = (Returnable<Boolean>) argumentList.get(4);
return new BlockFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), booleanReturnable, main, position);
}
@Override
public int argNumber() {
return 4;
return -1;
}
@Override
@@ -36,6 +40,8 @@ public class BlockFunctionBuilder implements FunctionBuilder<BlockFunction> {
return Returnable.ReturnType.NUMBER;
case 3:
return Returnable.ReturnType.STRING;
case 4:
return Returnable.ReturnType.BOOLEAN;
default:
return null;
}

View File

@@ -19,8 +19,9 @@ public class BlockFunction implements Function<Void> {
private final BlockData data;
private final Returnable<Number> x, y, z;
private final Position position;
private final Returnable<Boolean> overwrite;
public BlockFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> data, TerraPlugin main, Position position) throws ParseException {
public BlockFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> data, Returnable<Boolean> overwrite, TerraPlugin main, Position position) throws ParseException {
this.position = position;
if(!(data instanceof ConstantExpression)) throw new ParseException("Block data must be constant", data.getPosition());
@@ -28,6 +29,7 @@ public class BlockFunction implements Function<Void> {
this.x = x;
this.y = y;
this.z = z;
this.overwrite = overwrite;
}
@Override
@@ -38,7 +40,7 @@ public class BlockFunction implements Function<Void> {
RotationUtil.rotateVector(xz, arguments.getRotation());
BlockData rot = data.clone();
RotationUtil.rotateBlockData(rot, arguments.getRotation().inverse());
arguments.getBuffer().addItem(new BufferedBlock(rot), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments).intValue(), FastMath.roundToInt(xz.getZ())));
arguments.getBuffer().addItem(new BufferedBlock(rot, overwrite.apply(implementationArguments)), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments).intValue(), FastMath.roundToInt(xz.getZ())));
return null;
}

View File

@@ -1,17 +1,21 @@
package com.dfsek.terra.api.structures.structure.buffer.items;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.platform.block.Block;
import com.dfsek.terra.api.platform.block.BlockData;
public class BufferedBlock implements BufferedItem {
private final BlockData data;
private final boolean overwrite;
public BufferedBlock(BlockData data) {
public BufferedBlock(BlockData data, boolean overwrite) {
this.data = data;
this.overwrite = overwrite;
}
@Override
public void paste(Location origin) {
origin.getBlock().setBlockData(data, false);
Block block = origin.getBlock();
if(overwrite || block.isEmpty()) block.setBlockData(data, false);
}
}

View File

@@ -44,7 +44,8 @@ public class Token {
|| type.equals(Type.LESS_THAN_OR_EQUALS_OPERATOR)
|| type.equals(Type.GREATER_THAN_OR_EQUALS_OPERATOR)
|| type.equals(Type.BOOLEAN_OR)
|| type.equals(Type.BOOLEAN_AND);
|| type.equals(Type.BOOLEAN_AND)
|| type.equals(Type.MODULO_OPERATOR);
}
public boolean isStrictNumericOperator() {
@@ -54,7 +55,8 @@ public class Token {
|| type.equals(Type.GREATER_THAN_OPERATOR)
|| type.equals(Type.LESS_THAN_OPERATOR)
|| type.equals(Type.LESS_THAN_OR_EQUALS_OPERATOR)
|| type.equals(Type.GREATER_THAN_OR_EQUALS_OPERATOR);
|| type.equals(Type.GREATER_THAN_OR_EQUALS_OPERATOR)
|| type.equals(Type.MODULO_OPERATOR);
}
public boolean isStrictBooleanOperator() {
@@ -164,6 +166,10 @@ public class Token {
* Division operator
*/
DIVISION_OPERATOR,
/**
* Modulo operator.
*/
MODULO_OPERATOR,
/**
* Boolean not operator
*/

View File

@@ -96,6 +96,8 @@ public class Tokenizer {
return new Token(reader.consume().toString(), Token.Type.MULTIPLICATION_OPERATOR, 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()));