terrascript should be thread safe now

This commit is contained in:
dfsek 2021-01-15 00:59:04 -07:00
parent 346a8826aa
commit 6d1dd3acbf
38 changed files with 301 additions and 175 deletions

View File

@ -36,11 +36,8 @@ import com.dfsek.terra.api.structures.parser.lang.operations.statements.LessThan
import com.dfsek.terra.api.structures.parser.lang.operations.statements.LessThanStatement; import com.dfsek.terra.api.structures.parser.lang.operations.statements.LessThanStatement;
import com.dfsek.terra.api.structures.parser.lang.operations.statements.NotEqualsStatement; import com.dfsek.terra.api.structures.parser.lang.operations.statements.NotEqualsStatement;
import com.dfsek.terra.api.structures.parser.lang.variables.Assignment; import com.dfsek.terra.api.structures.parser.lang.variables.Assignment;
import com.dfsek.terra.api.structures.parser.lang.variables.BooleanVariable; import com.dfsek.terra.api.structures.parser.lang.variables.Declaration;
import com.dfsek.terra.api.structures.parser.lang.variables.Getter; import com.dfsek.terra.api.structures.parser.lang.variables.Getter;
import com.dfsek.terra.api.structures.parser.lang.variables.NumberVariable;
import com.dfsek.terra.api.structures.parser.lang.variables.StringVariable;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import com.dfsek.terra.api.structures.tokenizer.Token; import com.dfsek.terra.api.structures.tokenizer.Token;
import com.dfsek.terra.api.structures.tokenizer.Tokenizer; import com.dfsek.terra.api.structures.tokenizer.Tokenizer;
@ -92,7 +89,7 @@ public class Parser {
} }
private Keyword<?> parseLoopLike(Tokenizer tokens, Map<String, Variable<?>> variableMap, boolean loop) throws ParseException { private Keyword<?> parseLoopLike(Tokenizer tokens, Map<String, Returnable.ReturnType> variableMap, boolean loop) throws ParseException {
Token identifier = tokens.consume(); Token identifier = tokens.consume();
ParserUtil.checkType(identifier, Token.Type.IF_STATEMENT, Token.Type.WHILE_LOOP, Token.Type.FOR_LOOP); ParserUtil.checkType(identifier, Token.Type.IF_STATEMENT, Token.Type.WHILE_LOOP, Token.Type.FOR_LOOP);
@ -111,7 +108,7 @@ public class Parser {
} }
} }
private WhileKeyword parseWhileLoop(Tokenizer tokens, Map<String, Variable<?>> variableMap, Position start) throws ParseException { private WhileKeyword parseWhileLoop(Tokenizer tokens, Map<String, Returnable.ReturnType> variableMap, Position start) throws ParseException {
Returnable<?> first = parseExpression(tokens, true, variableMap); Returnable<?> first = parseExpression(tokens, true, variableMap);
ParserUtil.checkReturnType(first, Returnable.ReturnType.BOOLEAN); ParserUtil.checkReturnType(first, Returnable.ReturnType.BOOLEAN);
@ -120,7 +117,7 @@ public class Parser {
return new WhileKeyword(parseStatementBlock(tokens, variableMap, true), (Returnable<Boolean>) first, start); // While loop return new WhileKeyword(parseStatementBlock(tokens, variableMap, true), (Returnable<Boolean>) first, start); // While loop
} }
private IfKeyword parseIfStatement(Tokenizer tokens, Map<String, Variable<?>> variableMap, Position start, boolean loop) throws ParseException { private IfKeyword parseIfStatement(Tokenizer tokens, Map<String, Returnable.ReturnType> variableMap, Position start, boolean loop) throws ParseException {
Returnable<?> condition = parseExpression(tokens, true, variableMap); Returnable<?> condition = parseExpression(tokens, true, variableMap);
ParserUtil.checkReturnType(condition, Returnable.ReturnType.BOOLEAN); ParserUtil.checkReturnType(condition, Returnable.ReturnType.BOOLEAN);
@ -147,7 +144,7 @@ public class Parser {
return new IfKeyword(statement, (Returnable<Boolean>) condition, elseIf, elseBlock, start); // If statement return new IfKeyword(statement, (Returnable<Boolean>) condition, elseIf, elseBlock, start); // If statement
} }
private Block parseStatementBlock(Tokenizer tokens, Map<String, Variable<?>> variableMap, boolean loop) throws ParseException { private Block parseStatementBlock(Tokenizer tokens, Map<String, Returnable.ReturnType> variableMap, boolean loop) throws ParseException {
if(tokens.get().getType().equals(Token.Type.BLOCK_BEGIN)) { if(tokens.get().getType().equals(Token.Type.BLOCK_BEGIN)) {
ParserUtil.checkType(tokens.consume(), Token.Type.BLOCK_BEGIN); ParserUtil.checkType(tokens.consume(), Token.Type.BLOCK_BEGIN);
@ -162,21 +159,17 @@ public class Parser {
} }
} }
private ForKeyword parseForLoop(Tokenizer tokens, Map<String, Variable<?>> old, Position start) throws ParseException { private ForKeyword parseForLoop(Tokenizer tokens, Map<String, Returnable.ReturnType> old, Position start) throws ParseException {
Map<String, Variable<?>> variableMap = new HashMap<>(old); // New scope Map<String, Returnable.ReturnType> variableMap = new HashMap<>(old); // New scope
Token f = tokens.get(); Token f = tokens.get();
ParserUtil.checkType(f, Token.Type.NUMBER_VARIABLE, Token.Type.STRING_VARIABLE, Token.Type.BOOLEAN_VARIABLE, Token.Type.IDENTIFIER); ParserUtil.checkType(f, Token.Type.NUMBER_VARIABLE, Token.Type.STRING_VARIABLE, Token.Type.BOOLEAN_VARIABLE, Token.Type.IDENTIFIER);
Item<?> initializer; Item<?> initializer;
if(f.isVariableDeclaration()) { if(f.isVariableDeclaration()) {
Variable<?> forVar = parseVariableDeclaration(tokens, ParserUtil.getVariableReturnType(f)); Declaration<?> forVar = parseVariableDeclaration(tokens, variableMap);
ParserUtil.checkType(tokens.consume(), Token.Type.STRING_VARIABLE, Token.Type.BOOLEAN_VARIABLE, Token.Type.NUMBER_VARIABLE);
Token name = tokens.get(); Token name = tokens.get();
if(functions.containsKey(name.getContent()) || variableMap.containsKey(name.getContent())) if(functions.containsKey(name.getContent()) || variableMap.containsKey(name.getContent()))
throw new ParseException(name.getContent() + " is already defined in this scope", name.getPosition()); throw new ParseException(name.getContent() + " is already defined in this scope", name.getPosition());
initializer = forVar;
initializer = parseAssignment(forVar, tokens, variableMap);
variableMap.put(name.getContent(), forVar);
} else initializer = parseExpression(tokens, true, variableMap); } else initializer = parseExpression(tokens, true, variableMap);
ParserUtil.checkType(tokens.consume(), Token.Type.STATEMENT_END); ParserUtil.checkType(tokens.consume(), Token.Type.STATEMENT_END);
Returnable<?> conditional = parseExpression(tokens, true, variableMap); Returnable<?> conditional = parseExpression(tokens, true, variableMap);
@ -186,8 +179,7 @@ public class Parser {
Item<?> incrementer; Item<?> incrementer;
Token token = tokens.get(); Token token = tokens.get();
if(variableMap.containsKey(token.getContent())) { // Assume variable assignment if(variableMap.containsKey(token.getContent())) { // Assume variable assignment
Variable<?> variable = variableMap.get(token.getContent()); incrementer = parseAssignment(tokens, variableMap);
incrementer = parseAssignment(variable, tokens, variableMap);
} else incrementer = parseFunction(tokens, true, variableMap); } else incrementer = parseFunction(tokens, true, variableMap);
ParserUtil.checkType(tokens.consume(), Token.Type.GROUP_END); ParserUtil.checkType(tokens.consume(), Token.Type.GROUP_END);
@ -195,7 +187,7 @@ public class Parser {
return new ForKeyword(parseStatementBlock(tokens, variableMap, true), initializer, (Returnable<Boolean>) conditional, incrementer, start); return new ForKeyword(parseStatementBlock(tokens, variableMap, true), initializer, (Returnable<Boolean>) conditional, incrementer, start);
} }
private Returnable<?> parseExpression(Tokenizer tokens, boolean full, Map<String, Variable<?>> variableMap) throws ParseException { private Returnable<?> parseExpression(Tokenizer tokens, boolean full, Map<String, Returnable.ReturnType> variableMap) throws ParseException {
boolean booleanInverted = false; // Check for boolean not operator boolean booleanInverted = false; // Check for boolean not operator
boolean negate = false; boolean negate = false;
if(tokens.get().getType().equals(Token.Type.BOOLEAN_NOT)) { if(tokens.get().getType().equals(Token.Type.BOOLEAN_NOT)) {
@ -220,7 +212,7 @@ public class Parser {
expression = parseFunction(tokens, false, variableMap); expression = parseFunction(tokens, false, variableMap);
else if(variableMap.containsKey(id.getContent())) { else if(variableMap.containsKey(id.getContent())) {
ParserUtil.checkType(tokens.consume(), Token.Type.IDENTIFIER); ParserUtil.checkType(tokens.consume(), Token.Type.IDENTIFIER);
expression = new Getter(variableMap.get(id.getContent())); expression = new Getter(id.getContent(), id.getPosition(), variableMap.get(id.getContent()));
} else throw new ParseException("Unexpected token \" " + id.getContent() + "\"", id.getPosition()); } else throw new ParseException("Unexpected token \" " + id.getContent() + "\"", id.getPosition());
} }
@ -254,7 +246,7 @@ public class Parser {
} }
} }
private Returnable<?> parseGroup(Tokenizer tokens, Map<String, Variable<?>> variableMap) throws ParseException { private Returnable<?> parseGroup(Tokenizer tokens, Map<String, Returnable.ReturnType> variableMap) throws ParseException {
ParserUtil.checkType(tokens.consume(), Token.Type.GROUP_BEGIN); ParserUtil.checkType(tokens.consume(), Token.Type.GROUP_BEGIN);
Returnable<?> expression = parseExpression(tokens, true, variableMap); // Parse inside of group as a separate expression Returnable<?> expression = parseExpression(tokens, true, variableMap); // Parse inside of group as a separate expression
ParserUtil.checkType(tokens.consume(), Token.Type.GROUP_END); ParserUtil.checkType(tokens.consume(), Token.Type.GROUP_END);
@ -262,7 +254,7 @@ public class Parser {
} }
private BinaryOperation<?, ?> parseBinaryOperation(Returnable<?> left, Tokenizer tokens, Map<String, Variable<?>> variableMap) throws ParseException { private BinaryOperation<?, ?> parseBinaryOperation(Returnable<?> left, Tokenizer tokens, Map<String, Returnable.ReturnType> variableMap) throws ParseException {
Token binaryOperator = tokens.consume(); Token binaryOperator = tokens.consume();
ParserUtil.checkBinaryOperator(binaryOperator); ParserUtil.checkBinaryOperator(binaryOperator);
@ -316,23 +308,31 @@ public class Parser {
} }
} }
private Variable<?> parseVariableDeclaration(Tokenizer tokens, Returnable.ReturnType type) throws ParseException { private Declaration<?> parseVariableDeclaration(Tokenizer tokens, Map<String, Returnable.ReturnType> variableMap) throws ParseException {
ParserUtil.checkVarType(tokens.get(), type); // Check for type mismatch Token type = tokens.consume();
switch(type) { ParserUtil.checkType(type, Token.Type.STRING_VARIABLE, Token.Type.BOOLEAN_VARIABLE, Token.Type.NUMBER_VARIABLE);
case NUMBER:
return new NumberVariable(0d, tokens.get().getPosition()); Returnable.ReturnType returnType = ParserUtil.getVariableReturnType(type);
case STRING:
return new StringVariable("", tokens.get().getPosition()); ParserUtil.checkVarType(type, returnType); // Check for type mismatch
case BOOLEAN: Token identifier = tokens.consume();
return new BooleanVariable(false, tokens.get().getPosition()); ParserUtil.checkType(identifier, Token.Type.IDENTIFIER);
} if(functions.containsKey(identifier.getContent()) || variableMap.containsKey(identifier.getContent()))
throw new UnsupportedOperationException("Unsupported variable type: " + type); 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, variableMap);
ParserUtil.checkReturnType(value, returnType);
variableMap.put(identifier.getContent(), returnType);
return new Declaration<>(tokens.get().getPosition(), identifier.getContent(), value, returnType);
} }
private Block parseBlock(Tokenizer tokens, Map<String, Variable<?>> superVars, boolean loop) throws ParseException { private Block parseBlock(Tokenizer tokens, Map<String, Returnable.ReturnType> superVars, boolean loop) throws ParseException {
List<Item<?>> parsedItems = new GlueList<>(); List<Item<?>> parsedItems = new GlueList<>();
Map<String, Variable<?>> parsedVariables = new HashMap<>(superVars); // New hashmap as to not mutate parent scope's declarations. Map<String, Returnable.ReturnType> parsedVariables = new HashMap<>(superVars); // New hashmap as to not mutate parent scope's declarations.
Token first = tokens.get(); Token first = tokens.get();
@ -345,7 +345,7 @@ public class Parser {
return new Block(parsedItems, first.getPosition()); return new Block(parsedItems, first.getPosition());
} }
private Item<?> parseItem(Tokenizer tokens, Map<String, Variable<?>> variableMap, boolean loop) throws ParseException { private Item<?> parseItem(Tokenizer tokens, Map<String, Returnable.ReturnType> variableMap, boolean loop) throws ParseException {
Token token = tokens.get(); Token token = tokens.get();
if(loop) ParserUtil.checkType(token, Token.Type.IDENTIFIER, Token.Type.IF_STATEMENT, Token.Type.WHILE_LOOP, Token.Type.FOR_LOOP, 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);
@ -356,23 +356,12 @@ public class Parser {
return parseLoopLike(tokens, variableMap, loop); return parseLoopLike(tokens, variableMap, loop);
} else if(token.isIdentifier()) { // Parse identifiers } else if(token.isIdentifier()) { // Parse identifiers
if(variableMap.containsKey(token.getContent())) { // Assume variable assignment if(variableMap.containsKey(token.getContent())) { // Assume variable assignment
Variable<?> variable = variableMap.get(token.getContent()); return parseAssignment(tokens, variableMap);
return parseAssignment(variable, tokens, variableMap);
} else return parseFunction(tokens, true, variableMap); } else return parseFunction(tokens, true, variableMap);
} else if(token.isVariableDeclaration()) { } else if(token.isVariableDeclaration()) {
Variable<?> temp = parseVariableDeclaration(tokens, ParserUtil.getVariableReturnType(token));
ParserUtil.checkType(tokens.consume(), Token.Type.STRING_VARIABLE, Token.Type.BOOLEAN_VARIABLE, Token.Type.NUMBER_VARIABLE); return parseVariableDeclaration(tokens, variableMap);
Token name = tokens.get();
ParserUtil.checkType(name, Token.Type.IDENTIFIER); // Name must be an identifier.
if(functions.containsKey(name.getContent()) || variableMap.containsKey(name.getContent()))
throw new ParseException(name.getContent() + " is already defined in this scope", name.getPosition());
variableMap.put(name.getContent(), temp);
return parseAssignment(temp, tokens, variableMap);
} else if(token.getType().equals(Token.Type.RETURN)) return new ReturnKeyword(tokens.consume().getPosition()); } 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.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.CONTINUE)) return new ContinueKeyword(tokens.consume().getPosition());
@ -380,21 +369,21 @@ public class Parser {
else throw new UnsupportedOperationException("Unexpected token " + token.getType() + ": " + token.getPosition()); else throw new UnsupportedOperationException("Unexpected token " + token.getType() + ": " + token.getPosition());
} }
private Assignment<?> parseAssignment(Variable<?> variable, Tokenizer tokens, Map<String, Variable<?>> variableMap) throws ParseException { private Assignment<?> parseAssignment(Tokenizer tokens, Map<String, Returnable.ReturnType> variableMap) throws ParseException {
Token name = tokens.get(); Token identifier = tokens.consume();
ParserUtil.checkType(tokens.consume(), Token.Type.IDENTIFIER); ParserUtil.checkType(identifier, Token.Type.IDENTIFIER);
ParserUtil.checkType(tokens.consume(), Token.Type.ASSIGNMENT); ParserUtil.checkType(tokens.consume(), Token.Type.ASSIGNMENT);
Returnable<?> expression = parseExpression(tokens, true, variableMap); Returnable<?> value = parseExpression(tokens, true, variableMap);
ParserUtil.checkReturnType(expression, variable.getType()); ParserUtil.checkReturnType(value, variableMap.get(identifier.getContent()));
return new Assignment<>((Variable<Object>) variable, (Returnable<Object>) expression, name.getPosition()); return new Assignment<>(value, identifier.getContent(), identifier.getPosition());
} }
private Function<?> parseFunction(Tokenizer tokens, boolean fullStatement, Map<String, Variable<?>> variableMap) throws ParseException { private Function<?> parseFunction(Tokenizer tokens, boolean fullStatement, Map<String, Returnable.ReturnType> variableMap) throws ParseException {
Token identifier = tokens.consume(); Token identifier = tokens.consume();
ParserUtil.checkType(identifier, Token.Type.IDENTIFIER); // First token must be identifier ParserUtil.checkType(identifier, Token.Type.IDENTIFIER); // First token must be identifier
@ -428,7 +417,7 @@ public class Parser {
} }
private List<Returnable<?>> getArgs(Tokenizer tokens, Map<String, Variable<?>> variableMap) throws ParseException { private List<Returnable<?>> getArgs(Tokenizer tokens, Map<String, Returnable.ReturnType> variableMap) throws ParseException {
List<Returnable<?>> args = new GlueList<>(); List<Returnable<?>> args = new GlueList<>();
while(!tokens.get().getType().equals(Token.Type.GROUP_END)) { while(!tokens.get().getType().equals(Token.Type.GROUP_END)) {

View File

@ -1,8 +1,11 @@
package com.dfsek.terra.api.structures.parser.lang; package com.dfsek.terra.api.structures.parser.lang;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
public class Block implements Item<Block.ReturnInfo<?>> { public class Block implements Item<Block.ReturnInfo<?>> {
private final List<Item<?>> items; private final List<Item<?>> items;
@ -17,10 +20,15 @@ public class Block implements Item<Block.ReturnInfo<?>> {
return items; return items;
} }
public ReturnInfo<?> apply(ImplementationArguments implementationArguments) {
return apply(implementationArguments, new HashMap<>());
}
@Override @Override
public synchronized ReturnInfo<?> apply(ImplementationArguments implementationArguments) { public ReturnInfo<?> apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
Map<String, Variable<?>> scope = new HashMap<>(variableMap);
for(Item<?> item : items) { for(Item<?> item : items) {
Object result = item.apply(implementationArguments); Object result = item.apply(implementationArguments, scope);
if(result instanceof ReturnInfo) { if(result instanceof ReturnInfo) {
ReturnInfo<?> level = (ReturnInfo<?>) result; ReturnInfo<?> level = (ReturnInfo<?>) result;
if(!level.getLevel().equals(ReturnLevel.NONE)) return level; if(!level.getLevel().equals(ReturnLevel.NONE)) return level;

View File

@ -1,9 +1,12 @@
package com.dfsek.terra.api.structures.parser.lang; package com.dfsek.terra.api.structures.parser.lang;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.Map;
public interface Item<T> { public interface Item<T> {
T apply(ImplementationArguments implementationArguments); T apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap);
Position getPosition(); Position getPosition();
} }

View File

@ -2,8 +2,11 @@ package com.dfsek.terra.api.structures.parser.lang.constants;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.Map;
public abstract class ConstantExpression<T> implements Returnable<T> { public abstract class ConstantExpression<T> implements Returnable<T> {
private final T constant; private final T constant;
private final Position position; private final Position position;
@ -14,7 +17,7 @@ public abstract class ConstantExpression<T> implements Returnable<T> {
} }
@Override @Override
public T apply(ImplementationArguments implementationArguments) { public T apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
return constant; return constant;
} }

View File

@ -1,27 +0,0 @@
package com.dfsek.terra.api.structures.parser.lang.functions.def;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.functions.Function;
import com.dfsek.terra.api.structures.tokenizer.Position;
public abstract class DefinedFunction<T> implements Function<T> {
private final FunctionBlock<T> block;
private final String name;
private final Position position;
protected DefinedFunction(FunctionBlock<T> block, String name, Position position) {
this.block = block;
this.name = name;
this.position = position;
}
@Override
public T apply(ImplementationArguments implementationArguments) {
return block.apply(implementationArguments);
}
@Override
public Position getPosition() {
return position;
}
}

View File

@ -3,9 +3,12 @@ package com.dfsek.terra.api.structures.parser.lang.functions.def;
import com.dfsek.terra.api.structures.parser.lang.Block; import com.dfsek.terra.api.structures.parser.lang.Block;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Item; import com.dfsek.terra.api.structures.parser.lang.Item;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
public class FunctionBlock<T> implements Item<T> { public class FunctionBlock<T> implements Item<T> {
private final List<Item<?>> items; private final List<Item<?>> items;
@ -24,9 +27,10 @@ public class FunctionBlock<T> implements Item<T> {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public synchronized T apply(ImplementationArguments implementationArguments) { public synchronized T apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
Map<String, Variable<?>> scope = new HashMap<>(variableMap);
for(Item<?> item : items) { for(Item<?> item : items) {
Object result = item.apply(implementationArguments); Object result = item.apply(implementationArguments, variableMap);
if(result instanceof Block.ReturnInfo) { if(result instanceof Block.ReturnInfo) {
Block.ReturnInfo<T> level = (Block.ReturnInfo<T>) result; Block.ReturnInfo<T> level = (Block.ReturnInfo<T>) result;
if(level.getLevel().equals(Block.ReturnLevel.RETURN)) return level.getData(); if(level.getLevel().equals(Block.ReturnLevel.RETURN)) return level.getData();

View File

@ -3,8 +3,11 @@ package com.dfsek.terra.api.structures.parser.lang.keywords.flow;
import com.dfsek.terra.api.structures.parser.lang.Block; import com.dfsek.terra.api.structures.parser.lang.Block;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Keyword; import com.dfsek.terra.api.structures.parser.lang.Keyword;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.Map;
public class BreakKeyword implements Keyword<Block.ReturnInfo<?>> { public class BreakKeyword implements Keyword<Block.ReturnInfo<?>> {
private final Position position; private final Position position;
@ -13,7 +16,7 @@ public class BreakKeyword implements Keyword<Block.ReturnInfo<?>> {
} }
@Override @Override
public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments) { public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
return new Block.ReturnInfo<>(Block.ReturnLevel.BREAK, null); return new Block.ReturnInfo<>(Block.ReturnLevel.BREAK, null);
} }

View File

@ -3,8 +3,11 @@ package com.dfsek.terra.api.structures.parser.lang.keywords.flow;
import com.dfsek.terra.api.structures.parser.lang.Block; import com.dfsek.terra.api.structures.parser.lang.Block;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Keyword; import com.dfsek.terra.api.structures.parser.lang.Keyword;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.Map;
public class ContinueKeyword implements Keyword<Block.ReturnInfo<?>> { public class ContinueKeyword implements Keyword<Block.ReturnInfo<?>> {
private final Position position; private final Position position;
@ -13,7 +16,7 @@ public class ContinueKeyword implements Keyword<Block.ReturnInfo<?>> {
} }
@Override @Override
public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments) { public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
return new Block.ReturnInfo<>(Block.ReturnLevel.CONTINUE, null); return new Block.ReturnInfo<>(Block.ReturnLevel.CONTINUE, null);
} }

View File

@ -3,8 +3,11 @@ package com.dfsek.terra.api.structures.parser.lang.keywords.flow;
import com.dfsek.terra.api.structures.parser.lang.Block; import com.dfsek.terra.api.structures.parser.lang.Block;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Keyword; import com.dfsek.terra.api.structures.parser.lang.Keyword;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.Map;
public class FailKeyword implements Keyword<Block.ReturnInfo<?>> { public class FailKeyword implements Keyword<Block.ReturnInfo<?>> {
private final Position position; private final Position position;
@ -13,7 +16,7 @@ public class FailKeyword implements Keyword<Block.ReturnInfo<?>> {
} }
@Override @Override
public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments) { public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
return new Block.ReturnInfo<>(Block.ReturnLevel.FAIL, null); return new Block.ReturnInfo<>(Block.ReturnLevel.FAIL, null);
} }

View File

@ -3,8 +3,11 @@ package com.dfsek.terra.api.structures.parser.lang.keywords.flow;
import com.dfsek.terra.api.structures.parser.lang.Block; import com.dfsek.terra.api.structures.parser.lang.Block;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Keyword; import com.dfsek.terra.api.structures.parser.lang.Keyword;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.Map;
public class ReturnKeyword implements Keyword<Block.ReturnInfo<?>> { public class ReturnKeyword implements Keyword<Block.ReturnInfo<?>> {
private final Position position; private final Position position;
@ -13,7 +16,7 @@ public class ReturnKeyword implements Keyword<Block.ReturnInfo<?>> {
} }
@Override @Override
public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments) { public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
return new Block.ReturnInfo<>(Block.ReturnLevel.RETURN, null); return new Block.ReturnInfo<>(Block.ReturnLevel.RETURN, null);
} }

View File

@ -5,8 +5,11 @@ import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Item; import com.dfsek.terra.api.structures.parser.lang.Item;
import com.dfsek.terra.api.structures.parser.lang.Keyword; import com.dfsek.terra.api.structures.parser.lang.Keyword;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.Map;
public class ForKeyword implements Keyword<Block.ReturnInfo<?>> { public class ForKeyword implements Keyword<Block.ReturnInfo<?>> {
private final Block conditional; private final Block conditional;
private final Item<?> initializer; private final Item<?> initializer;
@ -23,9 +26,9 @@ public class ForKeyword implements Keyword<Block.ReturnInfo<?>> {
} }
@Override @Override
public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments) { public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
for(initializer.apply(implementationArguments); statement.apply(implementationArguments); incrementer.apply(implementationArguments)) { for(initializer.apply(implementationArguments, variableMap); statement.apply(implementationArguments, variableMap); incrementer.apply(implementationArguments, variableMap)) {
Block.ReturnInfo<?> level = conditional.apply(implementationArguments); Block.ReturnInfo<?> level = conditional.apply(implementationArguments, variableMap);
if(level.getLevel().equals(Block.ReturnLevel.BREAK)) break; if(level.getLevel().equals(Block.ReturnLevel.BREAK)) break;
if(level.getLevel().isReturnFast()) return level; if(level.getLevel().isReturnFast()) return level;
} }

View File

@ -4,10 +4,12 @@ import com.dfsek.terra.api.structures.parser.lang.Block;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Keyword; import com.dfsek.terra.api.structures.parser.lang.Keyword;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.List;
import java.util.Map;
public class IfKeyword implements Keyword<Block.ReturnInfo<?>> { public class IfKeyword implements Keyword<Block.ReturnInfo<?>> {
private final Block conditional; private final Block conditional;
@ -25,15 +27,15 @@ public class IfKeyword implements Keyword<Block.ReturnInfo<?>> {
} }
@Override @Override
public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments) { public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
if(statement.apply(implementationArguments)) return conditional.apply(implementationArguments); if(statement.apply(implementationArguments, variableMap)) return conditional.apply(implementationArguments, variableMap);
else { else {
for(Pair<Returnable<Boolean>, Block> pair : elseIf) { for(Pair<Returnable<Boolean>, Block> pair : elseIf) {
if(pair.getLeft().apply(implementationArguments)) { if(pair.getLeft().apply(implementationArguments, variableMap)) {
return pair.getRight().apply(implementationArguments); return pair.getRight().apply(implementationArguments, variableMap);
} }
} }
if(elseBlock != null) return elseBlock.apply(implementationArguments); if(elseBlock != null) return elseBlock.apply(implementationArguments, variableMap);
} }
return new Block.ReturnInfo<>(Block.ReturnLevel.NONE, null); return new Block.ReturnInfo<>(Block.ReturnLevel.NONE, null);
} }

View File

@ -4,8 +4,11 @@ import com.dfsek.terra.api.structures.parser.lang.Block;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Keyword; import com.dfsek.terra.api.structures.parser.lang.Keyword;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.Map;
public class WhileKeyword implements Keyword<Block.ReturnInfo<?>> { public class WhileKeyword implements Keyword<Block.ReturnInfo<?>> {
private final Block conditional; private final Block conditional;
private final Returnable<Boolean> statement; private final Returnable<Boolean> statement;
@ -18,9 +21,9 @@ public class WhileKeyword implements Keyword<Block.ReturnInfo<?>> {
} }
@Override @Override
public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments) { public Block.ReturnInfo<?> apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
while(statement.apply(implementationArguments)) { while(statement.apply(implementationArguments, variableMap)) {
Block.ReturnInfo<?> level = conditional.apply(implementationArguments); Block.ReturnInfo<?> level = conditional.apply(implementationArguments, variableMap);
if(level.getLevel().equals(Block.ReturnLevel.BREAK)) break; if(level.getLevel().equals(Block.ReturnLevel.BREAK)) break;
if(level.getLevel().isReturnFast()) return level; if(level.getLevel().isReturnFast()) return level;
} }

View File

@ -2,8 +2,11 @@ package com.dfsek.terra.api.structures.parser.lang.operations;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.Map;
public abstract class BinaryOperation<I, O> implements Returnable<O> { public abstract class BinaryOperation<I, O> implements Returnable<O> {
private final Returnable<I> left; private final Returnable<I> left;
private final Returnable<I> right; private final Returnable<I> right;
@ -23,7 +26,7 @@ public abstract class BinaryOperation<I, O> implements Returnable<O> {
} }
@Override @Override
public O apply(ImplementationArguments implementationArguments) { public O apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
return apply(left.apply(implementationArguments), right.apply(implementationArguments)); return apply(left.apply(implementationArguments, variableMap), right.apply(implementationArguments, variableMap));
} }
} }

View File

@ -2,8 +2,11 @@ package com.dfsek.terra.api.structures.parser.lang.operations;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.Map;
public abstract class UnaryOperation<T> implements Returnable<T> { public abstract class UnaryOperation<T> implements Returnable<T> {
private final Returnable<T> input; private final Returnable<T> input;
private final Position position; private final Position position;
@ -16,8 +19,8 @@ public abstract class UnaryOperation<T> implements Returnable<T> {
public abstract T apply(T input); public abstract T apply(T input);
@Override @Override
public T apply(ImplementationArguments implementationArguments) { public T apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
return apply(input.apply(implementationArguments)); return apply(input.apply(implementationArguments, variableMap));
} }
@Override @Override

View File

@ -5,21 +5,24 @@ import com.dfsek.terra.api.structures.parser.lang.Item;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.Map;
public class Assignment<T> implements Item<T> { public class Assignment<T> implements Item<T> {
private final Variable<T> delegate;
private final Returnable<T> value; private final Returnable<T> value;
private final Position position; private final Position position;
private final String identifier;
public Assignment(Variable<T> delegate, Returnable<T> value, Position position) { public Assignment(Returnable<T> value, String identifier, Position position) {
this.delegate = delegate;
this.value = value; this.value = value;
this.identifier = identifier;
this.position = position; this.position = position;
} }
@SuppressWarnings("unchecked")
@Override @Override
public synchronized T apply(ImplementationArguments implementationArguments) { public synchronized T apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
T val = value.apply(implementationArguments); T val = value.apply(implementationArguments, variableMap);
delegate.setValue(val); ((Variable<T>) variableMap.get(identifier)).setValue(val);
return val; return val;
} }

View File

@ -0,0 +1,60 @@
package com.dfsek.terra.api.structures.parser.lang.variables;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Item;
import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.Map;
public class Declaration<T> implements Item<T> {
private final Position position;
private final String identifier;
private final Returnable<T> value;
private final Returnable.ReturnType type;
public Declaration(Position position, String identifier, Returnable<T> value, Returnable.ReturnType type) {
switch(type) {
case STRING:
case BOOLEAN:
case NUMBER:
break;
default:
throw new IllegalArgumentException("Invalid variable type: " + type);
}
this.position = position;
this.identifier = identifier;
this.value = value;
this.type = type;
}
@Override
public T apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
T result = value.apply(implementationArguments, variableMap);
switch(type) {
case NUMBER:
variableMap.put(identifier, new NumberVariable((Number) result, position));
break;
case BOOLEAN:
variableMap.put(identifier, new BooleanVariable((Boolean) result, position));
break;
case STRING:
variableMap.put(identifier, new StringVariable((String) result, position));
break;
}
return result;
}
@Override
public Position getPosition() {
return position;
}
public Returnable.ReturnType getType() {
return type;
}
public String getIdentifier() {
return identifier;
}
}

View File

@ -4,25 +4,31 @@ import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
public class Getter implements Returnable<Object> { import java.util.Map;
private final Variable<?> delegate;
public Getter(Variable<?> delegate) { public class Getter implements Returnable<Object> {
this.delegate = delegate; private final String identifier;
private final Position position;
private final ReturnType type;
public Getter(String identifier, Position position, ReturnType type) {
this.identifier = identifier;
this.position = position;
this.type = type;
} }
@Override @Override
public ReturnType returnType() { public ReturnType returnType() {
return delegate.getType(); return type;
} }
@Override @Override
public synchronized Object apply(ImplementationArguments implementationArguments) { public synchronized Object apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
return delegate.getValue(); return variableMap.get(identifier).getValue();
} }
@Override @Override
public Position getPosition() { public Position getPosition() {
return delegate.getPosition(); return position;
} }
} }

View File

@ -4,9 +4,11 @@ import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.Function; 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.functions.FunctionBuilder;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.function.BiFunction; import java.util.function.BiFunction;
public class BinaryNumberFunctionBuilder implements FunctionBuilder<Function<Number>> { public class BinaryNumberFunctionBuilder implements FunctionBuilder<Function<Number>> {
@ -27,8 +29,8 @@ public class BinaryNumberFunctionBuilder implements FunctionBuilder<Function<Num
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public Number apply(ImplementationArguments implementationArguments) { public Number apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
return function.apply(((Returnable<Number>) argumentList.get(0)).apply(implementationArguments), ((Returnable<Number>) argumentList.get(1)).apply(implementationArguments)); return function.apply(((Returnable<Number>) argumentList.get(0)).apply(implementationArguments, variableMap), ((Returnable<Number>) argumentList.get(1)).apply(implementationArguments, variableMap));
} }
@Override @Override

View File

@ -4,9 +4,11 @@ import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.Function; 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.functions.FunctionBuilder;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.List; import java.util.List;
import java.util.Map;
public class UnaryNumberFunctionBuilder implements FunctionBuilder<Function<Number>> { public class UnaryNumberFunctionBuilder implements FunctionBuilder<Function<Number>> {
@ -26,8 +28,8 @@ public class UnaryNumberFunctionBuilder implements FunctionBuilder<Function<Numb
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public Number apply(ImplementationArguments implementationArguments) { public Number apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
return function.apply(((Returnable<Number>) argumentList.get(0)).apply(implementationArguments)); return function.apply(((Returnable<Number>) argumentList.get(0)).apply(implementationArguments, variableMap));
} }
@Override @Override

View File

@ -4,9 +4,11 @@ import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.Function; 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.functions.FunctionBuilder;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.List; import java.util.List;
import java.util.Map;
public class UnaryStringFunctionBuilder implements FunctionBuilder<Function<Void>> { public class UnaryStringFunctionBuilder implements FunctionBuilder<Function<Void>> {
@ -26,8 +28,8 @@ public class UnaryStringFunctionBuilder implements FunctionBuilder<Function<Void
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public Void apply(ImplementationArguments implementationArguments) { public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
function.accept(((Returnable<String>) argumentList.get(0)).apply(implementationArguments)); function.accept(((Returnable<String>) argumentList.get(0)).apply(implementationArguments, variableMap));
return null; return null;
} }

View File

@ -4,10 +4,12 @@ import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.Function; 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.functions.FunctionBuilder;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.script.TerraImplementationArguments; import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.List; import java.util.List;
import java.util.Map;
public class ZeroArgFunctionBuilder<T> implements FunctionBuilder<Function<T>> { public class ZeroArgFunctionBuilder<T> implements FunctionBuilder<Function<T>> {
private final java.util.function.Function<TerraImplementationArguments, T> function; private final java.util.function.Function<TerraImplementationArguments, T> function;
@ -27,7 +29,7 @@ public class ZeroArgFunctionBuilder<T> implements FunctionBuilder<Function<T>> {
} }
@Override @Override
public T apply(ImplementationArguments implementationArguments) { public T apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
return function.apply((TerraImplementationArguments) implementationArguments); return function.apply((TerraImplementationArguments) implementationArguments);
} }

View File

@ -6,6 +6,7 @@ import com.dfsek.terra.api.platform.TerraPlugin;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.Function; import com.dfsek.terra.api.structures.parser.lang.functions.Function;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.script.TerraImplementationArguments; import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
import com.dfsek.terra.api.structures.structure.RotationUtil; import com.dfsek.terra.api.structures.structure.RotationUtil;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
@ -13,6 +14,8 @@ import com.dfsek.terra.biome.BiomeProvider;
import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.biome.UserDefinedBiome;
import net.jafama.FastMath; import net.jafama.FastMath;
import java.util.Map;
public class BiomeFunction implements Function<String> { public class BiomeFunction implements Function<String> {
private final TerraPlugin main; private final TerraPlugin main;
private final Returnable<Number> x, y, z; private final Returnable<Number> x, y, z;
@ -29,16 +32,16 @@ public class BiomeFunction implements Function<String> {
@Override @Override
public String apply(ImplementationArguments implementationArguments) { public String apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments; TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = new Vector2(x.apply(implementationArguments).doubleValue(), z.apply(implementationArguments).doubleValue()); Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation()); RotationUtil.rotateVector(xz, arguments.getRotation());
BiomeProvider grid = main.getWorld(arguments.getBuffer().getOrigin().getWorld()).getBiomeProvider(); BiomeProvider grid = main.getWorld(arguments.getBuffer().getOrigin().getWorld()).getBiomeProvider();
return ((UserDefinedBiome) grid.getBiome(arguments.getBuffer().getOrigin().clone().add(new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments).intValue(), FastMath.roundToInt(xz.getZ()))))).getID(); return ((UserDefinedBiome) grid.getBiome(arguments.getBuffer().getOrigin().clone().add(new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), FastMath.roundToInt(xz.getZ()))))).getID();
} }

View File

@ -9,12 +9,15 @@ import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.constants.ConstantExpression; import com.dfsek.terra.api.structures.parser.lang.constants.ConstantExpression;
import com.dfsek.terra.api.structures.parser.lang.functions.Function; import com.dfsek.terra.api.structures.parser.lang.functions.Function;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.script.TerraImplementationArguments; import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
import com.dfsek.terra.api.structures.structure.RotationUtil; import com.dfsek.terra.api.structures.structure.RotationUtil;
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedBlock; import com.dfsek.terra.api.structures.structure.buffer.items.BufferedBlock;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import net.jafama.FastMath; import net.jafama.FastMath;
import java.util.Map;
public class BlockFunction implements Function<Void> { public class BlockFunction implements Function<Void> {
private final BlockData data; private final BlockData data;
private final Returnable<Number> x, y, z; private final Returnable<Number> x, y, z;
@ -37,16 +40,16 @@ public class BlockFunction implements Function<Void> {
} }
@Override @Override
public Void apply(ImplementationArguments implementationArguments) { public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments; TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
BlockData rot = data.clone(); BlockData rot = data.clone();
Vector2 xz = new Vector2(x.apply(implementationArguments).doubleValue(), z.apply(implementationArguments).doubleValue()); Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation()); RotationUtil.rotateVector(xz, arguments.getRotation());
RotationUtil.rotateBlockData(rot, arguments.getRotation().inverse()); RotationUtil.rotateBlockData(rot, arguments.getRotation().inverse());
arguments.getBuffer().addItem(new BufferedBlock(rot, overwrite.apply(implementationArguments)), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments).doubleValue(), FastMath.roundToInt(xz.getZ())).toLocation(arguments.getBuffer().getOrigin().getWorld())); arguments.getBuffer().addItem(new BufferedBlock(rot, overwrite.apply(implementationArguments, variableMap)), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).doubleValue(), FastMath.roundToInt(xz.getZ())).toLocation(arguments.getBuffer().getOrigin().getWorld()));
return null; return null;
} }

View File

@ -5,11 +5,14 @@ import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.Function; import com.dfsek.terra.api.structures.parser.lang.functions.Function;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.script.TerraImplementationArguments; import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
import com.dfsek.terra.api.structures.structure.RotationUtil; import com.dfsek.terra.api.structures.structure.RotationUtil;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import net.jafama.FastMath; import net.jafama.FastMath;
import java.util.Map;
public class CheckBlockFunction implements Function<String> { public class CheckBlockFunction implements Function<String> {
private final Returnable<Number> x, y, z; private final Returnable<Number> x, y, z;
private final Position position; private final Position position;
@ -23,14 +26,14 @@ public class CheckBlockFunction implements Function<String> {
@Override @Override
public String apply(ImplementationArguments implementationArguments) { public String apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments; TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = new Vector2(x.apply(implementationArguments).doubleValue(), z.apply(implementationArguments).doubleValue()); Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation()); RotationUtil.rotateVector(xz, arguments.getRotation());
String data = arguments.getBuffer().getOrigin().clone().add(new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments).doubleValue(), FastMath.roundToInt(xz.getZ()))).getBlock().getBlockData().getAsString(); String data = arguments.getBuffer().getOrigin().clone().add(new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).doubleValue(), FastMath.roundToInt(xz.getZ()))).getBlock().getBlockData().getAsString();
if(data.contains("[")) return data.substring(0, data.indexOf('[')); // Strip properties if(data.contains("[")) return data.substring(0, data.indexOf('[')); // Strip properties
else return data; else return data;
} }

View File

@ -9,6 +9,7 @@ import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.Function; import com.dfsek.terra.api.structures.parser.lang.functions.Function;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.script.TerraImplementationArguments; import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
import com.dfsek.terra.api.structures.structure.RotationUtil; import com.dfsek.terra.api.structures.structure.RotationUtil;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
@ -18,6 +19,8 @@ import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.generation.math.SamplerCache; import com.dfsek.terra.generation.math.SamplerCache;
import net.jafama.FastMath; import net.jafama.FastMath;
import java.util.Map;
public class CheckFunction implements Function<String> { public class CheckFunction implements Function<String> {
private final TerraPlugin main; private final TerraPlugin main;
private final Returnable<Number> x, y, z; private final Returnable<Number> x, y, z;
@ -35,14 +38,14 @@ public class CheckFunction implements Function<String> {
@Override @Override
public String apply(ImplementationArguments implementationArguments) { public String apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments; TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = new Vector2(x.apply(implementationArguments).doubleValue(), z.apply(implementationArguments).doubleValue()); Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation()); RotationUtil.rotateVector(xz, arguments.getRotation());
Location location = arguments.getBuffer().getOrigin().clone().add(new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments).doubleValue(), FastMath.roundToInt(xz.getZ()))); Location location = arguments.getBuffer().getOrigin().clone().add(new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).doubleValue(), FastMath.roundToInt(xz.getZ())));
return apply(location, arguments.getBuffer().getOrigin().getWorld()); return apply(location, arguments.getBuffer().getOrigin().getWorld());
} }

View File

@ -9,11 +9,14 @@ import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.constants.ConstantExpression; import com.dfsek.terra.api.structures.parser.lang.constants.ConstantExpression;
import com.dfsek.terra.api.structures.parser.lang.functions.Function; import com.dfsek.terra.api.structures.parser.lang.functions.Function;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.script.TerraImplementationArguments; import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
import com.dfsek.terra.api.structures.structure.RotationUtil; import com.dfsek.terra.api.structures.structure.RotationUtil;
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedEntity; import com.dfsek.terra.api.structures.structure.buffer.items.BufferedEntity;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.Map;
public class EntityFunction implements Function<Void> { public class EntityFunction implements Function<Void> {
private final EntityType data; private final EntityType data;
private final Returnable<Number> x, y, z; private final Returnable<Number> x, y, z;
@ -30,13 +33,13 @@ public class EntityFunction implements Function<Void> {
} }
@Override @Override
public Void apply(ImplementationArguments implementationArguments) { public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments; TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = new Vector2(x.apply(implementationArguments).doubleValue(), z.apply(implementationArguments).doubleValue()); Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation()); RotationUtil.rotateVector(xz, arguments.getRotation());
arguments.getBuffer().addItem(new BufferedEntity(data), new Vector3(xz.getX(), y.apply(implementationArguments).doubleValue(), xz.getZ()).toLocation(arguments.getBuffer().getOrigin().getWorld())); arguments.getBuffer().addItem(new BufferedEntity(data), new Vector3(xz.getX(), y.apply(implementationArguments, variableMap).doubleValue(), xz.getZ()).toLocation(arguments.getBuffer().getOrigin().getWorld()));
return null; return null;
} }

View File

@ -5,11 +5,14 @@ import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.Function; import com.dfsek.terra.api.structures.parser.lang.functions.Function;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.script.TerraImplementationArguments; import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
import com.dfsek.terra.api.structures.structure.RotationUtil; import com.dfsek.terra.api.structures.structure.RotationUtil;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import net.jafama.FastMath; import net.jafama.FastMath;
import java.util.Map;
public class GetMarkFunction implements Function<String> { public class GetMarkFunction implements Function<String> {
private final Returnable<Number> x, y, z; private final Returnable<Number> x, y, z;
private final Position position; private final Position position;
@ -22,12 +25,12 @@ public class GetMarkFunction implements Function<String> {
} }
@Override @Override
public String apply(ImplementationArguments implementationArguments) { public String apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments; TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = new Vector2(x.apply(implementationArguments).doubleValue(), z.apply(implementationArguments).doubleValue()); Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation()); RotationUtil.rotateVector(xz, arguments.getRotation());
String mark = arguments.getBuffer().getMark(new Vector3(FastMath.floorToInt(xz.getX()), FastMath.floorToInt(y.apply(implementationArguments).doubleValue()), FastMath.floorToInt(xz.getZ())).toLocation(arguments.getBuffer().getOrigin().getWorld())); String mark = arguments.getBuffer().getMark(new Vector3(FastMath.floorToInt(xz.getX()), FastMath.floorToInt(y.apply(implementationArguments, variableMap).doubleValue()), FastMath.floorToInt(xz.getZ())).toLocation(arguments.getBuffer().getOrigin().getWorld()));
return mark == null ? "" : mark; return mark == null ? "" : mark;
} }

View File

@ -7,6 +7,7 @@ import com.dfsek.terra.api.structures.loot.LootTable;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.Function; import com.dfsek.terra.api.structures.parser.lang.functions.Function;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.script.TerraImplementationArguments; import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
import com.dfsek.terra.api.structures.structure.RotationUtil; import com.dfsek.terra.api.structures.structure.RotationUtil;
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedLootApplication; import com.dfsek.terra.api.structures.structure.buffer.items.BufferedLootApplication;
@ -14,6 +15,8 @@ import com.dfsek.terra.api.structures.tokenizer.Position;
import com.dfsek.terra.registry.LootRegistry; import com.dfsek.terra.registry.LootRegistry;
import net.jafama.FastMath; import net.jafama.FastMath;
import java.util.Map;
public class LootFunction implements Function<Void> { public class LootFunction implements Function<Void> {
private final LootRegistry registry; private final LootRegistry registry;
private final Returnable<String> data; private final Returnable<String> data;
@ -32,13 +35,13 @@ public class LootFunction implements Function<Void> {
} }
@Override @Override
public Void apply(ImplementationArguments implementationArguments) { public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments; TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = new Vector2(x.apply(implementationArguments).doubleValue(), z.apply(implementationArguments).doubleValue()); Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation()); RotationUtil.rotateVector(xz, arguments.getRotation());
String id = data.apply(implementationArguments); String id = data.apply(implementationArguments, variableMap);
LootTable table = registry.get(id); LootTable table = registry.get(id);
if(table == null) { if(table == null) {
@ -46,7 +49,7 @@ public class LootFunction implements Function<Void> {
return null; return null;
} }
arguments.getBuffer().addItem(new BufferedLootApplication(table, main), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments).intValue(), FastMath.roundToInt(xz.getZ())).toLocation(arguments.getBuffer().getOrigin().getWorld())); arguments.getBuffer().addItem(new BufferedLootApplication(table, main), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), FastMath.roundToInt(xz.getZ())).toLocation(arguments.getBuffer().getOrigin().getWorld()));
return null; return null;
} }

