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());
|
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
|
@Override
|
||||||
public Value visit(Variable e) {
|
public Value visit(Variable e) {
|
||||||
Value result = this.env.get(e.name);
|
Value result = this.env.get(e.name);
|
||||||
|
|||||||
@@ -278,6 +278,103 @@ public class GenASM implements Visitor<Void> {
|
|||||||
return null;
|
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
|
@Override
|
||||||
public Void visit(IfStatement e) {
|
public Void visit(IfStatement e) {
|
||||||
int lblElse = ++lCount;
|
int lblElse = ++lCount;
|
||||||
|
|||||||
@@ -115,6 +115,26 @@ class GetVars implements Visitor<Void> {
|
|||||||
return null;
|
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
|
@Override
|
||||||
public Void visit(IfStatement e) {
|
public Void visit(IfStatement e) {
|
||||||
e.cond.welcome(this);
|
e.cond.welcome(this);
|
||||||
|
|||||||
@@ -195,6 +195,33 @@ public class PrettyPrintVisitor implements Visitor<Void> {
|
|||||||
return null;
|
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
|
@Override
|
||||||
public Void visit(IfStatement e) {
|
public Void visit(IfStatement e) {
|
||||||
ex.write("if (");
|
ex.write("if (");
|
||||||
|
|||||||
Reference in New Issue
Block a user