mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-02-16 10:30:42 +00:00
set up framework for binary operations
This commit is contained in:
@@ -98,7 +98,7 @@ public class Parser {
|
||||
|
||||
private Executable<?> parseExpression(List<Token> tokens) throws ParseException {
|
||||
if(tokens.get(0).isConstant()) {
|
||||
return new ConstantExpression(tokens.remove(0).getContent());
|
||||
return new ConstantExpression<>(tokens.remove(0).getContent());
|
||||
} else return parseFunction(tokens, false);
|
||||
}
|
||||
|
||||
@@ -128,21 +128,21 @@ public class Parser {
|
||||
return new Block(parsedItems);
|
||||
}
|
||||
|
||||
private Function<?> parseFunction(List<Token> functionAndArguments, boolean fullStatement) throws ParseException {
|
||||
Token identifier = functionAndArguments.remove(0);
|
||||
private Function<?> parseFunction(List<Token> tokens, boolean fullStatement) throws ParseException {
|
||||
Token identifier = tokens.remove(0);
|
||||
checkType(identifier, Token.Type.IDENTIFIER); // First token must be identifier
|
||||
|
||||
if(!functions.containsKey(identifier.getContent()))
|
||||
throw new ParseException("No such function " + identifier.getContent() + ": " + identifier.getStart());
|
||||
|
||||
checkType(functionAndArguments.remove(0), Token.Type.BODY_BEGIN); // Second is body begin
|
||||
checkType(tokens.remove(0), Token.Type.BODY_BEGIN); // Second is body begin
|
||||
|
||||
|
||||
List<Token> args = getArgs(functionAndArguments); // Extract arguments, consume the rest.
|
||||
List<Token> args = getArgs(tokens); // Extract arguments, consume the rest.
|
||||
|
||||
functionAndArguments.remove(0); // Remove body end
|
||||
tokens.remove(0); // Remove body end
|
||||
|
||||
if(fullStatement) checkType(functionAndArguments.get(0), Token.Type.STATEMENT_END);
|
||||
if(fullStatement) checkType(tokens.get(0), Token.Type.STATEMENT_END);
|
||||
|
||||
List<String> arg = args.stream().map(Token::getContent).collect(Collectors.toList());
|
||||
|
||||
|
||||
@@ -3,21 +3,29 @@ package com.dfsek.terra.api.structures.parser.lang;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.world.Chunk;
|
||||
|
||||
public class ConstantExpression implements Executable<Object> {
|
||||
private final Object constant;
|
||||
public class ConstantExpression<T> implements Executable<T> {
|
||||
private final T constant;
|
||||
|
||||
public ConstantExpression(Object constant) {
|
||||
public ConstantExpression(T constant) {
|
||||
this.constant = constant;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object apply(Location location) {
|
||||
public T apply(Location location) {
|
||||
return constant;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object apply(Location location, Chunk chunk) {
|
||||
public T apply(Location location, Chunk chunk) {
|
||||
return constant;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReturnType returnType() {
|
||||
if(constant instanceof String) return ReturnType.STRING;
|
||||
if(constant instanceof Number) return ReturnType.NUMBER;
|
||||
if(constant instanceof Boolean) return ReturnType.BOOLEAN;
|
||||
return ReturnType.OBJECT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,19 @@
|
||||
package com.dfsek.terra.api.structures.parser.lang;
|
||||
|
||||
public interface Executable<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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.dfsek.terra.api.structures.parser.lang;
|
||||
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.world.Chunk;
|
||||
import com.dfsek.terra.api.structures.parser.lang.operations.BinaryOperation;
|
||||
|
||||
public class Expression<T> implements Executable<T> {
|
||||
private final ReturnType type;
|
||||
private final Executable<T> left;
|
||||
private final Executable<T> right;
|
||||
private final BinaryOperation<T> operation;
|
||||
|
||||
public Expression(ReturnType type, Executable<T> left, Executable<T> right, BinaryOperation<T> operation) {
|
||||
this.type = type;
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReturnType returnType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(Location location) {
|
||||
return operation.apply(left.apply(location), right.apply(location));
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(Location location, Chunk chunk) {
|
||||
return operation.apply(left.apply(location, chunk), right.apply(location, chunk));
|
||||
}
|
||||
}
|
||||
@@ -26,4 +26,9 @@ public class IfKeyword implements Keyword<Void> {
|
||||
if(statement.apply(location, chunk)) conditional.apply(location, chunk);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReturnType returnType() {
|
||||
return ReturnType.VOID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,4 +14,9 @@ public class ReturnKeyword implements Keyword<Void> {
|
||||
public Void apply(Location location, Chunk chunk) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReturnType returnType() {
|
||||
return ReturnType.VOID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.dfsek.terra.api.structures.parser.lang.operations;
|
||||
|
||||
public interface BinaryOperation<T> {
|
||||
T apply(T left, T right);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.dfsek.terra.api.structures.parser.lang.operations;
|
||||
|
||||
public class ConcatenationOperation implements BinaryOperation<Object> {
|
||||
@Override
|
||||
public String apply(Object left, Object right) {
|
||||
return left.toString() + right.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.dfsek.terra.api.structures.parser.lang.operations;
|
||||
|
||||
public class NumberAdditionOperation implements BinaryOperation<Number> {
|
||||
@Override
|
||||
public Number apply(Number left, Number right) {
|
||||
return left.doubleValue() + right.doubleValue();
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,6 @@ public class EqualsStatement implements Statement {
|
||||
|
||||
@Override
|
||||
public Boolean apply(Location location) {
|
||||
System.out.println(left.apply(location));
|
||||
System.out.println(right.apply(location));
|
||||
return left.apply(location).equals(right.apply(location));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.dfsek.terra.api.structures.parser.lang.statements;
|
||||
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.world.Chunk;
|
||||
import com.dfsek.terra.api.structures.parser.lang.Item;
|
||||
import com.dfsek.terra.api.structures.parser.lang.Statement;
|
||||
|
||||
public class GreaterThanStatement<T extends Comparable<T>> implements Statement {
|
||||
private final Item<T> left;
|
||||
private final Item<T> right;
|
||||
|
||||
public GreaterThanStatement(Item<T> left, Item<T> right) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean apply(Location location) {
|
||||
return left.apply(location).compareTo(right.apply(location)) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean apply(Location location, Chunk chunk) {
|
||||
return left.apply(location).compareTo(right.apply(location)) > 0;
|
||||
}
|
||||
}
|
||||
@@ -16,13 +16,11 @@ public class NotEqualsStatement implements Statement {
|
||||
|
||||
@Override
|
||||
public Boolean apply(Location location) {
|
||||
System.out.println(left.apply(location));
|
||||
System.out.println(right.apply(location));
|
||||
return !left.apply(location).equals(right.apply(location));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean apply(Location location, Chunk chunk) {
|
||||
return left.apply(location, chunk).equals(right.apply(location, chunk));
|
||||
return !left.apply(location, chunk).equals(right.apply(location, chunk));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,4 +32,9 @@ public class BlockFunction implements Function<Void> {
|
||||
//TODO: do
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReturnType returnType() {
|
||||
return ReturnType.VOID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,4 +40,9 @@ public class CheckFunction implements Function<String> {
|
||||
return "OCEAN";
|
||||
return "AIR";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReturnType returnType() {
|
||||
return ReturnType.STRING;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,10 @@ public class Token {
|
||||
/**
|
||||
* Boolean operator
|
||||
*/
|
||||
BOOLEAN_OPERATOR
|
||||
BOOLEAN_OPERATOR,
|
||||
/**
|
||||
* Addition/concatenation operator
|
||||
*/
|
||||
ADDITION_OPERATOR
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +82,8 @@ public class Tokenizer {
|
||||
return new Token(reader.consume().toString(), Token.Type.BLOCK_END, new Position(reader.getLine(), reader.getIndex()));
|
||||
if(reader.current().is('='))
|
||||
return new Token(reader.consume().toString(), Token.Type.ASSIGNMENT, new Position(reader.getLine(), reader.getIndex()));
|
||||
if(reader.current().is('+'))
|
||||
return new Token(reader.consume().toString(), Token.Type.ADDITION_OPERATOR, new Position(reader.getLine(), reader.getIndex()));
|
||||
|
||||
StringBuilder token = new StringBuilder();
|
||||
while(!reader.current().isEOF() && !isSyntaxSignificant(reader.current().getCharacter())) {
|
||||
|
||||
@@ -74,5 +74,10 @@ public class ParserTest {
|
||||
public String toString() {
|
||||
return "string: " + a + ", double: " + b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReturnType returnType() {
|
||||
return ReturnType.VOID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user