/**
  * Die Methode generiert den Assembler-Code für diesen Ausdruck. Sie geht davon aus, dass die
  * Kontextanalyse vorher erfolgreich abgeschlossen wurde.
  *
  * @param code Der Strom, in den die Ausgabe erfolgt.
  */
 void generateCode(CodeStream code) {
   String lookupLabel = code.nextLabel();
   code.println("; NEW " + newType.name);
   code.println("ADD R2, R1");
   /** BEGIN Aufgabe (j): Garbage Collector */
   // code.println("MMR (R2), R4 ; Referenz auf neues Objekt auf den Stapel legen");
   // code.println("MRI R6, _free ; Adresse von _free holen");
   // code.println("MRM R6, (R6) ; Referenz auf neues Objekt aus _free holen");
   // code.println("MMR (R2), R6 ; Referenz auf neues Objekt auf den Stapel legen");
   code.println("MRI R5, " + lookupLabel);
   code.println("MMR (R2), R5; Ruecksprungadresse");
   code.println("MRI R5, " + ((ClassDeclaration) newType.declaration).objectSize);
   code.println("ADD R2, R1");
   code.println("MMR (R2), R5; Objektgroesse");
   code.println("MRI R0, _lookup; Rufe _lookup Methode auf");
   code.println(lookupLabel + ":");
   code.println("MRM R6, (R2); freie Stelle vom Stack nehmen");
   /** BEGIN Aufgabe (i): Vererbung */
   code.println("MRI R5, " + ((ClassDeclaration) newType.declaration).identifier.name);
   // code.println("MMR (R4), R5 ; Referenz auf die VMT des Objects");
   code.println("MMR (R6), R5 ; Referenz auf die VMT des Objects");
   /** END Aufgabe (i) */
   // code.println("MRI R5, " + ((ClassDeclaration) newType.declaration).objectSize);
   // code.println("ADD R4, R5 ; Heap weiter zählen");
   // code.println("ADD R6, R5 ; Heap weiter zählen");
   /** BEGIN Aufgabe (j): Garbage Collector */
   code.println("ADD R6, R1 ; Heap weiter zählen");
   code.println("MRI R5, 0 ; NULL Pointer ");
   for (int i = 0; i < ((ClassDeclaration) newType.declaration).objectSize - 1; i++) {
     code.println("MMR (R6), R5 ; Attribut " + i + " nullen");
     code.println("ADD R6, R1 ; Heap weiter zaehlen");
   }
   /** END Aufgabe (j) */
   code.println("MRI R5, _free ; Adresse von _free holen");
   code.println("MMR (R5), R6 ; neuen Heap Pointer in _free ablegen");
   /** END Aufgabe (j) */
 }
Exemple #2
0
 /**
  * Die Methode generiert den Assembler-Code für diesen Ausdruck. Sie geht davon aus, dass die
  * Kontextanalyse vorher erfolgreich abgeschlossen wurde.
  *
  * @param code Der Strom, in den die Ausgabe erfolgt.
  */
 void generateCode(CodeStream code) {
   if (identifier.declaration instanceof VarDeclaration) {
     VarDeclaration v = (VarDeclaration) identifier.declaration;
     if (v.isAttribute) {
       code.println("; Referenz auf Attribut " + identifier.name);
       code.println("MRM R5, (R2)");
       code.println("MRI R6, " + v.offset);
       code.println("ADD R5, R6");
       code.println("MMR (R2), R5");
     } else {
       code.println("; Referenz auf Variable " + identifier.name);
       code.println("MRI R5, " + v.offset);
       code.println("ADD R5, R3");
       code.println("ADD R2, R1");
       code.println("MMR (R2), R5");
     }
   } else if (identifier.declaration instanceof MethodDeclaration) {
     MethodDeclaration m = (MethodDeclaration) identifier.declaration;
     /** BEGIN Aufgabe (f): Methoden Parameter */
     code.println("; CALL " + m.self.type.name + "." + m.identifier.name);
     /** BEGIN Aufgabe (j): Garbage Collector */
     code.println("MRM R5, (R2) ; SELF von R2 nehmen");
     code.println("SUB R2, R1");
     code.println("ADD R4, R1");
     code.println("MMR (R4), R5 ; SELF auf R4 legen");
     /** END Aufgabe (j) */
     if (!params.isEmpty()) {
       for (int i = 0; i < params.size(); i++) {
         Expression p = params.get(i);
         code.println("; Parameter " + i + ":");
         p.generateCode(code);
         /** BEGIN Aufgabe (j): Garbage Collector */
         code.println("MRM R5, (R2) ; Parameter " + i + " von R2 nehmen");
         code.println("SUB R2, R1");
         code.println("ADD R4, R1");
         code.println("MMR (R4), R5 ; Parameter " + i + " auf R4 legen");
         /** END Aufgabe (j) */
       }
     }
     /** END Aufgabe (f) */
     String returnLabel = code.nextLabel();
     code.println("MRI R5, " + returnLabel);
     code.println("ADD R2, R1");
     code.println("MMR (R2), R5 ; Rücksprungadresse auf den Stapel");
     /** BEGIN Aufgabe (i): Vererbung */
     if (dynamicBind) {
       // dynamisches Binden
       code.println("; Dynamischer Aufruf von " + identifier.name);
       code.println("MRI R5, " + (m.self.offset + 1));
       /** BEGIN Aufgabe (j): Garbage Collector */
       // code.println("ADD R5, R2 ");
       code.println("ADD R5, R4 ");
       /** END Aufgabe (j) */
       code.println("MRM R5, (R5) ; Adresse von SELF auf dem Heap ");
       code.println("MRM R5, (R5) ; VMT Referenz ");
       code.println("MRI R6, " + m.index + " ; Methodenoffset");
       code.println("ADD R5, R6 ; Methodenoffset anwenden");
       code.println("MRM R5, (R5) ; Methodenadresse holen ");
       code.println("MRR R0, R5 ; Sprung zu " + m.identifier.name);
     } else {
       code.println("; Statischer Aufruf von " + identifier.name);
       code.println("MRI R0, " + m.self.type.name + "_" + m.identifier.name);
     }
     /** END Aufgabe (i) */
     // code.println("; Statischer Aufruf von " + identifier.name);
     // code.println("MRI R0, " + m.self.type.name + "_" + m.identifier.name);
     code.println(returnLabel + ":");
   } else {
     assert false;
   }
 }