implement visitors for boolean expressions

This commit is contained in:
2020-01-20 19:32:50 +01:00
parent 722a9babcb
commit 295bcaec8a
4 changed files with 164 additions and 0 deletions

View File

@@ -129,6 +129,26 @@ public class EvalVisitor implements Visitor<Value> {
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);

View File

@@ -278,6 +278,103 @@ public class GenASM implements Visitor<Void> {
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;

View File

@@ -115,6 +115,26 @@ class GetVars implements Visitor<Void> {
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);

View File

@@ -195,6 +195,33 @@ public class PrettyPrintVisitor implements Visitor<Void> {
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 (");