TOY.java


Below is the syntax highlighted version of TOY.java from §5.5 TOY Simulator.



/*************************************************************************
 *  Compilation:  javac TOY.java StdIn.java In.java
 *  Execution:    java TOY file.toy 
 *
 *  We use variables of type int to store the TOY registers, main
 *  memory, and program counter even though in TOY these quantities
 *  are 16 and 8 bit integers. Java does not have an 8-bit unsigned
 *  type. The type short in Java does represent 16-bit 2's complement
 *  integers, but using it requires alot of casting. Instead, we are
 *  careful to treat all of the variable as if they were the appropriate
 *  type so that the behavior truly models the TOY machine.
 *
 *  Probably need to cast with right shift to simulate signed short.
 *
 *************************************************************************/

import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class TOY { 

    // return a 4 digit hex string corresponding to n
    public static String toHex(int n) {
        String symbols = "0123456789ABCDEF";
        int base   = 16;      // print in hex
        int digits =  4;      // print out 4 hex digits (for 16-bit integers)
        String s = "";
        for (int i = 0; i < digits; i++) {
            int d = n % base;
            s = symbols.charAt(d) + s;
            n = n / base;
        }
        return s;
    }

    // return an integer corresponding to the 4 digit hex string
    public static int fromHex(String s) {
        return Integer.parseInt(s, 16)  & 0xFFFF;
    }


    // display an array of hex integers, 16 per line
    public static void show(int[] a) {
        for (int i = 0; i < a.length; i++) {
            System.out.print(toHex(a[i]) + "  ");
            if (i % 16 == 15) System.out.println();
        }
        System.out.println();
    }


    // the TOY simulator
    public static void main(String[] args) { 

        int pc    = 0x10;             // program counter
        int[] R   = new int[16];      // registers
        int[] mem = new int[256];     // main memory


       /****************************************************************
        *  Read in memory location and instruction.         
        *  A valid input line consists of 2 hex digits followed by a 
        *  colon, followed by any number of spaces, followed by 4
        *  hex digits. The rest of the line is ignored.
        ****************************************************************/
        // read the TOY program directly from the file
        String filename = args[0];
        In in = new In(filename);

        String regexp = "([0-9A-Fa-f]{2}):[ \t]*([0-9A-Fa-f]{4}).*";
        Pattern pattern = Pattern.compile(regexp);
        String line;
        while ((line = in.readLine()) != null) {
            Matcher matcher = pattern.matcher(line);
            if (matcher.find()) {
                int addr = fromHex(matcher.group(1));
                int inst = fromHex(matcher.group(2));
                mem[addr] = inst;
            }
        }

       /*****************************************************
        *  Print it back out.
        *****************************************************/
        System.out.println("Before");
        System.out.println("---------------------------------------------------");
        show(R);
        show(mem);


        while(true) {
            // Fetch and parse
            int inst = mem[pc++];           // fetch next instruction
            int op   = (inst >> 12) &  15;    // get opcode (bits 12-15)
            int d    = (inst >>  8) &  15;    // get dest   (bits  8-11)
            int s    = (inst >>  4) &  15;    // get s      (bits  4- 7)
            int t    = (inst >>  0) &  15;    // get t      (bits  0- 3)
            int addr = (inst >>  0) & 255;    // get addr   (bits  0- 7)

            // halt
            if (op == 0) break;

            // stdin 
            if ((addr == 255 && op == 8) || (R[t] == 255 && op == 10))
                mem[255] = fromHex(StdIn.readString());

            // Execute
            switch (op) {
                case  1: R[d] = R[s] +  R[t];               break;    // add
                case  2: R[d] = R[s] -  R[t];               break;    // subtract
                case  3: R[d] = R[s] &  R[t];               break;    // bitwise and
                case  4: R[d] = R[s] ^  R[t];               break;    // bitwise xor
                case  5: R[d] = R[s] << R[t];               break;    // shift left
                case  6: R[d] = (short) R[s] >> R[t];       break;    // shift right
                case  7: R[d] = addr;                       break;    // load address
                case  8: R[d] = mem[addr];                  break;    // load
                case  9: mem[addr] = R[d];                  break;    // store
                case 10: R[d] = mem[R[t] & 255];            break;    // load indirect
                case 11: mem[R[t] & 255] = R[d];            break;    // store indirect
                case 12: if ((short) R[d] == 0) pc = addr;  break;    // branch if zero
                case 13: if ((short) R[d] >  0) pc = addr;  break;    // branch if positive
                case 14: pc = R[d];                         break;    // jump indirect
                case 15: R[d] = pc; pc = addr;              break;    // jump and link
            }

            // stdout
            if ((addr == 255 && op == 9) || (R[t] == 255 && op == 11))
                System.out.println(toHex(mem[255]));

            R[0] = 0;                // ensure R0 is always 0
            R[d] = R[d] & 0xFFFF;    // don't let R[d] overflow a 16-bit integer (needed???)
            pc = pc & 255;           // don't let pc overflow an 8-bit integer

        }


       /*****************************************************
        *  Print out final contents of TOY.
        *****************************************************/
        System.out.println("After");
        System.out.println("---------------------------------------------------");
        show(R);
        show(mem);

    }
}


Copyright © 2007, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Sep 29 16:17:41 EDT 2009.