mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-04-03 14:26:27 +00:00
Implement boolean binary operations AND and OR
This commit is contained in:
@@ -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<Token> 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<Number>) left, (Returnable<Number>) right, binaryOperator.getPosition());
|
||||
case LESS_THAN_OR_EQUALS_OPERATOR:
|
||||
return new LessThanOrEqualsStatement((Returnable<Number>) left, (Returnable<Number>) right, binaryOperator.getPosition());
|
||||
case BOOLEAN_AND:
|
||||
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());
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ public abstract class BinaryOperation<I, O> implements Returnable<O> {
|
||||
private final Returnable<I> right;
|
||||
private final Position start;
|
||||
|
||||
protected BinaryOperation(Returnable<I> left, Returnable<I> right, Position start) {
|
||||
public BinaryOperation(Returnable<I> left, Returnable<I> right, Position start) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this.start = start;
|
||||
|
||||
@@ -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<Boolean, Boolean> {
|
||||
public BooleanAndOperation(Returnable<Boolean> left, Returnable<Boolean> 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;
|
||||
}
|
||||
}
|
||||
@@ -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<Boolean, Boolean> {
|
||||
public BooleanOrOperation(Returnable<Boolean> left, Returnable<Boolean> 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;
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ public abstract class UnaryOperation<T> implements Returnable<T> {
|
||||
private final Returnable<T> input;
|
||||
private final Position position;
|
||||
|
||||
protected UnaryOperation(Returnable<T> input, Position position) {
|
||||
public UnaryOperation(Returnable<T> input, Position position) {
|
||||
this.input = input;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user