From ad5823055de2c297c570bd491021efe80264a4ca Mon Sep 17 00:00:00 2001 From: dfsek Date: Thu, 31 Dec 2020 02:03:47 -0700 Subject: [PATCH] do precedence better --- .../terra/api/structures/parser/Parser.java | 2 +- .../api/structures/parser/ParserUtil.java | 23 +++++++++++++++++++ common/src/test/resources/test.tesf | 9 +++++++- 3 files changed, 32 insertions(+), 2 deletions(-) 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 0443827f9..78f9cbfea 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 @@ -286,7 +286,7 @@ public class Parser { Returnable right = parseExpression(tokens, false, variableMap); Token other = tokens.get(); - if(other.isBinaryOperator() && (other.getType().equals(Token.Type.MULTIPLICATION_OPERATOR) || other.getType().equals(Token.Type.DIVISION_OPERATOR))) { + if(ParserUtil.hasPrecedence(binaryOperator.getType(), other.getType())) { return assemble(left, parseBinaryOperation(right, tokens, variableMap), binaryOperator); } else if(other.isBinaryOperator()) { return parseBinaryOperation(assemble(left, right, binaryOperator), tokens, variableMap); diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/ParserUtil.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/ParserUtil.java index c54169044..e42349ac1 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/ParserUtil.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/ParserUtil.java @@ -5,8 +5,26 @@ import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.tokenizer.Token; import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class ParserUtil { + + private static final Map> PRECEDENCE = new HashMap<>(); + private static final List ARITHMETIC = Arrays.asList(Token.Type.ADDITION_OPERATOR, Token.Type.SUBTRACTION_OPERATOR, Token.Type.MULTIPLICATION_OPERATOR, Token.Type.DIVISION_OPERATOR); + + static { // Setup precedence + PRECEDENCE.put(Token.Type.ADDITION_OPERATOR, Arrays.asList(Token.Type.MULTIPLICATION_OPERATOR, Token.Type.DIVISION_OPERATOR)); + PRECEDENCE.put(Token.Type.SUBTRACTION_OPERATOR, Arrays.asList(Token.Type.MULTIPLICATION_OPERATOR, Token.Type.DIVISION_OPERATOR)); + PRECEDENCE.put(Token.Type.EQUALS_OPERATOR, ARITHMETIC); + PRECEDENCE.put(Token.Type.NOT_EQUALS_OPERATOR, ARITHMETIC); + PRECEDENCE.put(Token.Type.GREATER_THAN_OPERATOR, ARITHMETIC); + 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); + } + public static void checkType(Token token, Token.Type... expected) throws ParseException { for(Token.Type type : expected) if(token.getType().equals(type)) return; throw new ParseException("Expected " + Arrays.toString(expected) + " but found " + token.getType(), token.getPosition()); @@ -59,4 +77,9 @@ public class ParserUtil { throw new ParseException("Unexpected token " + varToken.getType() + "; expected variable declaration", varToken.getPosition()); } } + + public static boolean hasPrecedence(Token.Type first, Token.Type second) { + if(!PRECEDENCE.containsKey(first)) return false; + return PRECEDENCE.get(first).contains(second); + } } diff --git a/common/src/test/resources/test.tesf b/common/src/test/resources/test.tesf index 8743834b1..f1108abda 100644 --- a/common/src/test/resources/test.tesf +++ b/common/src/test/resources/test.tesf @@ -7,6 +7,11 @@ num testVar = 3.4; bool boolean = true; str stringVar = "hello!"; +num precedence = 2 + 2 * 2; +test("precedence: " + precedence, 2); +num precedence2 = 2 * 2 + 2; +test("precedence 2: " + precedence2, 2); + bool iftest = false; bool truetest = false; @@ -19,7 +24,9 @@ for(num i = 0; i < 5; i = i + 1) { for(num j = 0; j < 5; j = j + 1) test("single statement j = " + j, iterator); - +if(4 + 2 == 2 + 4) { + test("new thing " + 2, iterator); +} while(iterator < 5) { test("always, even after " + 2, iterator);