View File

@ -9,12 +9,15 @@ import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.constants.ConstantExpression; import com.dfsek.terra.api.structures.parser.lang.constants.ConstantExpression;
import com.dfsek.terra.api.structures.parser.lang.functions.Function; import com.dfsek.terra.api.structures.parser.lang.functions.Function;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.script.TerraImplementationArguments; import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
import com.dfsek.terra.api.structures.structure.RotationUtil; import com.dfsek.terra.api.structures.structure.RotationUtil;
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedPulledBlock; import com.dfsek.terra.api.structures.structure.buffer.items.BufferedPulledBlock;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import net.jafama.FastMath; import net.jafama.FastMath;
import java.util.Map;
public class PullFunction implements Function<Void> { public class PullFunction implements Function<Void> {
private final BlockData data; private final BlockData data;
private final Returnable<Number> x, y, z; private final Returnable<Number> x, y, z;
@ -31,14 +34,14 @@ public class PullFunction implements Function<Void> {
} }
@Override @Override
public Void apply(ImplementationArguments implementationArguments) { public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments; TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = new Vector2(x.apply(implementationArguments).doubleValue(), z.apply(implementationArguments).doubleValue()); Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation()); RotationUtil.rotateVector(xz, arguments.getRotation());
BlockData rot = data.clone(); BlockData rot = data.clone();
RotationUtil.rotateBlockData(rot, arguments.getRotation().inverse()); RotationUtil.rotateBlockData(rot, arguments.getRotation().inverse());
arguments.getBuffer().addItem(new BufferedPulledBlock(rot), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments).intValue(), FastMath.roundToInt(xz.getZ())).toLocation(arguments.getBuffer().getOrigin().getWorld())); arguments.getBuffer().addItem(new BufferedPulledBlock(rot), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), FastMath.roundToInt(xz.getZ())).toLocation(arguments.getBuffer().getOrigin().getWorld()));
return null; return null;
} }

