implement visitors

This commit is contained in:
2020-03-07 00:14:31 +01:00
parent 32cb06cd51
commit 02666a9459
5 changed files with 63 additions and 0 deletions

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -269,4 +269,9 @@ class GetVars implements Visitor<Void> {
public Void visit(DestructorCall e) {
return null;
}
@Override
public Void visit(FieldAssignment e) {
return null;
}
}

View File

@@ -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;
}
}

View File

@@ -49,4 +49,5 @@ public interface Visitor<R> {
R visit(ConstructorCall e);
R visit(NullExpression e);
R visit(DestructorCall e);
R visit(FieldAssignment e);
}