diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/Parser.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/Parser.java index 19fcf8c4e..ee536915f 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/Parser.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/Parser.java @@ -12,7 +12,9 @@ import com.dfsek.terra.api.structures.parser.lang.functions.Function; import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder; import com.dfsek.terra.api.structures.parser.lang.keywords.IfKeyword; import com.dfsek.terra.api.structures.parser.lang.operations.BinaryOperation; +import com.dfsek.terra.api.structures.parser.lang.operations.BooleanAndOperation; 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.MultiplicationOperation; @@ -156,7 +158,8 @@ public class Parser { private BinaryOperation parseBinaryOperation(Returnable left, List tokens) throws ParseException { Token binaryOperator = tokens.remove(0); checkType(binaryOperator, Token.Type.ADDITION_OPERATOR, Token.Type.MULTIPLICATION_OPERATOR, Token.Type.DIVISION_OPERATOR, Token.Type.SUBTRACTION_OPERATOR, - Token.Type.GREATER_THAN_OPERATOR, Token.Type.LESS_THAN_OPERATOR, Token.Type.LESS_THAN_OR_EQUALS_OPERATOR, Token.Type.GREATER_THAN_OR_EQUALS_OPERATOR, Token.Type.EQUALS_OPERATOR, Token.Type.NOT_EQUALS_OPERATOR); + Token.Type.GREATER_THAN_OPERATOR, Token.Type.LESS_THAN_OPERATOR, Token.Type.LESS_THAN_OR_EQUALS_OPERATOR, Token.Type.GREATER_THAN_OR_EQUALS_OPERATOR, Token.Type.EQUALS_OPERATOR, Token.Type.NOT_EQUALS_OPERATOR, + Token.Type.BOOLEAN_AND, Token.Type.BOOLEAN_OR); Returnable right = parseExpression(tokens, false); @@ -172,6 +175,7 @@ public class Parser { @SuppressWarnings("unchecked") private BinaryOperation assemble(Returnable left, Returnable right, Token binaryOperator) throws ParseException { if(binaryOperator.isStrictNumericOperator()) checkArithmeticOperation(left, right, binaryOperator.getType()); + if(binaryOperator.isStrictBooleanOperator()) checkBooleanOperation(left, right, binaryOperator.getType()); switch(binaryOperator.getType()) { case ADDITION_OPERATOR: if(left.returnType().equals(Returnable.ReturnType.NUMBER) && right.returnType().equals(Returnable.ReturnType.NUMBER)) { @@ -196,6 +200,10 @@ public class Parser { return new GreaterOrEqualsThanStatement((Returnable) left, (Returnable) right, binaryOperator.getPosition()); case LESS_THAN_OR_EQUALS_OPERATOR: return new LessThanOrEqualsStatement((Returnable) left, (Returnable) right, binaryOperator.getPosition()); + case BOOLEAN_AND: + return new BooleanAndOperation((Returnable) left, (Returnable) right, binaryOperator.getPosition()); + case BOOLEAN_OR: + return new BooleanOrOperation((Returnable) left, (Returnable) right, binaryOperator.getPosition()); default: throw new UnsupportedOperationException("Unsupported binary operator: " + binaryOperator.getType()); } @@ -278,4 +286,10 @@ public class Parser { throw new ParseException("Operation " + operation + " not supported between " + left.returnType() + " and " + right.returnType()); } } + + private void checkBooleanOperation(Returnable left, Returnable right, Token.Type operation) throws ParseException { + if(!left.returnType().equals(Returnable.ReturnType.BOOLEAN) || !right.returnType().equals(Returnable.ReturnType.BOOLEAN)) { + throw new ParseException("Operation " + operation + " not supported between " + left.returnType() + " and " + right.returnType()); + } + } } diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/BinaryOperation.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/BinaryOperation.java index 360db72be..dc583d20e 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/BinaryOperation.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/BinaryOperation.java @@ -10,7 +10,7 @@ public abstract class BinaryOperation implements Returnable { private final Returnable right; private final Position start; - protected BinaryOperation(Returnable left, Returnable right, Position start) { + public BinaryOperation(Returnable left, Returnable right, Position start) { this.left = left; this.right = right; this.start = start; diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/BooleanAndOperation.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/BooleanAndOperation.java new file mode 100644 index 000000000..3bca80717 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/BooleanAndOperation.java @@ -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 BooleanAndOperation extends BinaryOperation { + public BooleanAndOperation(Returnable left, Returnable right, Position start) { + super(left, right, start); + } + + @Override + public Boolean apply(Boolean left, Boolean right) { + return left && right; + } + + @Override + public ReturnType returnType() { + return ReturnType.BOOLEAN; + } +} diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/BooleanOrOperation.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/BooleanOrOperation.java new file mode 100644 index 000000000..513c35be5 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/BooleanOrOperation.java @@ -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 BooleanOrOperation extends BinaryOperation { + public BooleanOrOperation(Returnable left, Returnable right, Position start) { + super(left, right, start); + } + + @Override + public Boolean apply(Boolean left, Boolean right) { + return left || right; + } + + @Override + public ReturnType returnType() { + return ReturnType.BOOLEAN; + } +} diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/UnaryOperation.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/UnaryOperation.java index 8f0db76e5..bc1e1e902 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/UnaryOperation.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/UnaryOperation.java @@ -9,7 +9,7 @@ public abstract class UnaryOperation implements Returnable { private final Returnable input; private final Position position; - protected UnaryOperation(Returnable input, Position position) { + public UnaryOperation(Returnable input, Position position) { this.input = input; this.position = position; } diff --git a/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Token.java b/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Token.java index 1e09aa6bd..d6cea01a3 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Token.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Token.java @@ -42,7 +42,9 @@ public class Token { || type.equals(Type.LESS_THAN_OPERATOR) || type.equals(Type.GREATER_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.BOOLEAN_OR) + || type.equals(Type.BOOLEAN_AND); } public boolean isStrictNumericOperator() { @@ -55,6 +57,11 @@ public class Token { || type.equals(Type.GREATER_THAN_OR_EQUALS_OPERATOR); } + public boolean isStrictBooleanOperator() { + return type.equals(Type.BOOLEAN_AND) + || type.equals(Type.BOOLEAN_OR); + } + public enum Type { /** * Function identifier or language keyword @@ -148,6 +155,14 @@ public class Token { /** * Boolean not operator */ - BOOLEAN_NOT + BOOLEAN_NOT, + /** + * Boolean or + */ + BOOLEAN_OR, + /** + * Boolean and + */ + BOOLEAN_AND } } diff --git a/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Tokenizer.java b/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Tokenizer.java index e886ca509..526f6c3dd 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Tokenizer.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Tokenizer.java @@ -50,6 +50,10 @@ public class Tokenizer { return new Token(">=", Token.Type.GREATER_THAN_OR_EQUALS_OPERATOR, new Position(reader.getLine(), reader.getIndex())); if(reader.matches("<=", true)) return new Token("<=", Token.Type.LESS_THAN_OR_EQUALS_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()) { diff --git a/common/src/test/resources/test.tesf b/common/src/test/resources/test.tesf index 35aa873b3..f067052ce 100644 --- a/common/src/test/resources/test.tesf +++ b/common/src/test/resources/test.tesf @@ -1,5 +1,5 @@ -test("hello" + 3 + "gdfg", (2 * (3+1))); +test("hello" + 3 + "gdfg", (2 * (3+1) * (2 * (1+1)))); -if(true == test("hello" + 3 + "gdfg", 3 + 8*2 - 1)) { +if(true || false) { test("fdsgdf" + 2, 3.4); } \ No newline at end of file