View File

@ -3,9 +3,12 @@ package com.dfsek.terra.api.structures.script.functions;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.Function; import com.dfsek.terra.api.structures.parser.lang.functions.Function;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.script.TerraImplementationArguments; import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.Map;
public class RandomFunction implements Function<Integer> { public class RandomFunction implements Function<Integer> {
private final Returnable<Number> numberReturnable; private final Returnable<Number> numberReturnable;
private final Position position; private final Position position;
@ -22,8 +25,8 @@ public class RandomFunction implements Function<Integer> {
} }
@Override @Override
public Integer apply(ImplementationArguments implementationArguments) { public Integer apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
return ((TerraImplementationArguments) implementationArguments).getRandom().nextInt(numberReturnable.apply(implementationArguments).intValue()); return ((TerraImplementationArguments) implementationArguments).getRandom().nextInt(numberReturnable.apply(implementationArguments, variableMap).intValue());
} }
@Override @Override

View File

@ -2,9 +2,12 @@ package com.dfsek.terra.api.structures.script.functions;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.functions.Function; import com.dfsek.terra.api.structures.parser.lang.functions.Function;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.script.TerraImplementationArguments; import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import java.util.Map;
public class RecursionsFunction implements Function<Number> { public class RecursionsFunction implements Function<Number> {
private final Position position; private final Position position;
@ -18,7 +21,7 @@ public class RecursionsFunction implements Function<Number> {
} }
@Override @Override
public Number apply(ImplementationArguments implementationArguments) { public Number apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
return ((TerraImplementationArguments) implementationArguments).getRecursions(); return ((TerraImplementationArguments) implementationArguments).getRecursions();
} }

