implement visitors
This commit is contained in:
@@ -527,4 +527,21 @@ public class EvalVisitor implements Visitor<Value> {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(FieldAssignment e) {
|
||||
Value val = this.env.get(e.varName);
|
||||
String fieldNameToUpdate = e.path[e.path.length - 1];
|
||||
|
||||
// Find the struct that holds the field to be updated
|
||||
Map<String, Value> struct = val.asStruct();
|
||||
for (int i = 0; i < e.path.length - 1; i++) {
|
||||
struct = struct.get(e.path[i]).asStruct();
|
||||
}
|
||||
|
||||
// if we are here, struct contains a reference to the struct that holds the field to be updated
|
||||
struct.put(fieldNameToUpdate, e.expression.welcome(this));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -865,4 +865,31 @@ public class GenASM implements Visitor<Void> {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(FieldAssignment e) {
|
||||
var structDef = this.structs.get(e.structName);
|
||||
int offset = this.env.get(e.varName);
|
||||
String fieldNameToUpdate = e.path[e.path.length - 1];
|
||||
|
||||
// Push the expression onto the stack
|
||||
e.expression.welcome(this);
|
||||
this.ex.write(" pushq %rax\n");
|
||||
|
||||
// move struct address into rax
|
||||
this.ex.write(" movq " + offset + "(%rbp), %rax\n");
|
||||
|
||||
// If there are at least two elements in the path,
|
||||
// move the address of the next referenced struct into rax
|
||||
for (int i = 0; i < e.path.length - 1; i++) {
|
||||
structDef = this.structs.get(structDef.fields[Helper.getFieldIndex(structDef, e.path[i])].type.getName());
|
||||
this.ex.write(" movq " + Helper.getFieldOffset(structDef, e.path[i]) + "(%rax), %rax\n");
|
||||
}
|
||||
|
||||
// pop the expression that is ontop of the stack into the field of the struct that has to be updated
|
||||
this.ex.write(" popq " + Helper.getFieldOffset(structDef, fieldNameToUpdate) + "(%rax)\n");
|
||||
this.ex.write(" movq $0, %rax\n"); // clear rax sind an assignment has no result
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -269,4 +269,9 @@ class GetVars implements Visitor<Void> {
|
||||
public Void visit(DestructorCall e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(FieldAssignment e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -444,4 +444,17 @@ public class PrettyPrintVisitor implements Visitor<Void> {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(FieldAssignment e) {
|
||||
ex.write(e.varName);
|
||||
for (int i = 0; i < e.path.length; i++) {
|
||||
ex.write(".");
|
||||
ex.write(e.path[i]);
|
||||
}
|
||||
ex.write(" = ");
|
||||
e.expression.welcome(this);
|
||||
ex.write(";");
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -49,4 +49,5 @@ public interface Visitor<R> {
|
||||
R visit(ConstructorCall e);
|
||||
R visit(NullExpression e);
|
||||
R visit(DestructorCall e);
|
||||
R visit(FieldAssignment e);
|
||||
}
|
||||
Reference in New Issue
Block a user