/*
 * zusatzregister.java
 *
 * Created on 25. Dezember 2000
 */

/**
 * Matthias Mayer
 * Mail : matthias.mayer@student.uni-magdeburg.de
 * version 0.1 
 */
import algds.IOUtils;
public class zusatzregister {

    /* Alle Variablen werden hier global definiert, d.h. sie sind
     * auch in den allen Methoden sichtbar */

    static int b,reg,k,spanz,anzb;
    /* b     =  Befehlszähler
       reg   =  aktuelle Register im Hauptprogramm
       k     =  Hilfvariable für ifgoto-Befehl
       spanz =  Anzahl der Speicherregister 
       anzb  =  Anzahl der Befehle*/
              
    static int[] c = new int[32768]; //Feld der Register
    static String[]feldop = null; //Feld der Befehle
    static int[]feldreg = null; //Feld der Register
    static String operation;  //aktuelle Operation implements Hauptprogramm

    //Befehle als Methoden definiert

    // Ein- und Ausgabebefehle
    static void load (int i) {
        b = b + 1;
        c[0] = c[i];
    }
    static void cload (int i) {
        b = b + 1;
        c[0] = i;
    }
    static void store (int i) {
        b = b + 1;
        c[i] = c[0];
    }
    // Arithmetische Befehle
    static void add (int i) {
        b = b + 1;
        c[0] = c[0] + c[i];
    }
    static void cadd (int i) {
        b = b + 1;
        c[0] = c[0] + i;
    }
    static void sub (int i) {
        b = b + 1;
        if (c[0]>=c[i])
        c[0] = c[0] - c[i];
        else
        c[0] = 0;
    }
    static void csub (int i) {
        b = b + 1;
        if (c[0]>=i)
        c[0] = c[0] - i;
        else
    c[0] = 0;}
    static void mult (int i) {
        b = b + 1;
        c[0] = c[0] * c[i];
    }
    static void cmult (int i) {
        b = b + 1;
        c[0] = c[0] * i;
    }
    static void div (int i) {
        b = b + 1;
        c[0] = c[0] / c[i];
    }
    static void cdiv (int i) {
        b = b + 1;
        c[0] = c[0] / i;
    }
    // Sprungbefehle
    static void gotoi (int i) {
        b = i;
    }
    static void ifgoto (int i) {
        if (c[0]==0){
            b = i;
            k = i;
        }
        else b =  b + 1;
    }
    //Stoppbefehl
    public static void end (int i){
        b = b;
        System.out.print("Ergebnis : ");
    }
    // Konfiguration ausgeben
    public static void ausgabe(int spanz) {
        System.out.print("("+ b);
        for (int i=0; i<=spanz; i++)
        System.out.print(", " +c[i]);
        System.out.print(") ");
        System.out.println();
    }
    // Hauptprogramm
    public static void main(String args[]) {
        System.out.println("Registermaschinen-Programm");
        System.out.println();
        System.out.println("Ihre Befehle :");
        System.out.println(" load   - cload - store - add");
        System.out.println(" cadd   - sub   - csub  - mult");
        System.out.println(" cmult  - div   - cdiv  - goto");
        System.out.println(" ifgoto - end");
        System.out.println();
        System.out.println(" ifgoto ist der Befehl if c0=0 goto");
        System.out.println();
        System.out.println("BITTE so eingeben, das Program verzeiht keine Fehler !");
        System.out.println();
        // Einlesen der Anzahl der Befehle
        System.out.print("Wieviele Befehle : ");
        anzb=IOUtils.readInt();
        System.out.println(anzb);
        // Felder werden dementsprechend definiert
        String[] feldop = new String[anzb];
        int[] feldreg = new int[anzb];
        
        for(int j=1;j<=anzb;j++){
            System.out.print((j)+". Operation : ");
            String op=IOUtils.readString();
            System.out.print(op);
            feldop[j-1]=op;  //Operation kommt ins Feld Operation
            System.out.print("   "+(j)+". Register : ");
            int i=IOUtils.readInt();
            System.out.println(i);
            feldreg[j-1]=i; //Register kommt ins Feld Register
        }
        
        b=1; //Anfangswert Befehlszähler
        
        //Einlesen der Arbeits- und Speicherregister
        System.out.print("Anfangswert Arbeitsregister c0 : ");
        c[0]=IOUtils.readInt();
        System.out.println(c[0]);
        System.out.print("Wieviele Speicherregister wollen Sie mit Werten belegen : ");
        int spanz=IOUtils.readInt();
        System.out.println(spanz);
        for(int j=1;j<=spanz;j++){
            System.out.print("Anfangswert c"+j+" : ");
            c[j]=IOUtils.readInt();
        System.out.println(c[j]);}
        System.out.print("Anfang:   ");
        ausgabe(spanz);

        //Abarbeitung der Befehle
        for (int k=1;k<=anzb;k++){
            System.out.print(k+" "+feldop[k-1]+" ("+feldreg[k-1]+") -> ");
            operation=feldop[k-1];
            reg=feldreg[k-1];
            if(operation.compareTo("load")==0) load(reg);
            if(operation.compareTo("cload")==0) cload(reg);
            if(operation.compareTo("store")==0) store(reg);
            if(operation.compareTo("add")==0) add(reg);
            if(operation.compareTo("cadd")==0) cadd(reg);
            if(operation.compareTo("sub")==0) sub(reg);
            if(operation.compareTo("csub")==0) csub(reg);
            if(operation.compareTo("mult")==0) mult(reg);
            if(operation.compareTo("cmult")==0) cmult(reg);
            if(operation.compareTo("div")==0) div(reg);
            if(operation.compareTo("cdiv")==0) cdiv(reg);
            if(operation.compareTo("goto")==0) {
            gotoi(reg); k=reg-1;}
            if(operation.compareTo("ifgoto")==0) {
                ifgoto(reg);
            if (c[0]==0) k=reg-1;}
            if(operation.compareTo("end")==0) end(reg);
            ausgabe(spanz);
        }
    }
}