View File

@ -5,11 +5,14 @@ import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.Function; import com.dfsek.terra.api.structures.parser.lang.functions.Function;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.script.TerraImplementationArguments; import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
import com.dfsek.terra.api.structures.structure.RotationUtil; import com.dfsek.terra.api.structures.structure.RotationUtil;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import net.jafama.FastMath; import net.jafama.FastMath;
import java.util.Map;
public class SetMarkFunction implements Function<Void> { public class SetMarkFunction implements Function<Void> {
private final Returnable<Number> x, y, z; private final Returnable<Number> x, y, z;
private final Position position; private final Position position;
@ -24,13 +27,13 @@ public class SetMarkFunction implements Function<Void> {
} }
@Override @Override
public Void apply(ImplementationArguments implementationArguments) { public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments; TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = new Vector2(x.apply(implementationArguments).doubleValue(), z.apply(implementationArguments).doubleValue()); Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation()); RotationUtil.rotateVector(xz, arguments.getRotation());
arguments.getBuffer().setMark(mark.apply(implementationArguments), new Vector3(FastMath.floorToInt(xz.getX()), FastMath.floorToInt(y.apply(implementationArguments).doubleValue()), FastMath.floorToInt(xz.getZ())).toLocation(arguments.getBuffer().getOrigin().getWorld())); arguments.getBuffer().setMark(mark.apply(implementationArguments, variableMap), new Vector3(FastMath.floorToInt(xz.getX()), FastMath.floorToInt(y.apply(implementationArguments, variableMap).doubleValue()), FastMath.floorToInt(xz.getZ())).toLocation(arguments.getBuffer().getOrigin().getWorld()));
return null; return null;
} }

