Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package visitor;
- import java.io.PrintWriter;
- import absyn.*;
- import table.*;
- import types.ArrayType;
- import types.ParamTypeList;
- import types.PrimitiveType;
- import types.Type;
- import codegen.*;
- public class CodegenVisitor extends DoNothingVisitor {
- int nextReg;
- Table symTab;
- int label;
- static PrintWriter outWriter;
- int newLabel = 0;
- private final int LASTREG = 23;
- boolean paramRef = false;
- public CodegenVisitor(int reg, Table t, PrintWriter ow) {
- nextReg = reg;
- symTab = t;
- outWriter = ow;
- }
- CodegenVisitor(int reg, Table t, int Label) {
- this(reg, t, outWriter);
- this.label = Label;
- }
- public CodegenVisitor() {
- }
- public CodegenVisitor(int i, Table symTab2, PrintWriter ow, int label) {
- nextReg = i;
- symTab = symTab2;
- outWriter = ow;
- this.label = label;
- }
- @Override
- public void visit(ArrayTy arrayTy) {
- regCheck(nextReg);
- // TODO regcheck
- outWriter.format("; ArrayTy \n");
- }
- @Override
- public void visit(ArrayVar arrayVar) {
- regCheck(nextReg + 2);
- arrayVar.var.accept(this);
- SimpleVar sVar = (SimpleVar) varNameFinden(arrayVar.var);
- VarEntry vEnt = (VarEntry) symTab.lookup(sVar.name);
- arrayVar.index.accept(new CodegenVisitor(nextReg + 1, symTab,
- outWriter, label));
- ArrayType aType = (ArrayType) vEnt.type;
- emitrrs("add", nextReg + 2, 0, aType.size,
- " ArrayVar: Arraygroeße in Reg. " + (nextReg + 2)
- + " schreiben.");
- emitrrb("bgeu", nextReg + 1, nextReg + 2, "_indexError",
- " ArrayVar: Indexcheck. ");
- emitrrs("mul", nextReg + 1, nextReg + 1, 4,
- " ArrayVar: Index mit 4 multiplizieren und in " + (nextReg + 1)
- + " schreiben.");
- emitrrr("add", nextReg, nextReg, nextReg + 1,
- " ArrayVar: Schreibt korrekte Adresse des Elements in Reg."
- + nextReg);
- }
- @Override
- public void visit(AssignStm assignStm) {
- regCheck(nextReg + 1);
- assignStm.var.accept(this);
- assignStm.exp.accept(new CodegenVisitor(nextReg + 1, symTab, outWriter,
- label));
- emitrrs("stw", nextReg + 1, nextReg, 0,
- "AssignStm: Schreiben des Wertes aus " + (nextReg + 1)
- + " in Register " + nextReg);
- nextReg--;
- }
- @Override
- public void visit(CallStm callStm) {
- regCheck(nextReg);
- ProcEntry pEnt = (ProcEntry) symTab.lookup(callStm.name);
- ExpList expList = callStm.args;
- int counter = 0;
- ParamTypeList paramTypes = pEnt.paramTypes;
- while (expList.isEmpty == false) {
- if (paramTypes.isRef == true) {
- paramRef = true;
- }
- expList.head.accept(this);
- paramRef = false;
- emitrrs("stw", nextReg, 29, counter, " : Arguemnt Nr. " + counter
- / 4 + " eintragen");
- counter = counter + 4;
- expList = expList.tail;
- paramTypes = paramTypes.next;
- }
- outWriter.format("jal " + callStm.name.toString() + "\n");
- }
- @Override
- public void visit(CompStm compStm) {
- regCheck(nextReg);
- compStm.stms.accept(this);
- }
- @Override
- public void visit(DecList decList) {
- regCheck(nextReg);
- decList.head.accept(this);
- if (decList.tail.isEmpty == false) {
- decList.tail.accept(this);
- }
- }
- @Override
- public void visit(EmptyStm emptyStm) {
- regCheck(nextReg);
- outWriter.format("; EmptyStm \n");
- }
- @Override
- public void visit(ExpList expList) {
- regCheck(nextReg + 1);
- if (expList.head != null) {
- expList.head.accept(this);
- }
- if (expList.tail != null) {
- expList.tail.accept(new CodegenVisitor(nextReg + 1, symTab,
- outWriter, label));
- }
- }
- @Override
- public void visit(IfStm ifStm) {
- regCheck(nextReg + 1);
- if (ifStm.elsePart instanceof EmptyStm) {
- ifStm.test.accept(this);
- OpExp opExp = (OpExp) ifStm.test;
- switch (opExp.op) {
- case OpExp.EQU:
- emitrrb("bne", nextReg, nextReg + 1, "L" + label,
- "OpExp: gleich");
- break;
- case OpExp.LST:
- emitrrb("bge", nextReg, nextReg + 1, "L" + label,
- "OpExp: kleiner");
- break;
- case OpExp.LSE:
- emitrrb("bgt", nextReg, nextReg + 1, "L" + label,
- "OpExp: kleiner-gleich");
- break;
- case OpExp.GRT:
- emitrrb("ble", nextReg, nextReg + 1, "L" + label,
- "OpExp: größer");
- break;
- case OpExp.GRE:
- emitrrb("blt", nextReg, nextReg + 1, "L" + label,
- "OpExp: größer-gleich");
- break;
- case OpExp.NEQ:
- emitrrb("beq", nextReg, nextReg + 1, "L" + label,
- "OpExp: größer-gleich");
- break;
- }
- ifStm.thenPart.accept(this);
- outWriter.format("L" + label++ + ": \n");
- }
- else {
- ifStm.test.accept(this);
- OpExp opExp = (OpExp) ifStm.test;
- switch (opExp.op) {
- case OpExp.EQU:
- emitrrb("bne", nextReg, nextReg + 1, emitLabel(),
- "OpExp: gleich");
- break;
- case OpExp.LST:
- emitrrb("bge", nextReg, nextReg + 1, emitLabel(),
- "OpExp: kleiner");
- break;
- case OpExp.LSE:
- emitrrb("bgt", nextReg, nextReg + 1, emitLabel(),
- "OpExp: kleiner-gleich");
- break;
- case OpExp.GRT:
- emitrrb("ble", nextReg, nextReg + 1, emitLabel(),
- "OpExp: größer");
- break;
- case OpExp.GRE:
- emitrrb("blt", nextReg, nextReg + 1, emitLabel(),
- "OpExp: größer-gleich");
- break;
- case OpExp.NEQ:
- emitrrb("beq", nextReg, nextReg + 1, emitLabel(),
- "OpExp: größer-gleich");
- break;
- }
- ifStm.thenPart.accept(this);
- emitJump("L" + (label + 1));
- outWriter.format("L" + label + ": \n");
- ifStm.elsePart.accept(new CodegenVisitor(nextReg + 1, symTab,
- outWriter, label));
- outWriter.format("L" + (label + 1) + ": \n");
- }
- }
- @Override
- public void visit(IntExp intExp) {
- regCheck(nextReg);
- emitrrs("add", nextReg, 0, intExp.val, " IntExp : " + intExp.val);
- }
- @Override
- public void visit(NameTy nameTy) {
- regCheck(nextReg);
- outWriter.format("; NameTy \n");
- }
- @Override
- public void visit(OpExp opExp) {
- regCheck(nextReg + 1);
- opExp.left.accept(this);
- opExp.right.accept(new CodegenVisitor(nextReg + 1, symTab, outWriter,
- label));
- switch (opExp.op) {
- case OpExp.ADD:
- emitrrr("add", nextReg, nextReg, nextReg + 1, "OpExp: add");
- break;
- case OpExp.SUB:
- emitrrr("sub", nextReg, nextReg, nextReg + 1, "OpExp: sub");
- break;
- case OpExp.MUL:
- emitrrr("mul", nextReg, nextReg, nextReg + 1, "OpExp: mul");
- break;
- case OpExp.DIV:
- emitrrr("div", nextReg, nextReg, nextReg + 1, "OpExp: div");
- break;
- case OpExp.EQU:
- // emitrrr("equ", nextReg, nextReg, nextReg + 1, "OpExp: gleich");
- break;
- case OpExp.LST:
- // emitrrr("equ", nextReg, nextReg, nextReg + 1, "OpExp: kleiner");
- break;
- case OpExp.LSE:
- // emitrrr("equ", nextReg, nextReg, nextReg + 1,
- // "OpExp: kleiner-gleich");
- break;
- case OpExp.GRT:
- // emitrrr("equ", nextReg, nextReg, nextReg + 1, "OpExp: größer");
- break;
- case OpExp.GRE:
- // emitrrr("equ", nextReg, nextReg, nextReg + 1,
- // "OpExp: größer-gleich");
- break;
- case OpExp.NEQ:
- // emitrrr("equ", nextReg, nextReg, nextReg + 1, "OpExp: ungleich");
- break;
- }
- }
- @Override
- public void visit(ParDec parDec) {
- regCheck(nextReg);
- outWriter.format("; ParDec \n");
- }
- @Override
- public void visit(ProcDec procDec) {
- regCheck(nextReg);
- ProcEntry pE = (ProcEntry) symTab.lookup(procDec.name);
- Table lokTab = pE.localTable;
- int aufruf = 0;
- // Wenn Rücksprungadresse gespeichert werden muss, dann Platz für RA
- // speichern:
- if (pE.ruftAuf == true) {
- aufruf = 4;
- }
- outWriter.format(procDec.name.toString() + ":\n");
- // Prolog:
- emitrrs("sub", 29, 29, pE.groeßeLokVars + 4 + aufruf
- + pE.groeßeAusgehenderBereich, " Prolog: Frame aufbauen");
- // TODO pE.groeßeLokVars+4 korrekt?
- emitrrs("stw", 25, 29, aufruf + pE.groeßeAusgehenderBereich,
- " Prolog: Framepointer sichern");
- emitrrs("add", 25, 29, pE.groeßeLokVars + 4 + aufruf
- + pE.groeßeAusgehenderBereich,
- " Prolog: Framepointer neu setzen");
- if (aufruf != 0) {
- emitrrs("stw", 31, 25,
- // -(pE.groeßeLokVars + aufruf + pE.groeßeAusgehenderBereich),
- -(pE.groeßeLokVars + 8), " Prolog: RA speichern");
- }
- // Prolog Ende
- if (procDec.body.isEmpty != true) {
- procDec.body.accept(new CodegenVisitor(nextReg, lokTab, outWriter,
- label));
- }
- // Epilog:
- if (aufruf != 0) {
- emitrrs("ldw", 31, 25, -(pE.groeßeLokVars + 8),
- " Prolog: RA wiederherstellen");
- }
- emitrrs("ldw", 25, 29, aufruf + pE.groeßeAusgehenderBereich,
- " Epilog: Alten Framepointer wieder herstellen");
- emitrrs("add", 29, 29, pE.groeßeLokVars + 4 + aufruf
- + pE.groeßeAusgehenderBereich, " Epilog: Frame abbauen");
- outWriter.format("jr $31 ; return zur Rücksprungadresse \n");
- }
- @Override
- public void visit(SimpleVar simpleVar) {
- regCheck(nextReg);
- VarEntry vEnt = (VarEntry) symTab.lookup(simpleVar.name);
- int offset = -vEnt.offsetSize;
- emitrrs("add", nextReg, 25, offset, " SimpleVar: " + simpleVar.name);
- }
- @Override
- public void visit(StmList stmList) {
- regCheck(nextReg + 1);
- stmList.head.accept(this);
- if (stmList.tail.isEmpty == false) {
- stmList.tail.accept(new CodegenVisitor(nextReg + 1, symTab,
- outWriter, label));
- }
- }
- @Override
- public void visit(TypeDec typeDec) {
- regCheck(nextReg);
- }
- @Override
- public void visit(VarDec varDec) {
- regCheck(nextReg);
- outWriter.format("; VarDec \n");
- }
- @Override
- public void visit(VarExp varExp) {
- regCheck(nextReg);
- varExp.var.accept(this);
- SimpleVar sVar = (SimpleVar) varNameFinden(varExp.var);
- if (paramRef == false) {
- emitrrs("ldw", nextReg, nextReg, 0,
- "VarExp: Ablegen des Wertes an Adresse " + nextReg);
- }
- }
- @Override
- public void visit(WhileStm whileStm) {
- regCheck(nextReg + 2);
- outWriter.format("L" + label++);
- whileStm.test.accept(this);
- OpExp opExp = (OpExp) whileStm.test;
- switch (opExp.op) {
- case OpExp.EQU:
- emitrrb("bne", nextReg, nextReg + 1, "L" + label, "OpExp: gleich");
- break;
- case OpExp.LST:
- emitrrb("bge", nextReg, nextReg + 1, "L" + label, "OpExp: kleiner");
- break;
- case OpExp.LSE:
- emitrrb("bgt", nextReg, nextReg + 1, "L" + label,
- "OpExp: kleiner-gleich");
- break;
- case OpExp.GRT:
- emitrrb("ble", nextReg, nextReg + 1, "L" + label, "OpExp: größer");
- break;
- case OpExp.GRE:
- emitrrb("blt", nextReg, nextReg + 1, "L" + label,
- "OpExp: größer-gleich");
- break;
- case OpExp.NEQ:
- emitrrb("beq", nextReg, nextReg + 1, "L" + label,
- "OpExp: größer-gleich");
- break;
- }
- whileStm.body.accept(this);
- emitJump("J" + (label - 1));
- }
- private void emitrrs(String string, int nextReg2, int nextReg3, int i,
- String string2) {
- outWriter.format(string + " $" + nextReg2 + ",$" + nextReg3 + "," + i
- + " ; " + string2 + " \n");
- }
- private void emitrrr(String string, int nextReg2, int nextReg3,
- int nextReg4, String string2) {
- outWriter.format(string + " $" + nextReg2 + ",$" + nextReg3 + ",$"
- + nextReg4 + " ; " + string2 + " \n");
- }
- private void emitrrb(String string, int nextReg2, int nextReg3,
- String string2, String string3) {
- outWriter.format(string + " $" + nextReg2 + ",$" + nextReg3 + ","
- + string2 + " ; " + string3 + " \n");
- }
- private Var varNameFinden(Var var) {
- SimpleVar sVar;
- ArrayVar aVar;
- if (var instanceof ArrayVar) {
- aVar = (ArrayVar) var;
- return varNameFinden(aVar.var);
- }
- if (var instanceof SimpleVar) {
- sVar = (SimpleVar) var;
- return sVar;
- }
- return null;
- }
- private void regCheck(int reg) {
- try {
- if (reg > LASTREG) {
- throw new Exception("Register: FULL");
- }
- } catch (Exception e) {
- }
- }
- private int nextLabel() {
- return newLabel++;
- }
- private String emitLabel() {
- return "L" + nextLabel();
- }
- private void emitJump(String string) {
- outWriter.format("j " + string + " \n");
- }
- }
Add Comment
Please, Sign In to add comment