diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/lexer/Lexer.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/lexer/Lexer.java index 9f5fcb01d..041981408 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/lexer/Lexer.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/lexer/Lexer.java @@ -83,17 +83,17 @@ public class Lexer { // Check if operator token if(reader.matchesString("==", true)) - return new Token("==", TokenType.EQUALS_OPERATOR, reader.getPosition()); + return new Token("==", TokenType.EQUALS_EQUALS, reader.getPosition()); if(reader.matchesString("!=", true)) - return new Token("!=", TokenType.NOT_EQUALS_OPERATOR, reader.getPosition()); + return new Token("!=", TokenType.BANG_EQUALS, reader.getPosition()); if(reader.matchesString(">=", true)) - return new Token(">=", TokenType.GREATER_THAN_OR_EQUALS_OPERATOR, reader.getPosition()); + return new Token(">=", TokenType.GREATER_EQUAL, reader.getPosition()); if(reader.matchesString("<=", true)) - return new Token("<=", TokenType.LESS_THAN_OR_EQUALS_OPERATOR, reader.getPosition()); + return new Token("<=", TokenType.LESS_EQUALS, reader.getPosition()); if(reader.matchesString(">", true)) - return new Token(">", TokenType.GREATER_THAN_OPERATOR, reader.getPosition()); + return new Token(">", TokenType.GREATER, reader.getPosition()); if(reader.matchesString("<", true)) - return new Token("<", TokenType.LESS_THAN_OPERATOR, reader.getPosition()); + return new Token("<", TokenType.LESS, reader.getPosition()); // Check if logical operator if(reader.matchesString("||", true)) @@ -131,9 +131,9 @@ public class Lexer { } if(reader.current().is('(')) - return new Token(reader.consume().toString(), TokenType.GROUP_BEGIN, reader.getPosition()); + return new Token(reader.consume().toString(), TokenType.OPEN_PAREN, reader.getPosition()); if(reader.current().is(')')) - return new Token(reader.consume().toString(), TokenType.GROUP_END, reader.getPosition()); + return new Token(reader.consume().toString(), TokenType.CLOSE_PAREN, reader.getPosition()); if(reader.current().is(';')) return new Token(reader.consume().toString(), TokenType.STATEMENT_END, reader.getPosition()); if(reader.current().is(',')) @@ -153,19 +153,19 @@ public class Lexer { if(reader.current().is('=')) return new Token(reader.consume().toString(), TokenType.ASSIGNMENT, reader.getPosition()); if(reader.current().is('+')) - return new Token(reader.consume().toString(), TokenType.ADDITION_OPERATOR, reader.getPosition()); + return new Token(reader.consume().toString(), TokenType.PLUS, reader.getPosition()); if(reader.current().is('-')) - return new Token(reader.consume().toString(), TokenType.SUBTRACTION_OPERATOR, + return new Token(reader.consume().toString(), TokenType.MINUS, reader.getPosition()); if(reader.current().is('*')) - return new Token(reader.consume().toString(), TokenType.MULTIPLICATION_OPERATOR, + return new Token(reader.consume().toString(), TokenType.STAR, reader.getPosition()); if(reader.current().is('/')) - return new Token(reader.consume().toString(), TokenType.DIVISION_OPERATOR, reader.getPosition()); + return new Token(reader.consume().toString(), TokenType.FORWARD_SLASH, reader.getPosition()); if(reader.current().is('%')) return new Token(reader.consume().toString(), TokenType.MODULO_OPERATOR, reader.getPosition()); if(reader.current().is('!')) - return new Token(reader.consume().toString(), TokenType.BOOLEAN_NOT, reader.getPosition()); + return new Token(reader.consume().toString(), TokenType.BANG, reader.getPosition()); // Read word StringBuilder token = new StringBuilder(); diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/lexer/Token.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/lexer/Token.java index 86c3b8855..dcf5986f9 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/lexer/Token.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/lexer/Token.java @@ -44,29 +44,29 @@ public class Token { } public boolean isBinaryOperator() { - return type.equals(TokenType.ADDITION_OPERATOR) - || type.equals(TokenType.SUBTRACTION_OPERATOR) - || type.equals(TokenType.MULTIPLICATION_OPERATOR) - || type.equals(TokenType.DIVISION_OPERATOR) - || type.equals(TokenType.EQUALS_OPERATOR) - || type.equals(TokenType.NOT_EQUALS_OPERATOR) - || type.equals(TokenType.LESS_THAN_OPERATOR) - || type.equals(TokenType.GREATER_THAN_OPERATOR) - || type.equals(TokenType.LESS_THAN_OR_EQUALS_OPERATOR) - || type.equals(TokenType.GREATER_THAN_OR_EQUALS_OPERATOR) + return type.equals(TokenType.PLUS) + || type.equals(TokenType.MINUS) + || type.equals(TokenType.STAR) + || type.equals(TokenType.FORWARD_SLASH) + || type.equals(TokenType.EQUALS_EQUALS) + || type.equals(TokenType.BANG_EQUALS) + || type.equals(TokenType.LESS) + || type.equals(TokenType.GREATER) + || type.equals(TokenType.LESS_EQUALS) + || type.equals(TokenType.GREATER_EQUAL) || type.equals(TokenType.BOOLEAN_OR) || type.equals(TokenType.BOOLEAN_AND) || type.equals(TokenType.MODULO_OPERATOR); } public boolean isStrictNumericOperator() { - return type.equals(TokenType.SUBTRACTION_OPERATOR) - || type.equals(TokenType.MULTIPLICATION_OPERATOR) - || type.equals(TokenType.DIVISION_OPERATOR) - || type.equals(TokenType.GREATER_THAN_OPERATOR) - || type.equals(TokenType.LESS_THAN_OPERATOR) - || type.equals(TokenType.LESS_THAN_OR_EQUALS_OPERATOR) - || type.equals(TokenType.GREATER_THAN_OR_EQUALS_OPERATOR) + return type.equals(TokenType.MINUS) + || type.equals(TokenType.STAR) + || type.equals(TokenType.FORWARD_SLASH) + || type.equals(TokenType.GREATER) + || type.equals(TokenType.LESS) + || type.equals(TokenType.LESS_EQUALS) + || type.equals(TokenType.GREATER_EQUAL) || type.equals(TokenType.MODULO_OPERATOR); } @@ -108,11 +108,11 @@ public class Token { /** * Beginning of group */ - GROUP_BEGIN, + OPEN_PAREN, /** * Ending of group */ - GROUP_END, + CLOSE_PAREN, /** * End of statement */ @@ -136,43 +136,43 @@ public class Token { /** * Boolean equals operator */ - EQUALS_OPERATOR, + EQUALS_EQUALS, /** * Boolean not equals operator */ - NOT_EQUALS_OPERATOR, + BANG_EQUALS, /** * Boolean greater than operator */ - GREATER_THAN_OPERATOR, + GREATER, /** * Boolean less than operator */ - LESS_THAN_OPERATOR, + LESS, /** * Boolean greater than or equal to operator */ - GREATER_THAN_OR_EQUALS_OPERATOR, + GREATER_EQUAL, /** * Boolean less than or equal to operator */ - LESS_THAN_OR_EQUALS_OPERATOR, + LESS_EQUALS, /** * Addition/concatenation operator */ - ADDITION_OPERATOR, + PLUS, /** * Subtraction operator */ - SUBTRACTION_OPERATOR, + MINUS, /** * Multiplication operator */ - MULTIPLICATION_OPERATOR, + STAR, /** * Division operator */ - DIVISION_OPERATOR, + FORWARD_SLASH, /** * Modulo operator. */ @@ -180,7 +180,7 @@ public class Token { /** * Boolean not operator */ - BOOLEAN_NOT, + BANG, /** * Boolean or */ diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/parser/Parser.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/parser/Parser.java index 0a046b5ea..fdefb4326 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/parser/Parser.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/parser/Parser.java @@ -63,11 +63,12 @@ import com.dfsek.terra.api.util.generic.pair.Pair; @SuppressWarnings("unchecked") public class Parser { - private final String source; private final List ignoredFunctions = new ArrayList<>(); - public Parser(String source) { - this.source = source; + private final Lexer lexer; + + public Parser(Lexer lexer) { + this.lexer = lexer; } /** @@ -78,30 +79,30 @@ public class Parser { * @throws ParseException If parsing fails. */ public Executable parse(ScopeBuilder scopeBuilder) { - return new Executable(parseBlock(new Lexer(source), scopeBuilder, ReturnType.VOID), scopeBuilder); + return new Executable(parseBlock(scopeBuilder, ReturnType.VOID), scopeBuilder); } - private WhileKeyword parseWhileLoop(Lexer lexer, ScopeBuilder scopeBuilder) { + private WhileKeyword parseWhileLoop(ScopeBuilder scopeBuilder) { SourcePosition start = lexer.consume().getPosition(); - ParserUtil.ensureType(lexer.consume(), TokenType.GROUP_BEGIN); + ParserUtil.ensureType(lexer.consume(), TokenType.OPEN_PAREN); scopeBuilder = scopeBuilder.innerLoopScope(); - Expression condition = parseExpression(lexer, true, scopeBuilder); + Expression condition = parseExpression(true, scopeBuilder); ParserUtil.ensureReturnType(condition, Expression.ReturnType.BOOLEAN); - ParserUtil.ensureType(lexer.consume(), TokenType.GROUP_END); - return new WhileKeyword(parseStatementBlock(lexer, scopeBuilder, ReturnType.VOID), (Expression) condition, + ParserUtil.ensureType(lexer.consume(), TokenType.CLOSE_PAREN); + return new WhileKeyword(parseStatementBlock(scopeBuilder, ReturnType.VOID), (Expression) condition, start); // While loop } - private IfKeyword parseIfStatement(Lexer lexer, ScopeBuilder scopeBuilder) { + private IfKeyword parseIfStatement(ScopeBuilder scopeBuilder) { SourcePosition start = lexer.consume().getPosition(); - ParserUtil.ensureType(lexer.consume(), TokenType.GROUP_BEGIN); - Expression condition = parseExpression(lexer, true, scopeBuilder); + ParserUtil.ensureType(lexer.consume(), TokenType.OPEN_PAREN); + Expression condition = parseExpression(true, scopeBuilder); ParserUtil.ensureReturnType(condition, Expression.ReturnType.BOOLEAN); - ParserUtil.ensureType(lexer.consume(), TokenType.GROUP_END); + ParserUtil.ensureType(lexer.consume(), TokenType.CLOSE_PAREN); Block elseBlock = null; - Block statement = parseStatementBlock(lexer, scopeBuilder, ReturnType.VOID); + Block statement = parseStatementBlock(scopeBuilder, ReturnType.VOID); List, Block>> elseIf = new ArrayList<>(); @@ -109,11 +110,11 @@ public class Parser { lexer.consume(); // Consume else. if(lexer.current().isType(TokenType.IF_STATEMENT)) { lexer.consume(); // Consume if. - Expression elseCondition = parseExpression(lexer, true, scopeBuilder); + Expression elseCondition = parseExpression(true, scopeBuilder); ParserUtil.ensureReturnType(elseCondition, Expression.ReturnType.BOOLEAN); - elseIf.add(Pair.of((Expression) elseCondition, parseStatementBlock(lexer, scopeBuilder, ReturnType.VOID))); + elseIf.add(Pair.of((Expression) elseCondition, parseStatementBlock(scopeBuilder, ReturnType.VOID))); } else { - elseBlock = parseStatementBlock(lexer, scopeBuilder, ReturnType.VOID); + elseBlock = parseStatementBlock(scopeBuilder, ReturnType.VOID); break; // Else must be last. } } @@ -121,10 +122,10 @@ public class Parser { return new IfKeyword(statement, (Expression) condition, elseIf, elseBlock, start); // If statement } - private Block parseStatementBlock(Lexer lexer, ScopeBuilder scopeBuilder, ReturnType blockReturnType) { + private Block parseStatementBlock(ScopeBuilder scopeBuilder, ReturnType blockReturnType) { if(lexer.current().isType(TokenType.BLOCK_BEGIN)) { ParserUtil.ensureType(lexer.consume(), TokenType.BLOCK_BEGIN); - Block block = parseBlock(lexer, scopeBuilder, blockReturnType); + Block block = parseBlock(scopeBuilder, blockReturnType); ParserUtil.ensureType(lexer.consume(), TokenType.BLOCK_END); return block; } else { @@ -133,61 +134,61 @@ public class Parser { } } - private ForKeyword parseForLoop(Lexer lexer, ScopeBuilder scopeBuilder) { + private ForKeyword parseForLoop(ScopeBuilder scopeBuilder) { SourcePosition start = lexer.consume().getPosition(); - ParserUtil.ensureType(lexer.consume(), TokenType.GROUP_BEGIN); + ParserUtil.ensureType(lexer.consume(), TokenType.OPEN_PAREN); scopeBuilder = scopeBuilder.innerLoopScope(); // new scope Token f = lexer.current(); ParserUtil.ensureType(f, TokenType.TYPE_NUMBER, TokenType.TYPE_STRING, TokenType.TYPE_BOOLEAN, TokenType.IDENTIFIER); Expression initializer; if(f.isVariableDeclaration()) { - Expression forVar = parseDeclaration(lexer, scopeBuilder); + Expression forVar = parseDeclaration(scopeBuilder); Token name = lexer.current(); if(scopeBuilder.containsFunction(name.getContent()) || scopeBuilder.contains(name.getContent())) throw new ParseException(name.getContent() + " is already defined in this scope", name.getPosition()); initializer = forVar; - } else initializer = parseExpression(lexer, true, scopeBuilder); + } else initializer = parseExpression(true, scopeBuilder); ParserUtil.ensureType(lexer.consume(), TokenType.STATEMENT_END); - Expression conditional = parseExpression(lexer, true, scopeBuilder); + Expression conditional = parseExpression(true, scopeBuilder); ParserUtil.ensureReturnType(conditional, Expression.ReturnType.BOOLEAN); ParserUtil.ensureType(lexer.consume(), TokenType.STATEMENT_END); Expression incrementer; Token token = lexer.current(); if(scopeBuilder.contains(token.getContent())) { // Assume variable assignment - incrementer = parseAssignment(lexer, scopeBuilder); - } else incrementer = parseFunctionInvocation(lexer, true, scopeBuilder); + incrementer = parseAssignment(scopeBuilder); + } else incrementer = parseFunctionInvocation(true, scopeBuilder); - ParserUtil.ensureType(lexer.consume(), TokenType.GROUP_END); + ParserUtil.ensureType(lexer.consume(), TokenType.CLOSE_PAREN); - return new ForKeyword(parseStatementBlock(lexer, scopeBuilder, ReturnType.VOID), initializer, (Expression) conditional, + return new ForKeyword(parseStatementBlock(scopeBuilder, ReturnType.VOID), initializer, (Expression) conditional, incrementer, start); } - private Expression parseExpression(Lexer lexer, boolean full, ScopeBuilder scopeBuilder) { + private Expression parseExpression(boolean full, ScopeBuilder scopeBuilder) { boolean booleanInverted = false; // Check for boolean not operator boolean negate = false; - if(lexer.current().isType(TokenType.BOOLEAN_NOT)) { + if(lexer.current().isType(TokenType.BANG)) { booleanInverted = true; lexer.consume(); - } else if(lexer.current().isType(TokenType.SUBTRACTION_OPERATOR)) { + } else if(lexer.current().isType(TokenType.MINUS)) { negate = true; lexer.consume(); } Token id = lexer.current(); - ParserUtil.ensureType(id, TokenType.IDENTIFIER, TokenType.BOOLEAN, TokenType.STRING, TokenType.NUMBER, TokenType.GROUP_BEGIN); + ParserUtil.ensureType(id, TokenType.IDENTIFIER, TokenType.BOOLEAN, TokenType.STRING, TokenType.NUMBER, TokenType.OPEN_PAREN); Expression expression; if(id.isConstant()) { expression = parseConstantExpression(lexer); - } else if(id.isType(TokenType.GROUP_BEGIN)) { // Parse grouped expression - expression = parseExpressionGroup(lexer, scopeBuilder); + } else if(id.isType(TokenType.OPEN_PAREN)) { // Parse grouped expression + expression = parseExpressionGroup(scopeBuilder); } else { if(scopeBuilder.containsFunction(id.getContent())) - expression = parseFunctionInvocation(lexer, false, scopeBuilder); + expression = parseFunctionInvocation(false, scopeBuilder); else if(scopeBuilder.contains(id.getContent())) { ParserUtil.ensureType(lexer.consume(), TokenType.IDENTIFIER); String varId = id.getContent(); @@ -211,7 +212,7 @@ public class Parser { } if(full && lexer.current().isBinaryOperator()) { // Parse binary operations - return parseBinaryOperation(expression, lexer, scopeBuilder); + return parseBinaryOperation(expression, scopeBuilder); } return expression; } @@ -231,27 +232,26 @@ public class Parser { }; } - private Expression parseExpressionGroup(Lexer lexer, ScopeBuilder scopeBuilder) { - ParserUtil.ensureType(lexer.consume(), TokenType.GROUP_BEGIN); - Expression expression = parseExpression(lexer, true, scopeBuilder); // Parse inside of group as a separate expression - ParserUtil.ensureType(lexer.consume(), TokenType.GROUP_END); + private Expression parseExpressionGroup(ScopeBuilder scopeBuilder) { + ParserUtil.ensureType(lexer.consume(), TokenType.OPEN_PAREN); + Expression expression = parseExpression(true, scopeBuilder); // Parse inside of group as a separate expression + ParserUtil.ensureType(lexer.consume(), TokenType.CLOSE_PAREN); return expression; } - private BinaryOperation parseBinaryOperation(Expression left, Lexer lexer, - ScopeBuilder scopeBuilder) { + private BinaryOperation parseBinaryOperation(Expression left, ScopeBuilder scopeBuilder) { Token binaryOperator = lexer.consume(); ParserUtil.checkBinaryOperator(binaryOperator); - Expression right = parseExpression(lexer, false, scopeBuilder); + Expression right = parseExpression(false, scopeBuilder); Token other = lexer.current(); if(ParserUtil.hasPrecedence(binaryOperator.getType(), other.getType())) - return assemble(left, parseBinaryOperation(right, lexer, scopeBuilder), binaryOperator); + return assemble(left, parseBinaryOperation(right, scopeBuilder), binaryOperator); if(other.isBinaryOperator()) - return parseBinaryOperation(assemble(left, right, binaryOperator), lexer, scopeBuilder); + return parseBinaryOperation(assemble(left, right, binaryOperator), scopeBuilder); return assemble(left, right, binaryOperator); } @@ -261,29 +261,29 @@ public class Parser { ParserUtil.checkArithmeticOperation(left, right, binaryOperator); // Numeric type checking if(binaryOperator.isStrictBooleanOperator()) ParserUtil.checkBooleanOperation(left, right, binaryOperator); // Boolean type checking switch(binaryOperator.getType()) { - case ADDITION_OPERATOR: + case PLUS: if(left.returnType().equals(Expression.ReturnType.NUMBER) && right.returnType().equals(Expression.ReturnType.NUMBER)) { return new NumberAdditionOperation((Expression) left, (Expression) right, binaryOperator.getPosition()); } return new ConcatenationOperation((Expression) left, (Expression) right, binaryOperator.getPosition()); - case SUBTRACTION_OPERATOR: + case MINUS: return new SubtractionOperation((Expression) left, (Expression) right, binaryOperator.getPosition()); - case MULTIPLICATION_OPERATOR: + case STAR: return new MultiplicationOperation((Expression) left, (Expression) right, binaryOperator.getPosition()); - case DIVISION_OPERATOR: + case FORWARD_SLASH: return new DivisionOperation((Expression) left, (Expression) right, binaryOperator.getPosition()); - case EQUALS_OPERATOR: + case EQUALS_EQUALS: return new EqualsStatement((Expression) left, (Expression) right, binaryOperator.getPosition()); - case NOT_EQUALS_OPERATOR: + case BANG_EQUALS: return new NotEqualsStatement((Expression) left, (Expression) right, binaryOperator.getPosition()); - case GREATER_THAN_OPERATOR: + case GREATER: return new GreaterThanStatement((Expression) left, (Expression) right, binaryOperator.getPosition()); - case LESS_THAN_OPERATOR: + case LESS: return new LessThanStatement((Expression) left, (Expression) right, binaryOperator.getPosition()); - case GREATER_THAN_OR_EQUALS_OPERATOR: + case GREATER_EQUAL: return new GreaterOrEqualsThanStatement((Expression) left, (Expression) right, binaryOperator.getPosition()); - case LESS_THAN_OR_EQUALS_OPERATOR: + case LESS_EQUALS: return new LessThanOrEqualsStatement((Expression) left, (Expression) right, binaryOperator.getPosition()); case BOOLEAN_AND: return new BooleanAndOperation((Expression) left, (Expression) right, binaryOperator.getPosition()); @@ -296,30 +296,30 @@ public class Parser { } } - private Expression parseDeclaration(Lexer lexer, ScopeBuilder scopeBuilder) { + private Expression parseDeclaration(ScopeBuilder scopeBuilder) { Token type = lexer.consume(); Token identifier = lexer.consume(); ParserUtil.ensureType(identifier, TokenType.IDENTIFIER); Token declarationType = lexer.consume(); - ParserUtil.ensureType(declarationType, TokenType.ASSIGNMENT, TokenType.GROUP_BEGIN); + ParserUtil.ensureType(declarationType, TokenType.ASSIGNMENT, TokenType.OPEN_PAREN); return switch(declarationType.getType()) { - case ASSIGNMENT -> parseVariableDeclaration(lexer, scopeBuilder, type, identifier); - case GROUP_BEGIN -> parseFunctionDeclaration(lexer, scopeBuilder, type, identifier); + case ASSIGNMENT -> parseVariableDeclaration(scopeBuilder, type, identifier); + case OPEN_PAREN -> parseFunctionDeclaration(scopeBuilder, type, identifier); default -> throw new ParseException("Illegal type for declaration: " + type, declarationType.getPosition()); }; } - private Expression parseVariableDeclaration(Lexer lexer, ScopeBuilder scopeBuilder, Token type, Token identifier) { + private Expression parseVariableDeclaration(ScopeBuilder scopeBuilder, Token type, Token identifier) { ParserUtil.ensureType(type, TokenType.TYPE_STRING, TokenType.TYPE_BOOLEAN, TokenType.TYPE_NUMBER); if(scopeBuilder.contains(identifier.getContent())) throw new ParseException(identifier.getContent() + " is already defined in this scope", identifier.getPosition()); - Expression value = parseExpression(lexer, true, scopeBuilder); + Expression value = parseExpression(true, scopeBuilder); ParserUtil.ensureReturnType(value, ParserUtil.getVariableReturnType(type)); String variableName = identifier.getContent(); @@ -334,7 +334,7 @@ public class Parser { }; } - private Expression parseFunctionDeclaration(Lexer lexer, ScopeBuilder scopeBuilder, Token type, Token identifier) { + private Expression parseFunctionDeclaration(ScopeBuilder scopeBuilder, Token type, Token identifier) { ParserUtil.ensureType(type, TokenType.TYPE_STRING, TokenType.TYPE_BOOLEAN, TokenType.TYPE_NUMBER, TokenType.TYPE_VOID); if(scopeBuilder.contains(identifier.getContent())) @@ -345,7 +345,7 @@ public class Parser { ScopeBuilder functionBodyScope = scopeBuilder.functionScope(); // Declare argument names into function body scope - List> argumentInfo = getFunctionArgumentsDeclaration(lexer).stream().map( + List> argumentInfo = getFunctionArgumentsDeclaration().stream().map( arg -> Pair.of(switch(arg.getRight()) { case NUMBER -> functionBodyScope.declareNum(arg.getLeft()); case BOOLEAN -> functionBodyScope.declareBool(arg.getLeft()); @@ -353,7 +353,7 @@ public class Parser { default -> throw new IllegalArgumentException("Unsupported argument type: " + arg.getRight()); }, arg.getRight())).toList(); - Block body = parseStatementBlock(lexer, functionBodyScope, returnType); + Block body = parseStatementBlock(functionBodyScope, returnType); FunctionBuilder functionBuilder = new UserDefinedFunctionBuilder<>(returnType, argumentInfo, body, functionBodyScope); @@ -361,9 +361,9 @@ public class Parser { return Expression.NOOP; } - private List> getFunctionArgumentsDeclaration(Lexer lexer) { + private List> getFunctionArgumentsDeclaration() { List> arguments = new ArrayList<>(); - while(lexer.current().getType() != TokenType.GROUP_END) { + while(lexer.current().getType() != TokenType.CLOSE_PAREN) { // Parse argument type Token typeToken = lexer.consume(); ParserUtil.ensureType(typeToken, TokenType.TYPE_BOOLEAN, TokenType.TYPE_STRING, TokenType.TYPE_NUMBER); @@ -379,11 +379,11 @@ public class Parser { // Consume separator if present, trailing separators are allowed if(lexer.current().isType(TokenType.SEPARATOR)) lexer.consume(); } - ParserUtil.ensureType(lexer.consume(), TokenType.GROUP_END); + ParserUtil.ensureType(lexer.consume(), TokenType.CLOSE_PAREN); return arguments; } - private Block parseBlock(Lexer lexer, ScopeBuilder scopeBuilder, ReturnType blockReturnType) { + private Block parseBlock(ScopeBuilder scopeBuilder, ReturnType blockReturnType) { List> expressions = new ArrayList<>(); scopeBuilder = scopeBuilder.innerScope(); SourcePosition startPosition = lexer.current().getPosition(); @@ -428,15 +428,15 @@ public class Parser { TokenType.FAIL); Expression expression = switch(token.getType()) { - case FOR_LOOP -> parseForLoop(lexer, scopeBuilder); - case IF_STATEMENT -> parseIfStatement(lexer, scopeBuilder); - case WHILE_LOOP -> parseWhileLoop(lexer, scopeBuilder); + case FOR_LOOP -> parseForLoop(scopeBuilder); + case IF_STATEMENT -> parseIfStatement(scopeBuilder); + case WHILE_LOOP -> parseWhileLoop(scopeBuilder); case IDENTIFIER -> { - if(scopeBuilder.contains(token.getContent())) yield parseAssignment(lexer, scopeBuilder); // Assume variable assignment - else yield parseFunctionInvocation(lexer, true, scopeBuilder); + if(scopeBuilder.contains(token.getContent())) yield parseAssignment(scopeBuilder); // Assume variable assignment + else yield parseFunctionInvocation(true, scopeBuilder); } - case TYPE_NUMBER, TYPE_STRING, TYPE_BOOLEAN, TYPE_VOID -> parseDeclaration(lexer, scopeBuilder); - case RETURN -> parseReturn(lexer, scopeBuilder); + case TYPE_NUMBER, TYPE_STRING, TYPE_BOOLEAN, TYPE_VOID -> parseDeclaration(scopeBuilder); + case RETURN -> parseReturn(scopeBuilder); case BREAK -> new BreakKeyword(lexer.consume().getPosition()); case CONTINUE -> new ContinueKeyword(lexer.consume().getPosition()); case FAIL -> new FailKeyword(lexer.consume().getPosition()); @@ -446,24 +446,24 @@ public class Parser { return expression; } - private ReturnKeyword parseReturn(Lexer lexer, ScopeBuilder scopeBuilder) { + private ReturnKeyword parseReturn(ScopeBuilder scopeBuilder) { Token returnToken = lexer.consume(); ParserUtil.ensureType(returnToken, TokenType.RETURN); Expression data = null; if(!lexer.current().isType(TokenType.STATEMENT_END)) { - data = parseExpression(lexer, true, scopeBuilder); + data = parseExpression(true, scopeBuilder); } return new ReturnKeyword(data, returnToken.getPosition()); } - private VariableAssignmentNode parseAssignment(Lexer lexer, ScopeBuilder scopeBuilder) { + private VariableAssignmentNode parseAssignment(ScopeBuilder scopeBuilder) { Token identifier = lexer.consume(); ParserUtil.ensureType(identifier, TokenType.IDENTIFIER); ParserUtil.ensureType(lexer.consume(), TokenType.ASSIGNMENT); - Expression value = parseExpression(lexer, true, scopeBuilder); + Expression value = parseExpression(true, scopeBuilder); String id = identifier.getContent(); @@ -479,18 +479,18 @@ public class Parser { }; } - private Expression parseFunctionInvocation(Lexer lexer, boolean fullStatement, ScopeBuilder scopeBuilder) { + private Expression parseFunctionInvocation(boolean fullStatement, ScopeBuilder scopeBuilder) { Token identifier = lexer.consume(); ParserUtil.ensureType(identifier, TokenType.IDENTIFIER); // First token must be identifier if(!scopeBuilder.containsFunction(identifier.getContent())) throw new ParseException("Function \"" + identifier.getContent() + "\" is not defined in this scope", identifier.getPosition()); - ParserUtil.ensureType(lexer.consume(), TokenType.GROUP_BEGIN); // Second is body begin + ParserUtil.ensureType(lexer.consume(), TokenType.OPEN_PAREN); // Second is body begin - List> args = getFunctionArgs(lexer, scopeBuilder); // Extract arguments, consume the rest. + List> args = getFunctionArgs(scopeBuilder); // Extract arguments, consume the rest. - ParserUtil.ensureType(lexer.consume(), TokenType.GROUP_END); // Remove body end + ParserUtil.ensureType(lexer.consume(), TokenType.CLOSE_PAREN); // Remove body end if(fullStatement) ParserUtil.ensureType(lexer.current(), TokenType.STATEMENT_END); @@ -516,12 +516,12 @@ public class Parser { throw new UnsupportedOperationException("Unsupported function: " + identifier.getContent()); } - private List> getFunctionArgs(Lexer lexer, ScopeBuilder scopeBuilder) { + private List> getFunctionArgs(ScopeBuilder scopeBuilder) { List> args = new ArrayList<>(); - while(!lexer.current().isType(TokenType.GROUP_END)) { - args.add(parseExpression(lexer, true, scopeBuilder)); - ParserUtil.ensureType(lexer.current(), TokenType.SEPARATOR, TokenType.GROUP_END); + while(!lexer.current().isType(TokenType.CLOSE_PAREN)) { + args.add(parseExpression(true, scopeBuilder)); + ParserUtil.ensureType(lexer.current(), TokenType.SEPARATOR, TokenType.CLOSE_PAREN); if(lexer.current().isType(TokenType.SEPARATOR)) lexer.consume(); } return args; diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/parser/ParserUtil.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/parser/ParserUtil.java index d79559067..b35f2499d 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/parser/ParserUtil.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/parser/ParserUtil.java @@ -21,21 +21,21 @@ import com.dfsek.terra.addons.terrascript.parser.lang.Expression; public class ParserUtil { private static final Map> PRECEDENCE = new HashMap<>(); // If second has precedence, true. - private static final List ARITHMETIC = Arrays.asList(TokenType.ADDITION_OPERATOR, TokenType.SUBTRACTION_OPERATOR, - TokenType.MULTIPLICATION_OPERATOR, TokenType.DIVISION_OPERATOR, + private static final List ARITHMETIC = Arrays.asList(TokenType.PLUS, TokenType.MINUS, + TokenType.STAR, TokenType.FORWARD_SLASH, TokenType.MODULO_OPERATOR); - private static final List COMPARISON = Arrays.asList(TokenType.EQUALS_OPERATOR, TokenType.NOT_EQUALS_OPERATOR, - TokenType.LESS_THAN_OPERATOR, TokenType.LESS_THAN_OR_EQUALS_OPERATOR, - TokenType.GREATER_THAN_OPERATOR, - TokenType.GREATER_THAN_OR_EQUALS_OPERATOR); + private static final List COMPARISON = Arrays.asList(TokenType.EQUALS_EQUALS, TokenType.BANG_EQUALS, + TokenType.LESS, TokenType.LESS_EQUALS, + TokenType.GREATER, + TokenType.GREATER_EQUAL); static { // Setup precedence Map add = new HashMap<>(); // Addition/subtraction before Multiplication/division. - add.put(TokenType.MULTIPLICATION_OPERATOR, true); - add.put(TokenType.DIVISION_OPERATOR, true); + add.put(TokenType.STAR, true); + add.put(TokenType.FORWARD_SLASH, true); - PRECEDENCE.put(TokenType.ADDITION_OPERATOR, add); - PRECEDENCE.put(TokenType.SUBTRACTION_OPERATOR, add); + PRECEDENCE.put(TokenType.PLUS, add); + PRECEDENCE.put(TokenType.MINUS, add); Map numericBoolean = new HashMap<>(); diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/StructureScript.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/StructureScript.java index 815af1f1d..72dae25c8 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/StructureScript.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/StructureScript.java @@ -7,6 +7,8 @@ package com.dfsek.terra.addons.terrascript.script; +import com.dfsek.terra.addons.terrascript.lexer.Lexer; + import net.jafama.FastMath; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; @@ -62,18 +64,18 @@ public class StructureScript implements Structure, Keyed { public StructureScript(InputStream source, RegistryKey id, Platform platform, Registry structureRegistry, Registry lootRegistry, Registry functionRegistry) { - Parser parser; + Lexer lexer; try { - parser = new Parser(IOUtils.toString(source, Charset.defaultCharset())); + lexer = new Lexer(IOUtils.toString(source, Charset.defaultCharset())); } catch(IOException e) { throw new RuntimeException(e); } + Parser parser = new Parser(lexer); this.id = id; this.profile = "terrascript_direct:" + id; ScopeBuilder scope = new ScopeBuilder(); - //noinspection unchecked functionRegistry.forEach((key, function) -> scope.registerFunction(key.getID(), function)); // Register registry functions. scope diff --git a/common/addons/structure-terrascript-loader/src/test/java/structure/ParserTest.java b/common/addons/structure-terrascript-loader/src/test/java/structure/ParserTest.java index f677b04f0..c93c1ebc3 100644 --- a/common/addons/structure-terrascript-loader/src/test/java/structure/ParserTest.java +++ b/common/addons/structure-terrascript-loader/src/test/java/structure/ParserTest.java @@ -8,6 +8,7 @@ package structure; +import com.dfsek.terra.addons.terrascript.lexer.Lexer; import com.dfsek.terra.addons.terrascript.parser.lang.Scope.ScopeBuilder; import org.apache.commons.io.IOUtils; @@ -32,8 +33,8 @@ import com.dfsek.terra.addons.terrascript.lexer.SourcePosition; public class ParserTest { @Test public void parse() throws IOException, ParseException { - Parser parser = new Parser( - IOUtils.toString(Objects.requireNonNull(getClass().getResourceAsStream("/test.tesf")), Charset.defaultCharset())); + Lexer lexer = new Lexer(IOUtils.toString(Objects.requireNonNull(getClass().getResourceAsStream("/test.tesf")), Charset.defaultCharset())); + Parser parser = new Parser(lexer); ScopeBuilder scope = new ScopeBuilder(); scope.registerFunction("test", new FunctionBuilder() {