View File

@ -6,12 +6,15 @@ import com.dfsek.terra.api.platform.TerraPlugin;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.Function; import com.dfsek.terra.api.structures.parser.lang.functions.Function;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.script.TerraImplementationArguments; import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
import com.dfsek.terra.api.structures.structure.RotationUtil; import com.dfsek.terra.api.structures.structure.RotationUtil;
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedStateManipulator; import com.dfsek.terra.api.structures.structure.buffer.items.BufferedStateManipulator;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import net.jafama.FastMath; import net.jafama.FastMath;
import java.util.Map;
public class StateFunction implements Function<Void> { public class StateFunction implements Function<Void> {
private final Returnable<String> data; private final Returnable<String> data;
private final Returnable<Number> x, y, z; private final Returnable<Number> x, y, z;
@ -28,12 +31,12 @@ public class StateFunction implements Function<Void> {
} }
@Override @Override
public Void apply(ImplementationArguments implementationArguments) { public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments; TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = new Vector2(x.apply(implementationArguments).doubleValue(), z.apply(implementationArguments).doubleValue()); Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation()); RotationUtil.rotateVector(xz, arguments.getRotation());
arguments.getBuffer().addItem(new BufferedStateManipulator(main, data.apply(implementationArguments)), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments).intValue(), FastMath.roundToInt(xz.getZ())).toLocation(arguments.getBuffer().getOrigin().getWorld())); arguments.getBuffer().addItem(new BufferedStateManipulator(main, data.apply(implementationArguments, variableMap)), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), FastMath.roundToInt(xz.getZ())).toLocation(arguments.getBuffer().getOrigin().getWorld()));
return null; return null;
} }

