package visitor.codegeneration; import ast.Program; import ast.definition.Definition; import ast.definition.classes.FuncDefinition; import ast.definition.classes.VarDefinition; import ast.statement.Statement; import ast.type.RecordField; import ast.type.classes.FunctionType; import ast.type.classes.RecordType; import visitor.AbstractVisitor; public class OffsetVisitor extends AbstractVisitor<Void, Void> { @Override public Void visit(Program ast, Void param) { int globalBytesSum = 0; for (Definition def : ast.getDefinitions()) { if (def instanceof VarDefinition) { ((VarDefinition) def).setOffset(globalBytesSum); globalBytesSum += def.getType().numberOfBytes(); } } super.visit(ast, param); return null; } @Override public Void visit(FuncDefinition ast, Void param) { int sumOfBytes = 0; for (Statement localVar : ast.getFunctionStmts()) { if (localVar instanceof VarDefinition) { sumOfBytes += ((VarDefinition) localVar).getType().numberOfBytes(); ((VarDefinition) localVar).setOffset(-sumOfBytes); } } super.visit(ast, param); return null; } @Override public Void visit(FunctionType ast, Void param) { int sumOfBytes = 4; for (int i = ast.getParameters().size() - 1; i >= 0; i--) { ast.getParameters().get(i).setOffset(sumOfBytes); sumOfBytes += ast.getParameters().get(i).getType().numberOfBytes(); } super.visit(ast, param); return null; } @Override public Void visit(RecordType ast, Void param) { int sumOfBytes = 0; for (RecordField rf : ast.getFields()) { rf.setOffset(sumOfBytes); sumOfBytes += rf.getFieldType().numberOfBytes(); rf.accept(this, null); //pre-order traversal } super.visit(ast, param); return null; } }