From a79b7c936249968210bf4ce349ad1f47693bbd95 Mon Sep 17 00:00:00 2001 From: Marvin Kaiser Date: Fri, 20 Dec 2019 09:01:03 +0100 Subject: [PATCH] Implemented boolean expressions --- makefile | 2 +- .../hsrm/compiler/Klang/visitors/GenASM.java | 106 ++++++++++++++++++ .../hsrm/compiler/Klang/visitors/GetVars.java | 35 ++++++ src/test/comparison/comparison.c | 51 +++++++++ src/test/comparison/comparison.h | 5 + src/test/testCode.c | 3 + src/test/tests.h | 3 +- src/test/tests.k | 27 +++++ 8 files changed, 230 insertions(+), 2 deletions(-) create mode 100644 src/test/comparison/comparison.c create mode 100644 src/test/comparison/comparison.h diff --git a/makefile b/makefile index 9f11615..691f713 100644 --- a/makefile +++ b/makefile @@ -18,7 +18,7 @@ runTest: ./src/test/test ./src/test/test ./src/test/test: ./src/test/tests.s - gcc -o ./src/test/test ./src/test/tests.s ./src/test/functionCall/functionCall.c ./src/test/recursive/recursive.c ./src/test/testCode.c + gcc -o ./src/test/test ./src/test/tests.s ./src/test/functionCall/functionCall.c ./src/test/recursive/recursive.c ./src/test/comparison/comparison.c ./src/test/testCode.c ./src/test/tests.s: target/klang-1.0-jar-with-dependencies.jar java -cp target/klang-1.0-jar-with-dependencies.jar de.hsrm.compiler.Klang.Klang < ./src/test/tests.k > ./src/test/tests.s diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java b/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java index 89804ad..fc561a2 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java @@ -74,6 +74,111 @@ public class GenASM implements Visitor { return null; } + @Override + public Void visit(EqualityExpression e) { + int lblTrue = ++lCount; + int lblEnd = ++lCount; + + e.lhs.welcome(this); + this.ex.write(" pushq %rax\n"); + e.rhs.welcome(this); + this.ex.write(" popq %rbx\n"); + this.ex.write(" cmp %rax, %rbx\n"); + this.ex.write(" je .L" + lblTrue + "\n"); + // false + this.ex.write(" movq $0, %rax\n"); + this.ex.write(" jmp .L" + lblEnd + "\n"); + this.ex.write(".L" + lblTrue + ":\n"); + // true + this.ex.write(" movq $1, %rax\n"); + this.ex.write(".L" + lblEnd + ":\n"); + return null; + } + + @Override + public Void visit(GTExpression e) { + int lblTrue = ++lCount; + int lblEnd = ++lCount; + + e.lhs.welcome(this); + this.ex.write(" pushq %rax\n"); + e.rhs.welcome(this); + this.ex.write(" popq %rbx\n"); + this.ex.write(" cmp %rax, %rbx\n"); + this.ex.write(" jg .L" + lblTrue + "\n"); + // false + this.ex.write(" movq $0, %rax\n"); + this.ex.write(" jmp .L" + lblEnd + "\n"); + this.ex.write(".L" + lblTrue + ":\n"); + // true + this.ex.write(" movq $1, %rax\n"); + this.ex.write(".L" + lblEnd + ":\n"); + return null; + } + + @Override + public Void visit(GTEExpression e) { + int lblTrue = ++lCount; + int lblEnd = ++lCount; + + e.lhs.welcome(this); + this.ex.write(" pushq %rax\n"); + e.rhs.welcome(this); + this.ex.write(" popq %rbx\n"); + this.ex.write(" cmp %rax, %rbx\n"); + this.ex.write(" jge .L" + lblTrue + "\n"); + // false + this.ex.write(" movq $0, %rax\n"); + this.ex.write(" jmp .L" + lblEnd + "\n"); + this.ex.write(".L" + lblTrue + ":\n"); + // true + this.ex.write(" movq $1, %rax\n"); + this.ex.write(".L" + lblEnd + ":\n"); + return null; + } + + @Override + public Void visit(LTExpression e) { + int lblTrue = ++lCount; + int lblEnd = ++lCount; + + e.lhs.welcome(this); + this.ex.write(" pushq %rax\n"); + e.rhs.welcome(this); + this.ex.write(" popq %rbx\n"); + this.ex.write(" cmp %rax, %rbx\n"); + this.ex.write(" jl .L" + lblTrue + "\n"); + // false + this.ex.write(" movq $0, %rax\n"); + this.ex.write(" jmp .L" + lblEnd + "\n"); + this.ex.write(".L" + lblTrue + ":\n"); + // true + this.ex.write(" movq $1, %rax\n"); + this.ex.write(".L" + lblEnd + ":\n"); + return null; + } + + @Override + public Void visit(LTEExpression e) { + int lblTrue = ++lCount; + int lblEnd = ++lCount; + + e.lhs.welcome(this); + this.ex.write(" pushq %rax\n"); + e.rhs.welcome(this); + this.ex.write(" popq %rbx\n"); + this.ex.write(" cmp %rax, %rbx\n"); + this.ex.write(" jle .L" + lblTrue + "\n"); + // false + this.ex.write(" movq $0, %rax\n"); + this.ex.write(" jmp .L" + lblEnd + "\n"); + this.ex.write(".L" + lblTrue + ":\n"); + // true + this.ex.write(" movq $1, %rax\n"); + this.ex.write(".L" + lblEnd + ":\n"); + return null; + } + @Override public Void visit(AdditionExpression e) { e.lhs.welcome(this); @@ -286,4 +391,5 @@ public class GenASM implements Visitor { this.ex.write(" ret\n"); return null; } + } \ No newline at end of file diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java b/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java index 1bef69b..d7e71b8 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java @@ -24,6 +24,41 @@ class GetVars implements Visitor { return null; } + @Override + public Void visit(EqualityExpression e) { + e.lhs.welcome(this); + e.rhs.welcome(this); + return null; + } + + @Override + public Void visit(GTExpression e) { + e.lhs.welcome(this); + e.rhs.welcome(this); + return null; + } + + @Override + public Void visit(GTEExpression e) { + e.lhs.welcome(this); + e.rhs.welcome(this); + return null; + } + + @Override + public Void visit(LTExpression e) { + e.lhs.welcome(this); + e.rhs.welcome(this); + return null; + } + + @Override + public Void visit(LTEExpression e) { + e.lhs.welcome(this); + e.rhs.welcome(this); + return null; + } + @Override public Void visit(AdditionExpression e) { e.lhs.welcome(this); diff --git a/src/test/comparison/comparison.c b/src/test/comparison/comparison.c new file mode 100644 index 0000000..80ebba4 --- /dev/null +++ b/src/test/comparison/comparison.c @@ -0,0 +1,51 @@ +#include +#include "comparison.h" + +void printSuccessComp(char* name, int x, int y, int expected, int result) { + printf("SUCCESS:\t%d %s %d\tGOT: %d\tExpected: %d\n", x, name, y, result, expected); +} + +void printErrorComp(char* name, int x, int y, int expected, int result) { + printf("ERROR:\t\t%d %s %d\tGOT: %d\tExpected: %d\n", x, name, y, result, expected); +} + +int comparisonTest(char* name, int x, int y, int expected, int result) { + if (expected == result) { + printSuccessComp(name, x, y, expected, result); + return 0; + } else { + printErrorComp(name, x, y, expected, result); + return 1; + } +} + +int runComparisonTests() { + printf("\nComparison Tests \n"); + int failed = 0; + failed += comparisonTest("==", 1, 1, 1, eq(1, 1)); + failed += comparisonTest("==", 1, 0, 0, eq(1, 0)); + failed += comparisonTest("==", 0, 1, 0, eq(0, 1)); + failed += comparisonTest("==", 0, 0, 1, eq(0, 0)); + + failed += comparisonTest("<", 1, 1, 0, lt(1, 1)); + failed += comparisonTest("<", 1, 0, 0, lt(1, 0)); + failed += comparisonTest("<", 0, 1, 1, lt(0, 1)); + failed += comparisonTest("<", 0, 0, 0, lt(0, 0)); + + failed += comparisonTest("<=", 1, 1, 1, lte(1, 1)); + failed += comparisonTest("<=", 1, 0, 0, lte(1, 0)); + failed += comparisonTest("<=", 0, 1, 1, lte(0, 1)); + failed += comparisonTest("<=", 0, 0, 1, lte(0, 0)); + + failed += comparisonTest(">", 1, 1, 0, gt(1, 1)); + failed += comparisonTest(">", 1, 0, 1, gt(1, 0)); + failed += comparisonTest(">", 0, 1, 0, gt(0, 1)); + failed += comparisonTest(">", 0, 0, 0, gt(0, 0)); + + failed += comparisonTest(">=", 1, 1, 1, gte(1, 1)); + failed += comparisonTest(">=", 1, 0, 1, gte(1, 0)); + failed += comparisonTest(">=", 0, 1, 0, gte(0, 1)); + failed += comparisonTest(">=", 0, 0, 1, gte(0, 0)); + + return failed; +} \ No newline at end of file diff --git a/src/test/comparison/comparison.h b/src/test/comparison/comparison.h new file mode 100644 index 0000000..420ce10 --- /dev/null +++ b/src/test/comparison/comparison.h @@ -0,0 +1,5 @@ +int eq(int x, int y); +int lt(int x, int y); +int lte(int x, int y); +int gt(int x, int y); +int gte(int x, int y); diff --git a/src/test/testCode.c b/src/test/testCode.c index 282ca5f..9973c33 100644 --- a/src/test/testCode.c +++ b/src/test/testCode.c @@ -111,6 +111,9 @@ int main(){ // Tests for recursive funtions failed += runRecursiveTests(); + // Tests for comparison expressions + failed += runComparisonTests(); + printf("\n=== Failed Tests: %d\n", failed); if (failed > 0) { diff --git a/src/test/tests.h b/src/test/tests.h index 0754e0a..1215d5e 100644 --- a/src/test/tests.h +++ b/src/test/tests.h @@ -3,4 +3,5 @@ */ int runFunctionCallTests(); -int runRecursiveTests(); \ No newline at end of file +int runRecursiveTests(); +int runComparisonTests(); \ No newline at end of file diff --git a/src/test/tests.k b/src/test/tests.k index 6b82c3a..eabd5d6 100644 --- a/src/test/tests.k +++ b/src/test/tests.k @@ -49,6 +49,7 @@ function get3() { function arg4(a, b, c, d, e, f, g, h, i ,j) { return d; } + function get4() { return arg4(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @@ -56,6 +57,7 @@ function get4() { function arg5(a, b, c, d, e, f, g, h, i ,j) { return e; } + function get5() { return arg5(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @@ -63,6 +65,7 @@ function get5() { function arg6(a, b, c, d, e, f, g, h, i ,j) { return f; } + function get6() { return arg6(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @@ -70,6 +73,7 @@ function get6() { function arg7(a, b, c, d, e, f, g, h, i ,j) { return g; } + function get7() { return arg7(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @@ -77,6 +81,7 @@ function get7() { function arg8(a, b, c, d, e, f, g, h, i ,j) { return h; } + function get8() { return arg8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @@ -84,6 +89,7 @@ function get8() { function arg9(a, b, c, d, e, f, g, h, i ,j) { return i; } + function get9() { return arg9(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @@ -91,6 +97,7 @@ function get9() { function arg10(a, b, c, d, e, f, g, h, i ,j) { return j; } + function get10() { return arg10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @@ -102,4 +109,24 @@ function fac(x) { return 1; } +function eq(x, y) { + return (x == y); +} + +function lt(x, y) { + return (x < y); +} + +function lte(x, y) { + return (x <= y); +} + +function gt(x, y) { + return (x > y); +} + +function gte(x, y) { + return (x >= y); +} + add(1, 1);