implement visitors
This commit is contained in:
@@ -527,4 +527,21 @@ public class EvalVisitor implements Visitor<Value> {
|
|||||||
return null;
|
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;
|
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) {
|
public Void visit(DestructorCall e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(FieldAssignment e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -444,4 +444,17 @@ public class PrettyPrintVisitor implements Visitor<Void> {
|
|||||||
return null;
|
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(ConstructorCall e);
|
||||||
R visit(NullExpression e);
|
R visit(NullExpression e);
|
||||||
R visit(DestructorCall e);
|
R visit(DestructorCall e);
|
||||||
|
R visit(FieldAssignment e);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user