From 079cdf4969d5a2a20db69e4d9984f850e28d7943 Mon Sep 17 00:00:00 2001 From: Marvin Kaiser Date: Fri, 20 Dec 2019 09:09:01 +0100 Subject: [PATCH] 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); }