View File

@ -6,6 +6,7 @@ import com.dfsek.terra.api.platform.TerraPlugin;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.Function; import com.dfsek.terra.api.structures.parser.lang.functions.Function;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.script.StructureScript; import com.dfsek.terra.api.structures.script.StructureScript;
import com.dfsek.terra.api.structures.script.TerraImplementationArguments; import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
import com.dfsek.terra.api.structures.structure.Rotation; import com.dfsek.terra.api.structures.structure.Rotation;
@ -16,6 +17,7 @@ import com.dfsek.terra.registry.ScriptRegistry;
import net.jafama.FastMath; import net.jafama.FastMath;
import java.util.List; import java.util.List;
import java.util.Map;
public class StructureFunction implements Function<Boolean> { public class StructureFunction implements Function<Boolean> {
private final ScriptRegistry registry; private final ScriptRegistry registry;
@ -42,17 +44,17 @@ public class StructureFunction implements Function<Boolean> {
} }
@Override @Override
public Boolean apply(ImplementationArguments implementationArguments) { public Boolean apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments; TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
if(arguments.getRecursions() > main.getTerraConfig().getMaxRecursion()) if(arguments.getRecursions() > main.getTerraConfig().getMaxRecursion())
throw new RuntimeException("Structure recursion too deep: " + arguments.getRecursions()); throw new RuntimeException("Structure recursion too deep: " + arguments.getRecursions());
Vector2 xz = new Vector2(x.apply(implementationArguments).doubleValue(), z.apply(implementationArguments).doubleValue()); Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation()); RotationUtil.rotateVector(xz, arguments.getRotation());
String app = id.apply(implementationArguments); String app = id.apply(implementationArguments, variableMap);
StructureScript script = registry.get(app); StructureScript script = registry.get(app);
if(script == null) { if(script == null) {
main.getLogger().severe("No such structure " + app); main.getLogger().severe("No such structure " + app);
@ -60,7 +62,7 @@ public class StructureFunction implements Function<Boolean> {
} }
Rotation rotation1; Rotation rotation1;
String rotString = rotations.get(arguments.getRandom().nextInt(rotations.size())).apply(implementationArguments); String rotString = rotations.get(arguments.getRandom().nextInt(rotations.size())).apply(implementationArguments, variableMap);
try { try {
rotation1 = Rotation.valueOf(rotString); rotation1 = Rotation.valueOf(rotString);
} catch(IllegalArgumentException e) { } catch(IllegalArgumentException e) {
@ -68,7 +70,7 @@ public class StructureFunction implements Function<Boolean> {
return null; return null;
} }
Vector3 offset = new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments).doubleValue(), FastMath.roundToInt(xz.getZ())); Vector3 offset = new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).doubleValue(), FastMath.roundToInt(xz.getZ()));
return script.executeInBuffer(new IntermediateBuffer(arguments.getBuffer(), offset), arguments.getRandom(), arguments.getRotation().rotate(rotation1), arguments.getRecursions() + 1); return script.executeInBuffer(new IntermediateBuffer(arguments.getBuffer(), offset), arguments.getRandom(), arguments.getRotation().rotate(rotation1), arguments.getRecursions() + 1);
} }

