mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-04-03 06:16:10 +00:00
allow data to be returned
This commit is contained in:
@@ -14,10 +14,10 @@ import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.parser.lang.functions.builtin.AbsFunction;
|
||||
import com.dfsek.terra.api.structures.parser.lang.functions.builtin.PowFunction;
|
||||
import com.dfsek.terra.api.structures.parser.lang.functions.builtin.SqrtFunction;
|
||||
import com.dfsek.terra.api.structures.parser.lang.keywords.BreakKeyword;
|
||||
import com.dfsek.terra.api.structures.parser.lang.keywords.ContinueKeyword;
|
||||
import com.dfsek.terra.api.structures.parser.lang.keywords.FailKeyword;
|
||||
import com.dfsek.terra.api.structures.parser.lang.keywords.ReturnKeyword;
|
||||
import com.dfsek.terra.api.structures.parser.lang.keywords.flow.BreakKeyword;
|
||||
import com.dfsek.terra.api.structures.parser.lang.keywords.flow.ContinueKeyword;
|
||||
import com.dfsek.terra.api.structures.parser.lang.keywords.flow.FailKeyword;
|
||||
import com.dfsek.terra.api.structures.parser.lang.keywords.flow.ReturnKeyword;
|
||||
import com.dfsek.terra.api.structures.parser.lang.keywords.looplike.ForKeyword;
|
||||
import com.dfsek.terra.api.structures.parser.lang.keywords.looplike.IfKeyword;
|
||||
import com.dfsek.terra.api.structures.parser.lang.keywords.looplike.WhileKeyword;
|
||||
@@ -188,7 +188,7 @@ public class Parser {
|
||||
}
|
||||
|
||||
private ForKeyword parseForLoop(TokenHolder tokens, Map<String, Variable<?>> old, Position start) throws ParseException {
|
||||
Map<String, Variable<?>> variableMap = new HashMap<>(old);
|
||||
Map<String, Variable<?>> variableMap = new HashMap<>(old); // New scope
|
||||
Token f = tokens.get();
|
||||
ParserUtil.checkType(f, Token.Type.NUMBER_VARIABLE, Token.Type.STRING_VARIABLE, Token.Type.BOOLEAN_VARIABLE, Token.Type.IDENTIFIER);
|
||||
Item<?> initializer;
|
||||
|
||||
@@ -13,6 +13,7 @@ public class ParserUtil {
|
||||
|
||||
private static final Map<Token.Type, List<Token.Type>> PRECEDENCE = new HashMap<>();
|
||||
private static final List<Token.Type> ARITHMETIC = Arrays.asList(Token.Type.ADDITION_OPERATOR, Token.Type.SUBTRACTION_OPERATOR, Token.Type.MULTIPLICATION_OPERATOR, Token.Type.DIVISION_OPERATOR);
|
||||
private static final List<Token.Type> COMPARISON = Arrays.asList(Token.Type.EQUALS_OPERATOR, Token.Type.NOT_EQUALS_OPERATOR, Token.Type.LESS_THAN_OPERATOR, Token.Type.LESS_THAN_OR_EQUALS_OPERATOR, Token.Type.GREATER_THAN_OPERATOR, Token.Type.GREATER_THAN_OR_EQUALS_OPERATOR);
|
||||
|
||||
static { // Setup precedence
|
||||
PRECEDENCE.put(Token.Type.ADDITION_OPERATOR, Arrays.asList(Token.Type.MULTIPLICATION_OPERATOR, Token.Type.DIVISION_OPERATOR));
|
||||
@@ -23,6 +24,8 @@ public class ParserUtil {
|
||||
PRECEDENCE.put(Token.Type.GREATER_THAN_OR_EQUALS_OPERATOR, ARITHMETIC);
|
||||
PRECEDENCE.put(Token.Type.LESS_THAN_OPERATOR, ARITHMETIC);
|
||||
PRECEDENCE.put(Token.Type.LESS_THAN_OR_EQUALS_OPERATOR, ARITHMETIC);
|
||||
PRECEDENCE.put(Token.Type.BOOLEAN_AND, COMPARISON);
|
||||
PRECEDENCE.put(Token.Type.BOOLEAN_OR, COMPARISON);
|
||||
}
|
||||
|
||||
public static void checkType(Token token, Token.Type... expected) throws ParseException {
|
||||
|
||||
@@ -7,7 +7,7 @@ import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class Block implements Item<Block.ReturnLevel> {
|
||||
public class Block implements Item<Block.ReturnInfo<?>> {
|
||||
private final List<Item<?>> items;
|
||||
private final Position position;
|
||||
|
||||
@@ -21,15 +21,15 @@ public class Block implements Item<Block.ReturnLevel> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ReturnLevel apply(Buffer buffer, Rotation rotation, Random random, int recursions) {
|
||||
public synchronized ReturnInfo<?> apply(Buffer buffer, Rotation rotation, Random random, int recursions) {
|
||||
for(Item<?> item : items) {
|
||||
Object result = item.apply(buffer, rotation, random, recursions);
|
||||
if(result instanceof ReturnLevel) {
|
||||
ReturnLevel level = (ReturnLevel) result;
|
||||
if(!level.equals(ReturnLevel.NONE)) return level;
|
||||
if(result instanceof ReturnInfo) {
|
||||
ReturnInfo<?> level = (ReturnInfo<?>) result;
|
||||
if(!level.getLevel().equals(ReturnLevel.NONE)) return level;
|
||||
}
|
||||
}
|
||||
return ReturnLevel.NONE;
|
||||
return new ReturnInfo<>(ReturnLevel.NONE, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -37,6 +37,24 @@ public class Block implements Item<Block.ReturnLevel> {
|
||||
return position;
|
||||
}
|
||||
|
||||
public static class ReturnInfo<T> {
|
||||
private final ReturnLevel level;
|
||||
private final T data;
|
||||
|
||||
public ReturnInfo(ReturnLevel level, T data) {
|
||||
this.level = level;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public ReturnLevel getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
public enum ReturnLevel {
|
||||
NONE(false), BREAK(false), CONTINUE(false), RETURN(true), FAIL(true);
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
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.functions.Function;
|
||||
import com.dfsek.terra.api.structures.structure.Rotation;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.Buffer;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public abstract class DefinedFunction<T> implements Function<T> {
|
||||
private final Block block;
|
||||
private final String name;
|
||||
|
||||
protected DefinedFunction(Block block, String name) {
|
||||
this.block = block;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(Buffer buffer, Rotation rotation, Random random, int recursions) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position getPosition() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
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.Item;
|
||||
import com.dfsek.terra.api.structures.structure.Rotation;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.Buffer;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class FunctionBlock<T> implements Item<Block.ReturnInfo<T>> {
|
||||
private final List<Item<?>> items;
|
||||
private final Position position;
|
||||
private final T defaultVal;
|
||||
|
||||
public FunctionBlock(List<Item<?>> items, T defaultVal, Position position) {
|
||||
this.items = items;
|
||||
this.position = position;
|
||||
this.defaultVal = defaultVal;
|
||||
}
|
||||
|
||||
public List<Item<?>> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public synchronized Block.ReturnInfo<T> apply(Buffer buffer, Rotation rotation, Random random, int recursions) {
|
||||
for(Item<?> item : items) {
|
||||
Object result = item.apply(buffer, rotation, random, recursions);
|
||||
if(result instanceof Block.ReturnInfo) {
|
||||
Block.ReturnInfo<T> level = (Block.ReturnInfo<T>) result;
|
||||
if(!level.getLevel().equals(Block.ReturnLevel.NONE)) return level;
|
||||
}
|
||||
}
|
||||
return new Block.ReturnInfo<>(Block.ReturnLevel.NONE, defaultVal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.api.structures.parser.lang.keywords;
|
||||
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.Keyword;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.api.structures.parser.lang.keywords;
|
||||
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.Keyword;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.api.structures.parser.lang.keywords;
|
||||
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.Keyword;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.api.structures.parser.lang.keywords;
|
||||
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.Keyword;
|
||||
@@ -10,7 +10,7 @@ import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class ForKeyword implements Keyword<Block.ReturnLevel> {
|
||||
public class ForKeyword implements Keyword<Block.ReturnInfo<?>> {
|
||||
private final Block conditional;
|
||||
private final Item<?> initializer;
|
||||
private final Returnable<Boolean> statement;
|
||||
@@ -26,13 +26,13 @@ public class ForKeyword implements Keyword<Block.ReturnLevel> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block.ReturnLevel apply(Buffer buffer, Rotation rotation, Random random, int recursions) {
|
||||
public Block.ReturnInfo<?> apply(Buffer buffer, Rotation rotation, Random random, int recursions) {
|
||||
for(initializer.apply(buffer, rotation, random, recursions); statement.apply(buffer, rotation, random, recursions); incrementer.apply(buffer, rotation, random, recursions)) {
|
||||
Block.ReturnLevel level = conditional.apply(buffer, rotation, random, recursions);
|
||||
if(level.equals(Block.ReturnLevel.BREAK)) break;
|
||||
if(level.isReturnFast()) return level;
|
||||
Block.ReturnInfo<?> level = conditional.apply(buffer, rotation, random, recursions);
|
||||
if(level.getLevel().equals(Block.ReturnLevel.BREAK)) break;
|
||||
if(level.getLevel().isReturnFast()) return level;
|
||||
}
|
||||
return Block.ReturnLevel.NONE;
|
||||
return new Block.ReturnInfo<>(Block.ReturnLevel.NONE, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -11,7 +11,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class IfKeyword implements Keyword<Block.ReturnLevel> {
|
||||
public class IfKeyword implements Keyword<Block.ReturnInfo<?>> {
|
||||
private final Block conditional;
|
||||
private final Returnable<Boolean> statement;
|
||||
private final Position position;
|
||||
@@ -27,7 +27,7 @@ public class IfKeyword implements Keyword<Block.ReturnLevel> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block.ReturnLevel apply(Buffer buffer, Rotation rotation, Random random, int recursions) {
|
||||
public Block.ReturnInfo<?> apply(Buffer buffer, Rotation rotation, Random random, int recursions) {
|
||||
if(statement.apply(buffer, rotation, random, recursions)) return conditional.apply(buffer, rotation, random, recursions);
|
||||
else {
|
||||
for(Pair<Returnable<Boolean>, Block> pair : elseIf) {
|
||||
@@ -37,7 +37,7 @@ public class IfKeyword implements Keyword<Block.ReturnLevel> {
|
||||
}
|
||||
if(elseBlock != null) return elseBlock.apply(buffer, rotation, random, recursions);
|
||||
}
|
||||
return Block.ReturnLevel.NONE;
|
||||
return new Block.ReturnInfo<>(Block.ReturnLevel.NONE, null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class WhileKeyword implements Keyword<Block.ReturnLevel> {
|
||||
public class WhileKeyword implements Keyword<Block.ReturnInfo<?>> {
|
||||
private final Block conditional;
|
||||
private final Returnable<Boolean> statement;
|
||||
private final Position position;
|
||||
@@ -21,13 +21,13 @@ public class WhileKeyword implements Keyword<Block.ReturnLevel> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block.ReturnLevel apply(Buffer buffer, Rotation rotation, Random random, int recursions) {
|
||||
public Block.ReturnInfo<?> apply(Buffer buffer, Rotation rotation, Random random, int recursions) {
|
||||
while(statement.apply(buffer, rotation, random, recursions)) {
|
||||
Block.ReturnLevel level = conditional.apply(buffer, rotation, random, recursions);
|
||||
if(level.equals(Block.ReturnLevel.BREAK)) break;
|
||||
if(level.isReturnFast()) return level;
|
||||
Block.ReturnInfo<?> level = conditional.apply(buffer, rotation, random, recursions);
|
||||
if(level.getLevel().equals(Block.ReturnLevel.BREAK)) break;
|
||||
if(level.getLevel().isReturnFast()) return level;
|
||||
}
|
||||
return Block.ReturnLevel.NONE;
|
||||
return new Block.ReturnInfo<>(Block.ReturnLevel.NONE, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -71,16 +71,16 @@ public class StructureScript {
|
||||
*/
|
||||
public boolean execute(Location location, Random random, Rotation rotation) {
|
||||
StructureBuffer buffer = new StructureBuffer(location);
|
||||
Block.ReturnLevel level = block.apply(buffer, rotation, random, 0);
|
||||
Block.ReturnInfo<?> level = block.apply(buffer, rotation, random, 0);
|
||||
buffer.paste();
|
||||
return !level.equals(Block.ReturnLevel.FAIL);
|
||||
return !level.getLevel().equals(Block.ReturnLevel.FAIL);
|
||||
}
|
||||
|
||||
public boolean execute(Location location, Chunk chunk, Random random, Rotation rotation) {
|
||||
StructureBuffer buffer = cache.computeIfAbsent(location, loc -> {
|
||||
StructureBuffer buf = new StructureBuffer(loc);
|
||||
Block.ReturnLevel level = block.apply(buf, rotation, random, 0);
|
||||
buf.setSucceeded(!level.equals(Block.ReturnLevel.FAIL));
|
||||
Block.ReturnInfo<?> level = block.apply(buf, rotation, random, 0);
|
||||
buf.setSucceeded(!level.getLevel().equals(Block.ReturnLevel.FAIL));
|
||||
return buf;
|
||||
});
|
||||
buffer.paste(chunk);
|
||||
|
||||
Reference in New Issue
Block a user