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 c34fea5..7151a76 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java @@ -129,6 +129,26 @@ public class EvalVisitor implements Visitor { return new Value(-a.asInteger()); } + @Override + public Value visit(OrExpression e) { + Value lhs = e.lhs.welcome(this); + Value rhs = e.rhs.welcome(this); + return new Value(lhs.asBoolean() || rhs.asBoolean()); + } + + @Override + public Value visit(AndExpression e) { + Value lhs = e.lhs.welcome(this); + Value rhs = e.rhs.welcome(this); + return new Value(lhs.asBoolean() && rhs.asBoolean()); + } + + @Override + public Value visit(NotExpression e) { + Value lhs = e.lhs.welcome(this); + return new Value(!lhs.asBoolean()); + } + @Override public Value visit(Variable e) { Value result = this.env.get(e.name); 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 6a69845..8dcc6e0 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java @@ -278,6 +278,103 @@ public class GenASM implements Visitor { return null; } + @Override + public Void visit(OrExpression e) { + int lblTrue = ++lCount; + int lblFalse = ++lCount; + int lblEnd = ++lCount; + + // Werte LHS aus + // Wenn LHS != 0 bedeutet das true + // also können wir direkt sagen dass das Ergebnis true ist + e.lhs.welcome(this); + this.ex.write(" cmpq $0, %rax\n"); + this.ex.write(" jne .L" + lblTrue + "\n"); + + // LHS war false, also werte RHS aus + // Wenn RHS == 0 bedeutet das false, + // also ist das Gesamtergebnis false + e.rhs.welcome(this); + this.ex.write(" cmpq $0, %rax\n"); + this.ex.write(" je .L" + lblFalse + "\n"); + + // Die Expression wertet zu true aus + // Springe am false Teil vorbei + this.ex.write(".L" + lblTrue + ":\n"); + this.ex.write(" movq $1, %rax\n"); + this.ex.write(" jmp .L" + lblEnd + "\n"); + + // Die Expressoin wertet zu false aus + this.ex.write(".L" + lblFalse + ":\n"); + this.ex.write(" movq $0, %rax\n"); + + // Das hier ist das ende + this.ex.write(".L" + lblEnd + ":\n"); + return null; + } + + @Override + public Void visit(AndExpression e) { + int lblTrue = ++lCount; + int lblFalse = ++lCount; + int lblEnd = ++lCount; + + // Werte LHS aus + // Wenn LHS == 0, bedeutet das false + // also können wir direkt sagen dass das Ergebnis false ist + e.lhs.welcome(this); + this.ex.write(" cmpq $0, %rax\n"); + this.ex.write(" je .L" + lblFalse + "\n"); + + // LHS war true, also werte RHS aus. + // Wenn RHS == 0, bedeutet das false + // also ist das Gesamtergebnis false + e.rhs.welcome(this); + this.ex.write(" cmpq $0, %rax\n"); + this.ex.write(" je .L" + lblFalse +"\n"); + + // Die Expression wertet zu true aus + // Springe am false Teil vorbei + this.ex.write(".L" + lblTrue +":\n"); + this.ex.write(" movq $1, %rax\n"); + this.ex.write(" jmp .L" + lblEnd + "\n"); + + // Die Expressoin wertet zu false aus + this.ex.write(".L" + lblFalse +":\n"); + this.ex.write(" movq $0, %rax\n"); + + // Das hier ist das ende + this.ex.write(".L" + lblEnd +":\n"); + return null; + } + + @Override + public Void visit(NotExpression e) { + int lblFalse = ++lCount; + int lblEnd = ++lCount; + + // Werte LHS aus + // Wenn LHS != 0 bedeutet das true, also jumpe zum false Teil + // Wenn nicht, falle durch zum true Teil + e.lhs.welcome(this); + this.ex.write(" cmpq $0, %rax\n"); + this.ex.write(" jne .L" +lblFalse +"\n"); + + // Hier ist das Ergebnis true + // Springe am false Teil vorbei + this.ex.write(" movq $1, %rax\n"); + this.ex.write(" jmp .L" +lblEnd +"\n"); + + // Hier ist das Ergebnis false + // Falle zum Ende durch + this.ex.write(".L" +lblFalse + ":\n"); + this.ex.write("movq $0, %rax\n"); + + // Hier ist das Ende + this.ex.write(".L" +lblEnd + ":\n"); + return null; + } + @Override public Void visit(IfStatement e) { int lblElse = ++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 8a6fa14..0d55d41 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java @@ -115,6 +115,26 @@ class GetVars implements Visitor { return null; } + @Override + public Void visit(OrExpression e) { + e.lhs.welcome(this); + e.rhs.welcome(this); + return null; + } + + @Override + public Void visit(AndExpression e) { + e.lhs.welcome(this); + e.rhs.welcome(this); + return null; + } + + @Override + public Void visit(NotExpression e) { + e.lhs.welcome(this); + return null; + } + @Override public Void visit(IfStatement e) { e.cond.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 ae1f364..0b35907 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java @@ -195,6 +195,33 @@ public class PrettyPrintVisitor implements Visitor { return null; } + @Override + public Void visit(OrExpression e) { + ex.write("("); + e.lhs.welcome(this); + ex.write(" || "); + e.rhs.welcome(this); + ex.write(")"); + return null; + } + + @Override + public Void visit(AndExpression e) { + ex.write("("); + e.lhs.welcome(this); + ex.write(" && "); + e.rhs.welcome(this); + ex.write(")"); + return null; + } + + @Override + public Void visit(NotExpression e) { + ex.write("!"); + e.lhs.welcome(this); + return null; + } + @Override public Void visit(IfStatement e) { ex.write("if (");