From c5419b85c7e92fd699b95c87fcbcd146eb452654 Mon Sep 17 00:00:00 2001 From: Marvin Kaiser Date: Fri, 20 Dec 2019 08:40:17 +0100 Subject: [PATCH 1/5] Extend grammar: added boolean expressions --- src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 b/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 index b266c6c..e3fdc45 100644 --- a/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 +++ b/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 @@ -55,6 +55,12 @@ expression | 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 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 + | SUB expression #negateExpression | functionCall #functionCallExpression ; @@ -86,6 +92,11 @@ OPAR: '('; CPAR: ')'; COMMA: ','; EQUAL: '='; +EQEQ: '=='; +LT: '<'; +GT: '>'; +LTE: '<='; +GTE: '>='; MUL: '*'; ADD: '+'; From 00145848dafbb4ea6480294c74446acec0891c2d Mon Sep 17 00:00:00 2001 From: Marvin Kaiser Date: Fri, 20 Dec 2019 08:41:05 +0100 Subject: [PATCH 2/5] Added classes for boolean expressions --- .../nodes/expressions/EqualityExpression.java | 14 ++++++++++++++ .../Klang/nodes/expressions/GTEExpression.java | 14 ++++++++++++++ .../Klang/nodes/expressions/GTExpression.java | 14 ++++++++++++++ .../Klang/nodes/expressions/LTEExpression.java | 14 ++++++++++++++ .../Klang/nodes/expressions/LTExpression.java | 14 ++++++++++++++ 5 files changed, 70 insertions(+) create mode 100644 src/main/java/de/hsrm/compiler/Klang/nodes/expressions/EqualityExpression.java create mode 100644 src/main/java/de/hsrm/compiler/Klang/nodes/expressions/GTEExpression.java create mode 100644 src/main/java/de/hsrm/compiler/Klang/nodes/expressions/GTExpression.java create mode 100644 src/main/java/de/hsrm/compiler/Klang/nodes/expressions/LTEExpression.java create mode 100644 src/main/java/de/hsrm/compiler/Klang/nodes/expressions/LTExpression.java diff --git a/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/EqualityExpression.java b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/EqualityExpression.java new file mode 100644 index 0000000..ad1b068 --- /dev/null +++ b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/EqualityExpression.java @@ -0,0 +1,14 @@ +package de.hsrm.compiler.Klang.nodes.expressions; + +import de.hsrm.compiler.Klang.visitors.Visitor; + +public class EqualityExpression extends BinaryExpression { + public EqualityExpression(Expression lhs, Expression rhs) { + super(lhs, rhs); + } + + @Override + public R welcome(Visitor v) { + return v.visit(this); + } +} \ No newline at end of file diff --git a/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/GTEExpression.java b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/GTEExpression.java new file mode 100644 index 0000000..cfe36d2 --- /dev/null +++ b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/GTEExpression.java @@ -0,0 +1,14 @@ +package de.hsrm.compiler.Klang.nodes.expressions; + +import de.hsrm.compiler.Klang.visitors.Visitor; + +public class GTEExpression extends BinaryExpression { + public GTEExpression(Expression lhs, Expression rhs) { + super(lhs, rhs); + } + + @Override + public R welcome(Visitor v) { + return v.visit(this); + } +} \ No newline at end of file diff --git a/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/GTExpression.java b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/GTExpression.java new file mode 100644 index 0000000..c705cfa --- /dev/null +++ b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/GTExpression.java @@ -0,0 +1,14 @@ +package de.hsrm.compiler.Klang.nodes.expressions; + +import de.hsrm.compiler.Klang.visitors.Visitor; + +public class GTExpression extends BinaryExpression { + public GTExpression(Expression lhs, Expression rhs) { + super(lhs, rhs); + } + + @Override + public R welcome(Visitor v) { + return v.visit(this); + } +} \ No newline at end of file diff --git a/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/LTEExpression.java b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/LTEExpression.java new file mode 100644 index 0000000..a5735c2 --- /dev/null +++ b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/LTEExpression.java @@ -0,0 +1,14 @@ +package de.hsrm.compiler.Klang.nodes.expressions; + +import de.hsrm.compiler.Klang.visitors.Visitor; + +public class LTEExpression extends BinaryExpression { + public LTEExpression(Expression lhs, Expression rhs) { + super(lhs, rhs); + } + + @Override + public R welcome(Visitor v) { + return v.visit(this); + } +} \ No newline at end of file diff --git a/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/LTExpression.java b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/LTExpression.java new file mode 100644 index 0000000..2d259d3 --- /dev/null +++ b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/LTExpression.java @@ -0,0 +1,14 @@ +package de.hsrm.compiler.Klang.nodes.expressions; + +import de.hsrm.compiler.Klang.visitors.Visitor; + +public class LTExpression extends BinaryExpression { + public LTExpression(Expression lhs, Expression rhs) { + super(lhs, rhs); + } + + @Override + public R welcome(Visitor v) { + return v.visit(this); + } +} \ No newline at end of file From f341401cccd76ff63a8ee7e0833e866c96ace634 Mon Sep 17 00:00:00 2001 From: Marvin Kaiser Date: Fri, 20 Dec 2019 08:42:20 +0100 Subject: [PATCH 3/5] Implemented pretty printing and evaluating of boolean expressions --- .../hsrm/compiler/Klang/ContextAnalysis.java | 25 +++++++++ .../compiler/Klang/visitors/EvalVisitor.java | 50 ++++++++++++++++++ .../Klang/visitors/PrettyPrintVisitor.java | 51 ++++++++++++++++++- .../hsrm/compiler/Klang/visitors/Visitor.java | 5 ++ 4 files changed, 130 insertions(+), 1 deletion(-) diff --git a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java index e17066d..2ee65fa 100644 --- a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java +++ b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java @@ -97,6 +97,31 @@ public class ContextAnalysis extends KlangBaseVisitor { return new AdditionExpression((Expression) this.visit(ctx.lhs), (Expression) this.visit(ctx.rhs)); } + @Override + public Node visitEqualityExpression(KlangParser.EqualityExpressionContext ctx) { + return new EqualityExpression((Expression) this.visit(ctx.lhs), (Expression) this.visit(ctx.rhs)); + } + + @Override + public Node visitLessThanExpression(KlangParser.LessThanExpressionContext ctx) { + return new LTExpression((Expression) this.visit(ctx.lhs), (Expression) this.visit(ctx.rhs)); + } + + @Override + public Node visitGreaterThanExpression(KlangParser.GreaterThanExpressionContext ctx) { + return new GTExpression((Expression) this.visit(ctx.lhs), (Expression) this.visit(ctx.rhs)); + } + + @Override + public Node visitLessThanOrEqualToExpression(KlangParser.LessThanOrEqualToExpressionContext ctx) { + return new LTEExpression((Expression) this.visit(ctx.lhs), (Expression) this.visit(ctx.rhs)); + } + + @Override + public Node visitGreaterThanOrEqualToExpression(KlangParser.GreaterThanOrEqualToExpressionContext ctx) { + return new GTEExpression((Expression) this.visit(ctx.lhs), (Expression) this.visit(ctx.rhs)); + } + @Override public Node visitSubstractionExpression(KlangParser.SubstractionExpressionContext ctx) { return new SubstractionExpression((Expression) this.visit(ctx.lhs), (Expression) this.visit(ctx.rhs)); diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java b/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java index 09d870a..778a3d4 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java @@ -20,6 +20,56 @@ public class EvalVisitor implements Visitor { return new Value(e.value); } + @Override + public Value visit(EqualityExpression e) { + Value lhs = e.lhs.welcome(this); + Value rhs = e.rhs.welcome(this); + if (lhs.asInteger() == rhs.asInteger()) { + return new Value(1); + } + return new Value(0); + } + + @Override + public Value visit(GTExpression e) { + Value lhs = e.lhs.welcome(this); + Value rhs = e.rhs.welcome(this); + if (lhs.asInteger() > rhs.asInteger()) { + return new Value(1); + } + return new Value(0); + } + + @Override + public Value visit(GTEExpression e) { + Value lhs = e.lhs.welcome(this); + Value rhs = e.rhs.welcome(this); + if (lhs.asInteger() >= rhs.asInteger()) { + return new Value(1); + } + return new Value(0); + } + + @Override + public Value visit(LTExpression e) { + Value lhs = e.lhs.welcome(this); + Value rhs = e.rhs.welcome(this); + if (lhs.asInteger() < rhs.asInteger()) { + return new Value(1); + } + return new Value(0); + } + + @Override + public Value visit(LTEExpression e) { + Value lhs = e.lhs.welcome(this); + Value rhs = e.rhs.welcome(this); + if (lhs.asInteger() <= rhs.asInteger()) { + return new Value(1); + } + return new Value(0); + } + @Override public Value visit(AdditionExpression e) { Value lhs = e.lhs.welcome(this); diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java b/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java index ad2cc94..4f96be1 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java @@ -71,6 +71,56 @@ public class PrettyPrintVisitor implements Visitor { return null; } + @Override + public Void visit(EqualityExpression e) { + ex.write("("); + e.lhs.welcome(this); + ex.write(" == "); + e.rhs.welcome(this); + ex.write(")"); + return null; + } + + @Override + public Void visit(GTExpression e) { + ex.write("("); + e.lhs.welcome(this); + ex.write(" > "); + e.rhs.welcome(this); + ex.write(")"); + return null; + } + + @Override + public Void visit(GTEExpression e) { + ex.write("("); + e.lhs.welcome(this); + ex.write(" >= "); + e.rhs.welcome(this); + ex.write(")"); + return null; + } + + @Override + public Void visit(LTExpression e) { + ex.write("("); + e.lhs.welcome(this); + ex.write(" < "); + e.rhs.welcome(this); + ex.write(")"); + return null; + } + + @Override + public Void visit(LTEExpression e) { + ex.write("("); + e.lhs.welcome(this); + ex.write(" <= "); + e.rhs.welcome(this); + ex.write(")"); + return null; + } + @Override public Void visit(AdditionExpression e) { ex.write("("); @@ -121,7 +171,6 @@ public class PrettyPrintVisitor implements Visitor { return null; } - @Override public Void visit(NegateExpression e) { ex.write(" - "); diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java b/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java index 6b944d7..efe6b88 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java @@ -10,6 +10,11 @@ public interface Visitor { R visit(IntegerExpression e); R visit(Variable e); R visit(AdditionExpression e); + R visit(EqualityExpression e); + R visit(GTExpression e); + R visit(GTEExpression e); + R visit(LTExpression e); + R visit(LTEExpression e); R visit(SubstractionExpression e); R visit(MultiplicationExpression e); R visit(DivisionExpression e); From a79b7c936249968210bf4ce349ad1f47693bbd95 Mon Sep 17 00:00:00 2001 From: Marvin Kaiser Date: Fri, 20 Dec 2019 09:01:03 +0100 Subject: [PATCH 4/5] 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); From 079cdf4969d5a2a20db69e4d9984f850e28d7943 Mon Sep 17 00:00:00 2001 From: Marvin Kaiser Date: Fri, 20 Dec 2019 09:09:01 +0100 Subject: [PATCH 5/5] Implemented != expression --- .../antlr4/de/hsrm/compiler/Klang/Klang.g4 | 2 ++ .../hsrm/compiler/Klang/ContextAnalysis.java | 5 +++++ .../expressions/NotEqualityExpression.java | 14 +++++++++++++ .../compiler/Klang/visitors/EvalVisitor.java | 10 +++++++++ .../hsrm/compiler/Klang/visitors/GenASM.java | 21 +++++++++++++++++++ .../hsrm/compiler/Klang/visitors/GetVars.java | 7 +++++++ .../Klang/visitors/PrettyPrintVisitor.java | 10 +++++++++ .../hsrm/compiler/Klang/visitors/Visitor.java | 1 + src/test/comparison/comparison.c | 5 +++++ src/test/comparison/comparison.h | 1 + src/test/tests.k | 4 ++++ 11 files changed, 80 insertions(+) create mode 100644 src/main/java/de/hsrm/compiler/Klang/nodes/expressions/NotEqualityExpression.java diff --git a/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 b/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 index e3fdc45..70d0655 100644 --- a/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 +++ b/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 @@ -56,6 +56,7 @@ expression | 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 @@ -93,6 +94,7 @@ CPAR: ')'; COMMA: ','; EQUAL: '='; EQEQ: '=='; +NEQ: '!='; LT: '<'; GT: '>'; LTE: '<='; diff --git a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java index 2ee65fa..6ee3244 100644 --- a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java +++ b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java @@ -102,6 +102,11 @@ public class ContextAnalysis extends KlangBaseVisitor { return new EqualityExpression((Expression) this.visit(ctx.lhs), (Expression) this.visit(ctx.rhs)); } + @Override + public Node visitNotEqualityExpression(KlangParser.NotEqualityExpressionContext ctx) { + return new NotEqualityExpression((Expression) this.visit(ctx.lhs), (Expression) this.visit(ctx.rhs)); + } + @Override public Node visitLessThanExpression(KlangParser.LessThanExpressionContext ctx) { return new LTExpression((Expression) this.visit(ctx.lhs), (Expression) this.visit(ctx.rhs)); diff --git a/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/NotEqualityExpression.java b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/NotEqualityExpression.java new file mode 100644 index 0000000..0489729 --- /dev/null +++ b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/NotEqualityExpression.java @@ -0,0 +1,14 @@ +package de.hsrm.compiler.Klang.nodes.expressions; + +import de.hsrm.compiler.Klang.visitors.Visitor; + +public class NotEqualityExpression extends BinaryExpression { + public NotEqualityExpression(Expression lhs, Expression rhs) { + super(lhs, rhs); + } + + @Override + public R welcome(Visitor v) { + return v.visit(this); + } +} \ No newline at end of file diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java b/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java index 778a3d4..7caad2e 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java @@ -30,6 +30,16 @@ public class EvalVisitor implements Visitor { return new Value(0); } + @Override + public Value visit(NotEqualityExpression e) { + Value lhs = e.lhs.welcome(this); + Value rhs = e.rhs.welcome(this); + if (lhs.asInteger() != rhs.asInteger()) { + return new Value(1); + } + return new Value(0); + } + @Override public Value visit(GTExpression e) { Value lhs = e.lhs.welcome(this); 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 fc561a2..93f40d2 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java @@ -95,6 +95,27 @@ public class GenASM implements Visitor { return null; } + @Override + public Void visit(NotEqualityExpression 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(" jne .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; 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 d7e71b8..dfb99fa 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java @@ -31,6 +31,13 @@ class GetVars implements Visitor { return null; } + @Override + public Void visit(NotEqualityExpression e) { + e.lhs.welcome(this); + e.rhs.welcome(this); + return null; + } + @Override public Void visit(GTExpression e) { e.lhs.welcome(this); diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java b/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java index 4f96be1..b09ff34 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java @@ -80,6 +80,16 @@ public class PrettyPrintVisitor implements Visitor { ex.write(")"); return null; } + + @Override + public Void visit(NotEqualityExpression e) { + ex.write("("); + e.lhs.welcome(this); + ex.write(" != "); + e.rhs.welcome(this); + ex.write(")"); + return null; + } @Override public Void visit(GTExpression e) { diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java b/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java index efe6b88..c838b9f 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java @@ -11,6 +11,7 @@ public interface Visitor { R visit(Variable e); R visit(AdditionExpression e); R visit(EqualityExpression e); + R visit(NotEqualityExpression e); R visit(GTExpression e); R visit(GTEExpression e); R visit(LTExpression e); diff --git a/src/test/comparison/comparison.c b/src/test/comparison/comparison.c index 80ebba4..b450b72 100644 --- a/src/test/comparison/comparison.c +++ b/src/test/comparison/comparison.c @@ -27,6 +27,11 @@ int runComparisonTests() { failed += comparisonTest("==", 0, 1, 0, eq(0, 1)); failed += comparisonTest("==", 0, 0, 1, eq(0, 0)); + failed += comparisonTest("!=", 1, 1, 0, neq(1, 1)); + failed += comparisonTest("!=", 1, 0, 1, neq(1, 0)); + failed += comparisonTest("!=", 0, 1, 1, neq(0, 1)); + failed += comparisonTest("!=", 0, 0, 0, neq(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)); diff --git a/src/test/comparison/comparison.h b/src/test/comparison/comparison.h index 420ce10..9d4b35a 100644 --- a/src/test/comparison/comparison.h +++ b/src/test/comparison/comparison.h @@ -1,4 +1,5 @@ int eq(int x, int y); +int neq(int x, int y); int lt(int x, int y); int lte(int x, int y); int gt(int x, int y); diff --git a/src/test/tests.k b/src/test/tests.k index eabd5d6..32b21d3 100644 --- a/src/test/tests.k +++ b/src/test/tests.k @@ -113,6 +113,10 @@ function eq(x, y) { return (x == y); } +function neq(x, y) { + return (x != y); +} + function lt(x, y) { return (x < y); }