From 34253a70ba026812c2d856211072705ebbfc9abe Mon Sep 17 00:00:00 2001 From: Marvin Kaiser Date: Mon, 3 Feb 2020 16:35:29 +0100 Subject: [PATCH] Implement operator precedence with and without parenthesis --- .../antlr4/de/hsrm/compiler/Klang/Klang.g4 | 27 +++---- .../hsrm/compiler/Klang/ContextAnalysis.java | 5 ++ src/test/math/math.c | 78 +++++++++++++------ src/test/math/math.h | 10 ++- src/test/test.k | 34 ++++++++ 5 files changed, 117 insertions(+), 37 deletions(-) diff --git a/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 b/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 index 0354533..c378682 100644 --- a/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 +++ b/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 @@ -65,19 +65,20 @@ return_statement expression : atom #atomExpression - | OPAR lhs=expression ADD rhs=expression CPAR #additionExpression - | OPAR lhs=expression SUB rhs=expression CPAR #substractionExpression - | OPAR lhs=expression MUL rhs=expression CPAR #multiplicationExpression - | OPAR lhs=expression DIV rhs=expression CPAR #divisionExpression - | OPAR lhs=expression MOD rhs=expression CPAR #moduloExpression - | OPAR lhs=expression EQEQ rhs=expression CPAR #equalityExpression - | OPAR lhs=expression NEQ rhs=expression CPAR #NotEqualityExpression - | OPAR lhs=expression LT rhs=expression CPAR #lessThanExpression - | OPAR lhs=expression GT rhs=expression CPAR #greaterThanExpression - | OPAR lhs=expression LTE rhs=expression CPAR #lessThanOrEqualToExpression - | OPAR lhs=expression GTE rhs=expression CPAR #GreaterThanOrEqualToExpression - | OPAR lhs=expression OR rhs=expression CPAR #OrExpression - | OPAR lhs=expression AND rhs=expression CPAR #AndExpression + | OPAR expression CPAR #parenthesisExpression + | lhs=expression MUL rhs=expression #multiplicationExpression + | lhs=expression DIV rhs=expression #divisionExpression + | lhs=expression MOD rhs=expression #moduloExpression + | lhs=expression ADD rhs=expression #additionExpression + | lhs=expression SUB rhs=expression #substractionExpression + | lhs=expression EQEQ rhs=expression #equalityExpression + | lhs=expression NEQ rhs=expression #NotEqualityExpression + | lhs=expression LT rhs=expression #lessThanExpression + | lhs=expression GT rhs=expression #greaterThanExpression + | lhs=expression LTE rhs=expression #lessThanOrEqualToExpression + | lhs=expression GTE rhs=expression #GreaterThanOrEqualToExpression + | lhs=expression OR rhs=expression #OrExpression + | lhs=expression AND rhs=expression #AndExpression | SUB expression #negateExpression | NOT expression #NotExpression | functionCall #functionCallExpression diff --git a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java index 090fac0..d326bff 100644 --- a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java +++ b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java @@ -221,6 +221,11 @@ public class ContextAnalysis extends KlangBaseVisitor { return result; } + @Override + public Node visitParenthesisExpression(KlangParser.ParenthesisExpressionContext ctx) { + return this.visit(ctx.expression()); + } + @Override public Node visitEqualityExpression(KlangParser.EqualityExpressionContext ctx) { Node lhs = this.visit(ctx.lhs); diff --git a/src/test/math/math.c b/src/test/math/math.c index 9acd0ba..c5fb382 100644 --- a/src/test/math/math.c +++ b/src/test/math/math.c @@ -2,59 +2,83 @@ #include "math.h" #include "../print/print.h" -int cAdd(int x, int y) { +int cAdd(int x, int y) +{ return x + y; } -int cSub(int x, int y) { +int cSub(int x, int y) +{ return x - y; } -int cMul(int x, int y) { +int cMul(int x, int y) +{ return x * y; } -int cModulo(int x, int y) { +int cModulo(int x, int y) +{ return x % y; } -int cNeg(int x) { +int cNeg(int x) +{ return -x; } -int cId(int x) { +int cId(int x) +{ return x; } -int cSelfMinus(int x) { +int cSelfMinus(int x) +{ x = x - 1; return x; } - -int math_testExpected(char* name, int x, int y, int expected, int result) { - if (expected == result) { +int math_testExpected(char *name, int x, int y, int expected, int result) +{ + if (expected == result) + { succPrefixTwo(name, x, y, expected, result); return 0; - } else { + } + else + { errPrefixTwo(name, x, y, expected, result); return 1; } } -int math_test(char* name, int (*correctFunction)(int, int), int (*testFunction)(int, int), int x, int y) { +int math_test(char *name, int (*correctFunction)(int, int), int (*testFunction)(int, int), int x, int y) +{ int expected = correctFunction(x, y); int result = testFunction(x, y); return math_testExpected(name, x, y, expected, result); } -int math_testOneArg(char* name, int (*correctFunction)(int), int (*testFunction)(int), int x) { +int math_testOneArg(char *name, int (*correctFunction)(int), int (*testFunction)(int), int x) +{ int expected = correctFunction(x); int result = testFunction(x); - if (expected == result) { + if (expected == result) + { succPrefixOne(name, x, expected, result); return 0; - } else { + } + else + { errPrefixOne(name, x, expected, result); return 1; } } -int runMathTests() { +void math_simpleTest(char *name, int expected, int result) { + if (expected == result) { + succ(name, expected, result); + } else { + err(name, expected, result); + } +} + +int runMathTests() +{ printf("\nAddition Tests \n"); math_test("add", cAdd, add, 0, 0); math_test("add", cAdd, add, 1, 1); @@ -77,10 +101,10 @@ int runMathTests() { math_test("mul", cMul, mul, -1, -1); printf("\nModulo Tests \n"); - math_test("modulo", cModulo, modulo, 1, 1); - math_test("modulo", cModulo, modulo, 1, 5); - math_test("modulo", cModulo, modulo, -1, -1); - math_test("modulo", cModulo, modulo, 1337, 42); + math_test("modulo", cModulo, modulo, 1, 1); + math_test("modulo", cModulo, modulo, 1, 5); + math_test("modulo", cModulo, modulo, -1, -1); + math_test("modulo", cModulo, modulo, 1337, 42); printf("\nNegative Tests\n"); math_testOneArg("neg", cNeg, neg, 0); @@ -88,13 +112,21 @@ int runMathTests() { math_testOneArg("neg", cNeg, neg, -1); printf("\nIdentity Tests\n"); - math_testOneArg("id", cId, id, 0); - math_testOneArg("id", cId, id, -1); - math_testOneArg("id", cId, id, 15); + math_testOneArg("id", cId, id, 0); + math_testOneArg("id", cId, id, -1); + math_testOneArg("id", cId, id, 15); printf("\nMisc Tests\n"); math_testOneArg("selfMinus", cSelfMinus, selfMinus, 5); math_testOneArg("selfMinus", cSelfMinus, selfMinus, 0); math_testOneArg("selfMinus", cSelfMinus, selfMinus, 100); math_testOneArg("selfMinus", cSelfMinus, selfMinus, -50); + math_simpleTest("precedence t1", 16, t1()); + math_simpleTest("precedence t2", 16, t2()); + math_simpleTest("precedence t3", 16, t3()); + math_simpleTest("precedence t4", 16, t4()); + math_simpleTest("precedence t5", 16, t5()); + math_simpleTest("precedence t6", 16, t6()); + math_simpleTest("precedence t7", 16, t7()); + math_simpleTest("precedence t8", 18, t8()); } \ No newline at end of file diff --git a/src/test/math/math.h b/src/test/math/math.h index a89022f..1801543 100644 --- a/src/test/math/math.h +++ b/src/test/math/math.h @@ -8,4 +8,12 @@ int mul(int x, int y); int modulo(int x, int y); int neg(int x); int id(int x); -int selfMinus(int x); \ No newline at end of file +int selfMinus(int x); +int t1(); +int t2(); +int t3(); +int t4(); +int t5(); +int t6(); +int t7(); +int t8(); \ No newline at end of file diff --git a/src/test/test.k b/src/test/test.k index a7d1603..a5c08ec 100644 --- a/src/test/test.k +++ b/src/test/test.k @@ -174,4 +174,38 @@ function not(a: bool): bool { return !a; } +function t1(): int { + return ((5 * 3) + 1); +} + +function t2(): int { + return (1 + (5 * 3)); +} + +function t3(): int { + return 5 * 3 + 1; +} + +function t4(): int { + return 1 + 5 * 3; +} + +function t5(): int { + return (5 * 3 + 1); +} + +function t6(): int { + return (1 + 5 * 3); +} + +function t7(): int { + return 1 + (5 * 3); +} + +function t8(): int { + return (1 + 5) * 3; +} + + + add(1, 1);