diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/Parser.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/Parser.java index 0e17da62f..8f5fc8214 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/Parser.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/Parser.java @@ -16,6 +16,7 @@ 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.IfKeyword; import com.dfsek.terra.api.structures.parser.lang.keywords.ReturnKeyword; import com.dfsek.terra.api.structures.parser.lang.keywords.WhileKeyword; @@ -268,7 +269,7 @@ public class Parser { Token token = tokens.get(0); if(token.getType().equals(Token.Type.BLOCK_END)) break; // Stop parsing at block end. - ParserUtil.checkType(token, Token.Type.IDENTIFIER, Token.Type.IF_STATEMENT, Token.Type.WHILE_LOOP, Token.Type.NUMBER_VARIABLE, Token.Type.STRING_VARIABLE, Token.Type.BOOLEAN_VARIABLE, Token.Type.RETURN, Token.Type.BREAK, Token.Type.CONTINUE); + ParserUtil.checkType(token, Token.Type.IDENTIFIER, Token.Type.IF_STATEMENT, Token.Type.WHILE_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); if(token.isLoopLike()) { // Parse loop-like tokens (if, while, etc) parsedItems.add(parseLoopLike(tokens, parsedVariables)); @@ -299,6 +300,7 @@ public class Parser { } else if(token.getType().equals(Token.Type.RETURN)) parsedItems.add(new ReturnKeyword(tokens.remove(0).getPosition())); else if(token.getType().equals(Token.Type.BREAK)) parsedItems.add(new BreakKeyword(tokens.remove(0).getPosition())); else if(token.getType().equals(Token.Type.CONTINUE)) parsedItems.add(new ContinueKeyword(tokens.remove(0).getPosition())); + else if(token.getType().equals(Token.Type.FAIL)) parsedItems.add(new FailKeyword(tokens.remove(0).getPosition())); else throw new UnsupportedOperationException("Unexpected token " + token.getType() + ": " + token.getPosition()); if(!tokens.isEmpty()) ParserUtil.checkType(tokens.remove(0), Token.Type.STATEMENT_END, Token.Type.BLOCK_END); diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/Block.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/Block.java index a47b19709..e02d0053c 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/Block.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/Block.java @@ -37,6 +37,6 @@ public class Block implements Item { } public enum ReturnLevel { - NONE, BREAK, CONTINUE, RETURN + NONE, BREAK, CONTINUE, RETURN, FAIL } } diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/FailKeyword.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/FailKeyword.java new file mode 100644 index 000000000..bb4904cef --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/FailKeyword.java @@ -0,0 +1,30 @@ +package com.dfsek.terra.api.structures.parser.lang.keywords; + +import com.dfsek.terra.api.structures.parser.lang.Block; +import com.dfsek.terra.api.structures.parser.lang.Keyword; +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; + +public class FailKeyword implements Keyword { + private final Position position; + + public FailKeyword(Position position) { + this.position = position; + } + + @Override + public Block.ReturnLevel apply(Buffer buffer, Rotation rotation, int recursions) { + return Block.ReturnLevel.FAIL; + } + + @Override + public Position getPosition() { + return position; + } + + @Override + public ReturnType returnType() { + return ReturnType.VOID; + } +} diff --git a/common/src/main/java/com/dfsek/terra/api/structures/script/StructureScript.java b/common/src/main/java/com/dfsek/terra/api/structures/script/StructureScript.java index 4f1556c58..12a89c004 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/script/StructureScript.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/script/StructureScript.java @@ -44,10 +44,18 @@ public class StructureScript { this.id = parser.getID(); } - public void execute(Location location, Rotation rotation) { + /** + * Paste the structure at a location + * + * @param location Location to paste structure + * @param rotation Rotation of structure + * @return Whether generation was successful + */ + public boolean execute(Location location, Rotation rotation) { StructureBuffer buffer = new StructureBuffer(location); - block.apply(buffer, rotation, 0); + Block.ReturnLevel level = block.apply(buffer, rotation, 0); buffer.paste(); + return !level.equals(Block.ReturnLevel.FAIL); } public void executeInBuffer(Buffer buffer, Rotation rotation, int recursions) { diff --git a/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Token.java b/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Token.java index b02413940..5916f9288 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Token.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Token.java @@ -207,6 +207,10 @@ public class Token { * Break statement */ BREAK, + /** + * Fail statement. Like return keyword, but specifies that generation has failed. + */ + FAIL, /** * ID declaration */ diff --git a/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Tokenizer.java b/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Tokenizer.java index c6071bec1..a9f52e4f1 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Tokenizer.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Tokenizer.java @@ -140,6 +140,8 @@ public class Tokenizer { return new Token(tokenString, Token.Type.CONTINUE, new Position(reader.getLine(), reader.getIndex())); if(tokenString.equals("break")) return new Token(tokenString, Token.Type.BREAK, new Position(reader.getLine(), reader.getIndex())); + if(tokenString.equals("fail")) + return new Token(tokenString, Token.Type.FAIL, new Position(reader.getLine(), reader.getIndex())); if(tokenString.equals("id")) return new Token(tokenString, Token.Type.ID, new Position(reader.getLine(), reader.getIndex()));