View File

@ -7,12 +7,15 @@ import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.Function; 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.functions.FunctionBuilder;
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
public class ParserTest { public class ParserTest {
@Test @Test
@ -49,9 +52,9 @@ public class ParserTest {
long t = System.nanoTime() - l; long t = System.nanoTime() - l;
System.out.println("Took " + (double) t / 1000000); System.out.println("Took " + (double) t / 1000000);
block.apply(null); block.apply(null, new HashMap<>());
block.apply(null); block.apply(null, new HashMap<>());
} }
private static class Test1 implements Function<Void> { private static class Test1 implements Function<Void> {
@ -66,8 +69,8 @@ public class ParserTest {
} }
@Override @Override
public Void apply(ImplementationArguments implementationArguments) { public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
System.out.println("string: " + a.apply(implementationArguments) + ", double: " + b.apply(implementationArguments)); System.out.println("string: " + a.apply(implementationArguments, variableMap) + ", double: " + b.apply(implementationArguments, variableMap));
return null; return null;
} }

View File

@ -18,6 +18,7 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
public class SpawnCommand extends WorldCommand implements DebugCommand { public class SpawnCommand extends WorldCommand implements DebugCommand {
@ -35,7 +36,7 @@ public class SpawnCommand extends WorldCommand implements DebugCommand {
com.dfsek.terra.api.platform.world.World w = BukkitAdapter.adapt(world); com.dfsek.terra.api.platform.world.World w = BukkitAdapter.adapt(world);
String check = new CheckFunction(getMain(), new NumericConstant(0, dummy), new NumericConstant(0, dummy), new NumericConstant(0, dummy), getMain().getWorld(w).getConfig().getSamplerCache(), dummy).apply(new TerraImplementationArguments(new StructureBuffer( String check = new CheckFunction(getMain(), new NumericConstant(0, dummy), new NumericConstant(0, dummy), new NumericConstant(0, dummy), getMain().getWorld(w).getConfig().getSamplerCache(), dummy).apply(new TerraImplementationArguments(new StructureBuffer(
new com.dfsek.terra.api.math.vector.Location(w, x, y, z) new com.dfsek.terra.api.math.vector.Location(w, x, y, z)
), Rotation.NONE, new FastRandom(), 0)); ), Rotation.NONE, new FastRandom(), 0), new HashMap<>());
sender.sendMessage("Found: " + check); sender.sendMessage("Found: " + check);
return true; return true;

View File

@ -56,6 +56,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
@ -202,7 +203,7 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
DefaultBiomeFeatures.addFarmAnimals(spawnSettings); DefaultBiomeFeatures.addFarmAnimals(spawnSettings);
DefaultBiomeFeatures.addMonsters(spawnSettings, 95, 5, 100); DefaultBiomeFeatures.addMonsters(spawnSettings, 95, 5, 100);
Biome vanilla = ((FabricBiome) biome.getVanillaBiome()).getHandle(); Biome vanilla = ((FabricBiome) new ArrayList<>(biome.getVanillaBiomes().getContents()).get(0)).getHandle();
GenerationSettings.Builder generationSettings = new GenerationSettings.Builder(); GenerationSettings.Builder generationSettings = new GenerationSettings.Builder();
generationSettings.surfaceBuilder(SurfaceBuilder.DEFAULT.withConfig(new TernarySurfaceConfig(Blocks.GRASS_BLOCK.getDefaultState(), Blocks.DIRT.getDefaultState(), Blocks.GRAVEL.getDefaultState()))); // It needs a surfacebuilder, even though we dont use it. generationSettings.surfaceBuilder(SurfaceBuilder.DEFAULT.withConfig(new TernarySurfaceConfig(Blocks.GRASS_BLOCK.getDefaultState(), Blocks.DIRT.getDefaultState(), Blocks.GRAVEL.getDefaultState()))); // It needs a surfacebuilder, even though we dont use it.