allow data to be returned

This commit is contained in:
dfsek
2020-12-31 02:30:41 -07:00
parent 122fbd841c
commit 792b6efd12
13 changed files with 133 additions and 34 deletions

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);