implement visitors for boolean expressions
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 (");
|
||||
|
||||
Reference in New Issue
Block a user