1
Fork 0
master
Joshua Potter 2015-12-15 07:40:18 -05:00
parent 518ca35a68
commit 72f3b2b497
75 changed files with 5203 additions and 5339 deletions

View File

@ -13,9 +13,8 @@ import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
/** /**
* Disassemble the mJAM object code * Disassemble the mJAM object code from input file xxx.mJAM into output file
* from input file xxx.mJAM * xxx.asm
* into output file xxx.asm
* *
* @author prins * @author prins
* @version COMP 520 v2.2 * @version COMP 520 v2.2
@ -33,11 +32,15 @@ public class Disassembler {
} }
/** /**
* Writes the r-field of an instruction in the form "l<I>reg</I>r", where * Writes the r-field of an instruction in the form "l<I>reg</I>r", where l
* l and r are the bracket characters to use. * and r are the bracket characters to use.
* @param leftbracket the character to print before the register. *
* @param r the number of the register. * @param leftbracket
* @param rightbracket the character to print after the register. * the character to print before the register.
* @param r
* the number of the register.
* @param rightbracket
* the character to print after the register.
*/ */
private void writeR(char leftbracket, int r, char rightbracket) { private void writeR(char leftbracket, int r, char rightbracket) {
asmWrite(Character.toString(leftbracket)); asmWrite(Character.toString(leftbracket));
@ -55,7 +58,9 @@ public class Disassembler {
// Writes the n-field of an instruction. // Writes the n-field of an instruction.
/** /**
* Writes the n-field of an instruction in the form "(n)". * Writes the n-field of an instruction in the form "(n)".
* @param n the integer to write. *
* @param n
* the integer to write.
*/ */
private void writeN(int n) { private void writeN(int n) {
asmWrite(String.format("%-6s", "(" + n + ")")); asmWrite(String.format("%-6s", "(" + n + ")"));
@ -63,7 +68,9 @@ public class Disassembler {
/** /**
* Writes the d-field of an instruction. * Writes the d-field of an instruction.
* @param d the integer to write. *
* @param d
* the integer to write.
*/ */
private void writeD(int d) { private void writeD(int d) {
asmWrite(Integer.toString(d)); asmWrite(Integer.toString(d));
@ -71,7 +78,9 @@ public class Disassembler {
/** /**
* Writes the name of primitive routine with relative address d. * Writes the name of primitive routine with relative address d.
* @param d the displacment of the primitive routine. *
* @param d
* the displacment of the primitive routine.
*/ */
private void writePrimitive(int d) { private void writePrimitive(int d) {
Machine.Prim prim = Machine.intToPrim[d]; Machine.Prim prim = Machine.intToPrim[d];
@ -80,7 +89,9 @@ public class Disassembler {
/** /**
* Writes the given instruction in assembly-code format. * Writes the given instruction in assembly-code format.
* @param instr the instruction to display. *
* @param instr
* the instruction to display.
*/ */
private void writeInstruction(Instruction instr) { private void writeInstruction(Instruction instr) {
@ -190,8 +201,7 @@ public class Disassembler {
try { try {
asmOut = new FileWriter(asmFileName); asmOut = new FileWriter(asmFileName);
} catch (IOException e) { } catch (IOException e) {
System.out.println("Disassembler: can not create asm output file " System.out.println("Disassembler: can not create asm output file " + asmName);
+ asmName);
error = true; error = true;
return; return;
} }
@ -204,12 +214,14 @@ public class Disassembler {
switch (op) { switch (op) {
case CALL: case CALL:
case CALLI: case CALLI:
// only consider calls (branches) within code memory (i.e. not primitives) // only consider calls (branches) within code memory (i.e. not
// primitives)
if (inst.r == Machine.Reg.CB.ordinal()) if (inst.r == Machine.Reg.CB.ordinal())
targets.add(inst.d); targets.add(inst.d);
break; break;
case JUMP: case JUMP:
// address following an unconditional branch is an implicit target // address following an unconditional branch is an implicit
// target
targets.add(addr + 1); targets.add(addr + 1);
targets.add(inst.d); targets.add(inst.d);
break; break;
@ -276,6 +288,7 @@ public class Disassembler {
/** /**
* Disassemble object file * Disassemble object file
*
* @return true if error encountered else false * @return true if error encountered else false
*/ */
public boolean disassemble() { public boolean disassemble() {
@ -283,15 +296,13 @@ public class Disassembler {
// read object file into code store // read object file into code store
if (objectFile.read()) { if (objectFile.read()) {
System.out.println("Disassembler: unable to read object file" System.out.println("Disassembler: unable to read object file" + objectFileName);
+ objectFileName);
return true; return true;
} }
// assembler-code output file name // assembler-code output file name
if (objectFileName.endsWith(".mJAM")) if (objectFileName.endsWith(".mJAM"))
asmName = objectFileName.substring(0, objectFileName.length() - 5) asmName = objectFileName.substring(0, objectFileName.length() - 5) + ".asm";
+ ".asm";
else else
asmName = objectFileName + ".asm"; asmName = objectFileName + ".asm";
@ -299,8 +310,7 @@ public class Disassembler {
disassembleProgram(asmName); disassembleProgram(asmName);
if (error) { if (error) {
System.out.println("Disassembler: unable to write asm file" System.out.println("Disassembler: unable to write asm file" + asmName);
+ asmName);
return true; return true;
} }

View File

@ -22,17 +22,15 @@ public class Interpreter {
static int[] data = new int[1024]; static int[] data = new int[1024];
// DATA STORE REGISTERS AND OTHER REGISTERS // DATA STORE REGISTERS AND OTHER REGISTERS
final static int CB = 0, SB = 0, HB = 1024; // = upper bound of data array + 1 final static int CB = 0, SB = 0, HB = 1024; // = upper bound of data array +
// 1
static int CT, CP, ST, HT, LB, OB, status, temp; static int CT, CP, ST, HT, LB, OB, status, temp;
// machine status values // machine status values
final static int running = 0, halted = 1, failedDataStoreFull = 2, final static int running = 0, halted = 1, failedDataStoreFull = 2, failedInvalidCodeAddress = 3,
failedInvalidCodeAddress = 3, failedInvalidInstruction = 4, failedInvalidInstruction = 4, failedOverflow = 5, failedZeroDivide = 6, failedIOError = 7,
failedOverflow = 5, failedZeroDivide = 6, failedIOError = 7, failedArrayIndex = 8, failedNullRef = 9, failedHeapRef = 10, failedMethodIndex = 11;
failedArrayIndex = 8, failedNullRef = 9, failedHeapRef =10,
failedMethodIndex = 11;
static long accumulator; static long accumulator;
@ -82,8 +80,7 @@ public class Interpreter {
// Writes a summary of the machine state. // Writes a summary of the machine state.
int addr, dynamicLink; int addr, dynamicLink;
System.out.println(""); System.out.println("");
System.out.println("At instruction " + CP System.out.println("At instruction " + CP + ", state of mJAM data store and registers is:");
+ ", state of mJAM data store and registers is:");
System.out.println(""); System.out.println("");
if (HT == HB) if (HT == HB)
System.out.println(" |--------| (heap is empty)"); System.out.println(" |--------| (heap is empty)");
@ -98,8 +95,7 @@ public class Interpreter {
System.out.print("HT--> "); System.out.print("HT--> ");
else else
System.out.print(" "); System.out.print(" ");
System.out.println("|" + leftPad(8, String.valueOf(data[addr])) System.out.println("|" + leftPad(8, String.valueOf(data[addr])) + "|");
+ "|");
} }
System.out.println(" |--------|"); System.out.println(" |--------|");
} }
@ -120,17 +116,13 @@ public class Interpreter {
else else
System.out.print(" "); System.out.print(" ");
if ((addr == dynamicLink) && (dynamicLink != SB)) if ((addr == dynamicLink) && (dynamicLink != SB))
System.out.print("|OB=" System.out.print("|OB=" + leftPad(5, String.valueOf(data[addr])) + "|");
+ leftPad(5, String.valueOf(data[addr])) + "|");
else if ((addr == dynamicLink + 1) && (dynamicLink != SB)) else if ((addr == dynamicLink + 1) && (dynamicLink != SB))
System.out.print("|DL=" System.out.print("|DL=" + leftPad(5, String.valueOf(data[addr])) + "|");
+ leftPad(5, String.valueOf(data[addr])) + "|");
else if ((addr == dynamicLink + 2) && (dynamicLink != SB)) else if ((addr == dynamicLink + 2) && (dynamicLink != SB))
System.out.print("|RA=" System.out.print("|RA=" + leftPad(5, String.valueOf(data[addr])) + "|");
+ leftPad(5, String.valueOf(data[addr])) + "|");
else else
System.out.print("|" System.out.print("|" + leftPad(8, String.valueOf(data[addr])) + "|");
+ leftPad(8, String.valueOf(data[addr])) + "|");
System.out.println(""); System.out.println("");
if (addr == dynamicLink) { if (addr == dynamicLink) {
System.out.println(" |--------|"); System.out.println(" |--------|");
@ -423,7 +415,8 @@ public class Interpreter {
HT = HT - size; // reserve space HT = HT - size; // reserve space
data[HT] = data[ST - 2]; // set class object addr data[HT] = data[ST - 2]; // set class object addr
data[HT + 1] = size - 2; // set size of object data[HT + 1] = size - 2; // set size of object
data[ST - 2] = HT + 2; // addr of new object instance, returned on stack data[ST - 2] = HT + 2; // addr of new object instance, returned on
// stack
ST = ST - 1; // net effect of pop 2 args, push 1 result ST = ST - 1; // net effect of pop 2 args, push 1 result
for (int i = 2; i < size; i++) { for (int i = 2; i < size; i++) {
data[HT + i] = 0; // zero all fields of new object data[HT + i] = 0; // zero all fields of new object
@ -451,7 +444,8 @@ public class Interpreter {
status = failedArrayIndex; status = failedArrayIndex;
break; break;
} }
data[ST - 2] = data[addr + index]; // result element, returned on stack data[ST - 2] = data[addr + index]; // result element, returned on
// stack
ST = ST - 1; // pop two args, return one result ST = ST - 1; // pop two args, return one result
break; break;
case arrayupd: case arrayupd:
@ -565,8 +559,10 @@ public class Interpreter {
// static method in code segment, no instance addr on stack // static method in code segment, no instance addr on stack
checkSpace(3); checkSpace(3);
data[ST] = OB; // save caller OB in callee frame data[ST] = OB; // save caller OB in callee frame
data[ST + 1] = LB; // save caller LB in callee frame (dynamic link) data[ST + 1] = LB; // save caller LB in callee frame (dynamic
data[ST + 2] = CP + 1; // save caller return address in callee frame // link)
data[ST + 2] = CP + 1; // save caller return address in callee
// frame
OB = Machine.nullRep; // set callee OB (null since no instance) OB = Machine.nullRep; // set callee OB (null since no instance)
LB = ST; // set LB = start of callee frame LB = ST; // set LB = start of callee frame
ST = ST + 3; // set ST = end of callee frame ST = ST + 3; // set ST = end of callee frame
@ -596,7 +592,8 @@ public class Interpreter {
break; break;
case RETURN: case RETURN:
// d = number of method args (does not include instance addr for CALLI) // d = number of method args (does not include instance addr for
// CALLI)
// n = size of result (0 or 1) // n = size of result (0 or 1)
if (n < 0 || n > 1) { if (n < 0 || n > 1) {
status = failedInvalidInstruction; status = failedInvalidInstruction;
@ -708,27 +705,15 @@ public class Interpreter {
} }
static void printHelp() { static void printHelp() {
String[] help = { String[] help = { "p or print:", " print entire machine state", "l or list [offset] [size]:",
"p or print:",
" print entire machine state",
"l or list [offset] [size]:",
" print the instructions around CP + offset, with size lines on either side", " print the instructions around CP + offset, with size lines on either side",
" offset = 0 and size = 2 by default", " offset = 0 and size = 2 by default", "b or break [address]:", " set a breakpoint at address",
"b or break [address]:", " address = CP by default", "del:", " delete one or more breakpoints", "n or next:",
" set a breakpoint at address", " execute one instruction", "c or continue:",
" address = CP by default",
"del:",
" delete one or more breakpoints",
"n or next:",
" execute one instruction",
"c or continue:",
" continue running the program from current position, until next breakpoint or completion", " continue running the program from current position, until next breakpoint or completion",
"r or run:", "r or run:", " run the program from start, until next breakpoint or completion", "i or info:",
" run the program from start, until next breakpoint or completion", " list the current breakpoints", "q, quit or <EOF>:", " quit the debugger",
"i or info:", " list the current breakpoints", "Simply press enter to repeat the last command", "? or help:", " print this help" };
"q, quit or <EOF>:", " quit the debugger",
"Simply press enter to repeat the last command", "? or help:",
" print this help" };
for (String line : help) { for (String line : help) {
System.out.println(" " + line); System.out.println(" " + line);
@ -738,8 +723,7 @@ public class Interpreter {
static void debugProgram() { static void debugProgram() {
initMachine(); initMachine();
BufferedReader inputReader = new BufferedReader(new InputStreamReader( BufferedReader inputReader = new BufferedReader(new InputStreamReader(System.in));
System.in));
String lastCommand = ""; String lastCommand = "";
@ -762,11 +746,9 @@ public class Interpreter {
if (command.equals("?") || command.equals("help")) { if (command.equals("?") || command.equals("help")) {
printHelp(); printHelp();
} else if (command.equalsIgnoreCase("p") } else if (command.equalsIgnoreCase("p") || command.equalsIgnoreCase("print")) {
|| command.equalsIgnoreCase("print")) {
dump(); dump();
} else if (command.equalsIgnoreCase("l") } else if (command.equalsIgnoreCase("l") || command.equalsIgnoreCase("list")) {
|| command.equalsIgnoreCase("list")) {
int offset = 0, size = 2; int offset = 0, size = 2;
if (scanner.hasNextInt()) if (scanner.hasNextInt())
offset = scanner.nextInt(); offset = scanner.nextInt();
@ -775,52 +757,42 @@ public class Interpreter {
for (int i = CP + offset - size; i <= CP + offset + size; ++i) { for (int i = CP + offset - size; i <= CP + offset + size; ++i) {
if (i >= 0 && i < sourceLines.size()) if (i >= 0 && i < sourceLines.size())
System.out.println((i == CP ? " >" : " ") System.out.println((i == CP ? " >" : " ") + sourceLines.get(i));
+ sourceLines.get(i));
} }
} else if (command.equalsIgnoreCase("b") } else if (command.equalsIgnoreCase("b") || command.equalsIgnoreCase("break")) {
|| command.equalsIgnoreCase("break")) {
int addr = scanner.hasNextInt() ? scanner.nextInt() : CP; int addr = scanner.hasNextInt() ? scanner.nextInt() : CP;
if (!breakpoints.contains(addr)) if (!breakpoints.contains(addr))
breakpoints.add(addr); breakpoints.add(addr);
System.out.println("Added breakpoint at " System.out.println("Added breakpoint at " + sourceLines.get(addr));
+ sourceLines.get(addr));
} else if (command.equalsIgnoreCase("del")) { } else if (command.equalsIgnoreCase("del")) {
while (scanner.hasNextInt()) { while (scanner.hasNextInt()) {
int addr = scanner.nextInt(), idx = breakpoints int addr = scanner.nextInt(), idx = breakpoints.indexOf(addr);
.indexOf(addr);
if (idx != -1) { if (idx != -1) {
breakpoints.remove(idx); breakpoints.remove(idx);
} else { } else {
System.out.println("No breakpoint at " + addr); System.out.println("No breakpoint at " + addr);
} }
} }
} else if (command.equalsIgnoreCase("n") } else if (command.equalsIgnoreCase("n") || command.equalsIgnoreCase("next")) {
|| command.equalsIgnoreCase("next")) {
if (status == running) { if (status == running) {
interpretOneOperation(); interpretOneOperation();
} else { } else {
System.out.println("Program is not running"); System.out.println("Program is not running");
} }
} else if (command.equalsIgnoreCase("c") } else if (command.equalsIgnoreCase("c") || command.equalsIgnoreCase("continue")) {
|| command.equalsIgnoreCase("continue")) {
continueProgram(); continueProgram();
} else if (command.equalsIgnoreCase("r") } else if (command.equalsIgnoreCase("r") || command.equalsIgnoreCase("run")) {
|| command.equalsIgnoreCase("run")) {
runProgramFromStart(); runProgramFromStart();
} else if (command.equalsIgnoreCase("i") } else if (command.equalsIgnoreCase("i") || command.equalsIgnoreCase("info")) {
|| command.equalsIgnoreCase("info")) {
System.out.println("Breakpoints:"); System.out.println("Breakpoints:");
for (int b : breakpoints) { for (int b : breakpoints) {
System.out.println("\t" + sourceLines.get(b)); System.out.println("\t" + sourceLines.get(b));
} }
} else if (command.equalsIgnoreCase("q") } else if (command.equalsIgnoreCase("q") || command.equalsIgnoreCase("quit")) {
|| command.equalsIgnoreCase("quit")) {
scanner.close(); scanner.close();
return; return;
} else { } else {
System.out.println("Unknown command '" + command System.out.println("Unknown command '" + command + "'. Type 'help' for a list of commands");
+ "'. Type 'help' for a list of commands");
} }
scanner.close(); scanner.close();
} }
@ -829,8 +801,7 @@ public class Interpreter {
// RUNNING // RUNNING
public static void main(String[] args) { public static void main(String[] args) {
System.out System.out.println("********** mJAM Interpreter (Version 1.2) **********");
.println("********** mJAM Interpreter (Version 1.2) **********");
String objectFileName; String objectFileName;
if (args.length >= 1) if (args.length >= 1)
@ -867,8 +838,7 @@ public class Interpreter {
sourceLines = new ArrayList<String>(); sourceLines = new ArrayList<String>();
try { try {
BufferedReader reader = new BufferedReader(new FileReader(new File( BufferedReader reader = new BufferedReader(new FileReader(new File(sourceFileName)));
sourceFileName)));
String line = reader.readLine(); String line = reader.readLine();
while (line != null) { while (line != null) {
sourceLines.add(line); sourceLines.add(line);

View File

@ -2,6 +2,7 @@ package mJAM;
/** /**
* Defines names and sizes of mJAM instructions and primitives * Defines names and sizes of mJAM instructions and primitives
*
* @author prins * @author prins
* @version COMP 520 V2.2 * @version COMP 520 V2.2
*/ */
@ -11,25 +12,14 @@ public final class Machine {
* mJAM instructions * mJAM instructions
*/ */
public enum Op { public enum Op {
LOAD, LOAD, LOADA, LOADI, LOADL, STORE, STOREI, CALL, // direct call of
LOADA, // instance method
LOADI,
LOADL,
STORE,
STOREI,
CALL, // direct call of instance method
CALLI, // indirect call of instance method CALLI, // indirect call of instance method
CALLD, // dynamic call of instance method CALLD, // dynamic call of instance method
RETURN, RETURN, PUSH, POP, JUMP, JUMPI, JUMPIF, HALT;
PUSH,
POP,
JUMP,
JUMPI,
JUMPIF,
HALT;
} }
public static Op [] intToOp = Op.values();
public static Op[] intToOp = Op.values();
/** /**
* mJAM registers * mJAM registers
@ -48,62 +38,28 @@ public final class Machine {
HT, // heap top HT, // heap top
OB; // object base OB; // object base
} }
public static Reg[] intToReg = Reg.values(); public static Reg[] intToReg = Reg.values();
/** /**
* mJAM primitives * mJAM primitives
*/ */
public enum Prim { public enum Prim {
id, id, not, and, or, succ, pred, neg, add, sub, mult, div, mod, lt, le, ge, gt, eq, ne, eol, eof, get, put, geteol, puteol, getint, putint, putintnl, alloc, dispose, newobj, newarr, arrayref, arrayupd, fieldref, fieldupd;
not,
and,
or,
succ,
pred,
neg,
add,
sub,
mult,
div,
mod,
lt,
le,
ge,
gt,
eq,
ne,
eol,
eof,
get,
put,
geteol,
puteol,
getint,
putint,
putintnl,
alloc,
dispose,
newobj,
newarr,
arrayref,
arrayupd,
fieldref,
fieldupd;
} }
public static Prim[] intToPrim = Prim.values(); public static Prim[] intToPrim = Prim.values();
// range for int constants // range for int constants
public final static long public final static long minintRep = -2147483648, maxintRep = 2147483647;
minintRep = -2147483648,
maxintRep = 2147483647;
// CODE STORE REGISTERS // CODE STORE REGISTERS
public final static int CB = 0; // start of code space public final static int CB = 0; // start of code space
public final static int PB = 1024; // size of code space reserved for instructions public final static int PB = 1024; // size of code space reserved for
public final static int PT = PB + Prim.values().length; // code space reserved for primitives // instructions
public final static int PT = PB + Prim.values().length; // code space
// reserved for
// primitives
// CODE STORE // CODE STORE
public static Instruction[] code = new Instruction[PB]; public static Instruction[] code = new Instruction[PB];
@ -114,11 +70,17 @@ public final class Machine {
} }
/** /**
* Places an instruction, with the given fields, into the next position in the code store * Places an instruction, with the given fields, into the next position in
* @param op - operation * the code store
* @param n - length *
* @param r - register * @param op
* @param d - displacement * - operation
* @param n
* - length
* @param r
* - register
* @param d
* - displacement
*/ */
public static void emit(Op op, int n, Reg r, Prim d) { public static void emit(Op op, int n, Reg r, Prim d) {
emit(op.ordinal(), n, r.ordinal(), d.ordinal()); emit(op.ordinal(), n, r.ordinal(), d.ordinal());
@ -141,8 +103,8 @@ public static void emit(Op op, int d) {
} }
/** /**
* emit operations without arguments. These are operations like * emit operations without arguments. These are operations like LOADI and
* LOADI and STOREI * STOREI
*/ */
public static void emit(Op op) { public static void emit(Op op) {
emit(op, 0, 0, 0); emit(op, 0, 0, 0);
@ -157,20 +119,19 @@ public static void emit(Op op, int d) {
} }
/** /**
* emit operation with n field, and register r and integer displacement. These are * emit operation with n field, and register r and integer displacement.
* operations like JUMPIF (1) 25[CB]. In the assembly code the value of n is shown * These are operations like JUMPIF (1) 25[CB]. In the assembly code the
* in parens. * value of n is shown in parens.
*/ */
public static void emit(Op op, int n, Reg r, int d) { public static void emit(Op op, int n, Reg r, int d) {
emit(op.ordinal(), n, r.ordinal(), d); emit(op.ordinal(), n, r.ordinal(), d);
} }
/** /**
* emit operation with integer n, r, d. These are operations * emit operation with integer n, r, d. These are operations like RETURN (1)
* like RETURN (1) 3 and HALT (4) 0. For RETURN the value * 3 and HALT (4) 0. For RETURN the value of d is the number of caller args
* of d is the number of caller args to pop off the callers * to pop off the callers stack and n is the number of values to return at
* stack and n is the number of values to return at caller stack * caller stack top. n must be 0 or 1.
* top. n must be 0 or 1.
*/ */
public static void emit(Op op, int n, int r, int d) { public static void emit(Op op, int n, int r, int d) {
emit(op.ordinal(), n, r, d); emit(op.ordinal(), n, r, d);
@ -200,7 +161,9 @@ public static int nextInstrAddr() {
} }
/** /**
* Update the displacement component of the (JUMP or CALL) instruction at addr * Update the displacement component of the (JUMP or CALL) instruction at
* addr
*
* @param addr * @param addr
* @param displacement * @param displacement
*/ */
@ -219,14 +182,8 @@ public static void patch(int addr, int displacement) {
// DATA REPRESENTATION // DATA REPRESENTATION
public final static int public final static int booleanSize = 1, characterSize = 1, integerSize = 1, addressSize = 1,
booleanSize = 1,
characterSize = 1,
integerSize = 1,
addressSize = 1,
linkDataSize = 3 * addressSize, // caller's OB, LB, CP linkDataSize = 3 * addressSize, // caller's OB, LB, CP
falseRep = 0, falseRep = 0, trueRep = 1, nullRep = 0;
trueRep = 1,
nullRep = 0;
} }

View File

@ -21,7 +21,9 @@ public class ObjectFile {
/** /**
* Write code store as object file * Write code store as object file
* @param output object file *
* @param output
* object file
* @return true if write fails * @return true if write fails
*/ */
public boolean write() { public boolean write() {
@ -37,13 +39,15 @@ public class ObjectFile {
is.writeInt(inst.d); is.writeInt(inst.d);
} }
objectFile.close(); objectFile.close();
} catch (Exception e) {
failed = true;
} }
catch (Exception e) {failed = true;}
return failed; return failed;
} }
/** /**
* Read object file into code store, setting CT * Read object file into code store, setting CT
*
* @return true if object code read fails * @return true if object code read fails
*/ */
public boolean read() { public boolean read() {

View File

@ -4,31 +4,31 @@
* @version COMP 520 V2.2 * @version COMP 520 V2.2
*/ */
package mJAM; package mJAM;
import mJAM.Machine.Op; import mJAM.Machine.Op;
import mJAM.Machine.Reg; import mJAM.Machine.Reg;
import mJAM.Machine.Prim; import mJAM.Machine.Prim;
// test class to construct and run an mJAM program // test class to construct and run an mJAM program
public class Test public class Test {
{
public static void main(String[] args) { public static void main(String[] args) {
Machine.initCodeGen(); Machine.initCodeGen();
System.out.println("Generating test program object code"); System.out.println("Generating test program object code");
/* class A { /*
* int x; * class A { int x; int p(){return x;} }
* int p(){return x;}
* }
*/ */
Machine.emit(Op.LOADL, 11); // hello Machine.emit(Op.LOADL, 11); // hello
Machine.emit(Prim.putintnl); Machine.emit(Prim.putintnl);
int patchme_coA = Machine.nextInstrAddr(); int patchme_coA = Machine.nextInstrAddr();
Machine.emit(Op.JUMP,Reg.CB,0); // jump around methods of class A (branch to /*coA*/) Machine.emit(Op.JUMP, Reg.CB, 0); // jump around methods of class A
// (branch to /*coA*/)
// code for p() in A // code for p() in A
int label_pA = Machine.nextInstrAddr(); int label_pA = Machine.nextInstrAddr();
/*pA*/ Machine.emit(Op.LOAD,Reg.OB,0); // x at offset 0 in current instance of A /* pA */ Machine.emit(Op.LOAD, Reg.OB, 0); // x at offset 0 in current
// instance of A
Machine.emit(Op.HALT, 4, 0, 0); Machine.emit(Op.HALT, 4, 0, 0);
Machine.emit(Op.RETURN, 1, 0, 0); // return one value, pop zero args Machine.emit(Op.RETURN, 1, 0, 0); // return one value, pop zero args
@ -39,18 +39,16 @@ public class Test
Machine.emit(Op.LOADL, 1); // number of methods Machine.emit(Op.LOADL, 1); // number of methods
Machine.emit(Op.LOADA, Reg.CB, label_pA); // code addr of p_A Machine.emit(Op.LOADA, Reg.CB, label_pA); // code addr of p_A
/*
/* class B extends A { * class B extends A { int y; int p(){return x + 22;} }
* int y;
* int p(){return x + 22;}
* }
*/ */
int patchme_coB = Machine.nextInstrAddr(); int patchme_coB = Machine.nextInstrAddr();
Machine.emit(Op.JUMP, Reg.CB, 0); // branch around methods in class B Machine.emit(Op.JUMP, Reg.CB, 0); // branch around methods in class B
// code for p() in B // code for p() in B
int label_pB = Machine.nextInstrAddr(); int label_pB = Machine.nextInstrAddr();
/*pB*/ Machine.emit(Op.LOAD,Reg.OB,0); // x at offset 0 in current instance /* pB */ Machine.emit(Op.LOAD, Reg.OB, 0); // x at offset 0 in current
// instance
Machine.emit(Op.LOADL, 22); Machine.emit(Op.LOADL, 22);
Machine.emit(Op.HALT, 4, 0, 0); Machine.emit(Op.HALT, 4, 0, 0);
Machine.emit(Prim.add); Machine.emit(Prim.add);
@ -59,17 +57,14 @@ public class Test
// build class object for B at 3[SB] // build class object for B at 3[SB]
int label_coB = Machine.nextInstrAddr(); int label_coB = Machine.nextInstrAddr();
Machine.patch(patchme_coB, label_coB); Machine.patch(patchme_coB, label_coB);
/*coB*/ Machine.emit(Op.LOADA,Reg.SB,0); // addr of superclass object /* coB */ Machine.emit(Op.LOADA, Reg.SB, 0); // addr of superclass
// object
Machine.emit(Op.LOADL, 1); // number of methods Machine.emit(Op.LOADL, 1); // number of methods
Machine.emit(Op.LOADA, Reg.CB, label_pB); // code addr of p_B Machine.emit(Op.LOADA, Reg.CB, label_pB); // code addr of p_B
/*
/* class C { * class C { public static void main(String [] args) { A a = new A();
* public static void main(String [] args) { * a.x = 33; System.out.println(a.p()); ...
* A a = new A();
* a.x = 33;
* System.out.println(a.p());
* ...
*/ */
int patchme_coC = Machine.nextInstrAddr(); int patchme_coC = Machine.nextInstrAddr();
Machine.emit(Op.JUMP, Reg.CB, 0); // branch around methods of class C Machine.emit(Op.JUMP, Reg.CB, 0); // branch around methods of class C
@ -87,14 +82,12 @@ public class Test
Machine.emit(Op.HALT, 4, 0, 0); Machine.emit(Op.HALT, 4, 0, 0);
Machine.emit(Prim.fieldupd); // a.x = 33 Machine.emit(Prim.fieldupd); // a.x = 33
Machine.emit(Op.LOAD, Reg.LB, 3); // addr of instance "a" on heap Machine.emit(Op.LOAD, Reg.LB, 3); // addr of instance "a" on heap
Machine.emit(Op.CALLI,Reg.CB,label_pA); // call to known instance method p_A Machine.emit(Op.CALLI, Reg.CB, label_pA); // call to known instance
// method p_A
Machine.emit(Prim.putintnl); // print result Machine.emit(Prim.putintnl); // print result
/* ... /*
* A b = new B(); * ... A b = new B(); b.x = 44; System.out.println(b.p()); } // end main
* b.x = 44;
* System.out.println(b.p());
* } // end main
* } // end class C * } // end class C
*/ */
// local var "b" will be at 4[LB] after init // local var "b" will be at 4[LB] after init
@ -109,7 +102,8 @@ public class Test
Machine.emit(Op.LOAD, Reg.LB, 4); // addr of instance "b" Machine.emit(Op.LOAD, Reg.LB, 4); // addr of instance "b"
Machine.emit(Op.CALLD, 0); // dynamic call, method index 0 (= method p) Machine.emit(Op.CALLD, 0); // dynamic call, method index 0 (= method p)
Machine.emit(Prim.putintnl); // print result Machine.emit(Prim.putintnl); // print result
Machine.emit(Op.RETURN,0,0,1); // return no value (void), pop 1 arg (= String [] args) Machine.emit(Op.RETURN, 0, 0, 1); // return no value (void), pop 1 arg
// (= String [] args)
// build class descriptor for C at 6[SB] // build class descriptor for C at 6[SB]
int label_coC = Machine.nextInstrAddr(); int label_coC = Machine.nextInstrAddr();
@ -120,7 +114,8 @@ public class Test
/* /*
* End of class declarations - call main * End of class declarations - call main
*/ */
Machine.emit(Op.LOADL,Machine.nullRep); // put null on stack as value of main's arg Machine.emit(Op.LOADL, Machine.nullRep); // put null on stack as value
// of main's arg
Machine.emit(Op.CALL, Reg.CB, label_mainC); // call known static main() Machine.emit(Op.CALL, Reg.CB, label_mainC); // call known static main()
Machine.emit(Op.LOADL, 88); // goodbye Machine.emit(Op.LOADL, 88); // goodbye
Machine.emit(Prim.putintnl); Machine.emit(Prim.putintnl);
@ -133,8 +128,7 @@ public class Test
if (objF.write()) { if (objF.write()) {
System.out.println("FAILED!"); System.out.println("FAILED!");
return; return;
} } else
else
System.out.println("SUCCEEDED"); System.out.println("SUCCEEDED");
/* create asm file using disassembler */ /* create asm file using disassembler */
@ -144,8 +138,7 @@ public class Test
if (d.disassemble()) { if (d.disassemble()) {
System.out.println("FAILED!"); System.out.println("FAILED!");
return; return;
} } else
else
System.out.println("SUCCEEDED"); System.out.println("SUCCEEDED");
/* run code */ /* run code */

View File

@ -116,16 +116,14 @@ public class ASTDisplay implements Visitor<String, Object> {
} }
public Object visitFieldDecl(FieldDecl f, String arg) { public Object visitFieldDecl(FieldDecl f, String arg) {
show(arg, "(" + (f.isPrivate ? "private" : "public") show(arg, "(" + (f.isPrivate ? "private" : "public") + (f.isStatic ? " static) " : ") ") + f.toString());
+ (f.isStatic ? " static) " : ") ") + f.toString());
f.type.visit(this, indent(arg)); f.type.visit(this, indent(arg));
show(indent(arg), quote(f.name) + " fieldname"); show(indent(arg), quote(f.name) + " fieldname");
return null; return null;
} }
public Object visitMethodDecl(MethodDecl m, String arg) { public Object visitMethodDecl(MethodDecl m, String arg) {
show(arg, "(" + (m.isPrivate ? "private" : "public") show(arg, "(" + (m.isPrivate ? "private" : "public") + (m.isStatic ? " static) " : ") ") + m.toString());
+ (m.isStatic ? " static) " : ") ") + m.toString());
m.type.visit(this, indent(arg)); m.type.visit(this, indent(arg));
show(indent(arg), quote(m.name) + " methodname"); show(indent(arg), quote(m.name) + " methodname");
ParameterDeclList pdl = m.parameterDeclList; ParameterDeclList pdl = m.parameterDeclList;

View File

@ -8,8 +8,7 @@ package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition; import miniJava.SyntacticAnalyzer.SourcePosition;
public class BinaryExpr extends Expression { public class BinaryExpr extends Expression {
public BinaryExpr(Operator o, Expression e1, Expression e2, public BinaryExpr(Operator o, Expression e1, Expression e2, SourcePosition posn) {
SourcePosition posn) {
super(posn); super(posn);
operator = o; operator = o;
left = e1; left = e1;

View File

@ -9,8 +9,7 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public class ClassDecl extends Declaration { public class ClassDecl extends Declaration {
public ClassDecl(String cn, FieldDeclList fdl, MethodDeclList mdl, public ClassDecl(String cn, FieldDeclList fdl, MethodDeclList mdl, SourcePosition posn) {
SourcePosition posn) {
super(cn, null, posn); super(cn, null, posn);
fieldDeclList = fdl; fieldDeclList = fdl;
methodDeclList = mdl; methodDeclList = mdl;

View File

@ -8,8 +8,7 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
*/ */
public class Declarators { public class Declarators {
public Declarators(boolean isPrivate, boolean isStatic, Type mt, public Declarators(boolean isPrivate, boolean isStatic, Type mt, SourcePosition posn) {
SourcePosition posn) {
this.isPrivate = isPrivate; this.isPrivate = isPrivate;
this.isStatic = isStatic; this.isStatic = isStatic;
this.mt = mt; this.mt = mt;

View File

@ -9,8 +9,7 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public class FieldDecl extends MemberDecl { public class FieldDecl extends MemberDecl {
public FieldDecl(boolean isPrivate, boolean isStatic, Type t, String name, public FieldDecl(boolean isPrivate, boolean isStatic, Type t, String name, SourcePosition posn) {
SourcePosition posn) {
super(isPrivate, isStatic, t, name, posn); super(isPrivate, isStatic, t, name, posn);
} }

View File

@ -9,8 +9,7 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
abstract public class MemberDecl extends Declaration { abstract public class MemberDecl extends Declaration {
public MemberDecl(boolean isPrivate, boolean isStatic, Type mt, public MemberDecl(boolean isPrivate, boolean isStatic, Type mt, String name, SourcePosition posn) {
String name, SourcePosition posn) {
super(name, mt, posn); super(name, mt, posn);
this.isPrivate = isPrivate; this.isPrivate = isPrivate;
this.isStatic = isStatic; this.isStatic = isStatic;

View File

@ -9,8 +9,7 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public class MethodDecl extends MemberDecl { public class MethodDecl extends MemberDecl {
public MethodDecl(MemberDecl md, ParameterDeclList pl, StatementList sl, public MethodDecl(MemberDecl md, ParameterDeclList pl, StatementList sl, Expression e, SourcePosition posn) {
Expression e, SourcePosition posn) {
super(md, posn); super(md, posn);
parameterDeclList = pl; parameterDeclList = pl;
statementList = sl; statementList = sl;

View File

@ -9,8 +9,9 @@ public class Code {
public Declaration decl; public Declaration decl;
/** /**
* If addr true, returns the address of the declaration. * If addr true, returns the address of the declaration. Otherwise, uses the
* Otherwise, uses the size of the declaration in its place. * size of the declaration in its place.
*
* @param op * @param op
* @param decl * @param decl
* @param addr * @param addr

View File

@ -16,7 +16,6 @@ public class Encoder implements Visitor<Integer, Object> {
// Maintains data to correct once completed traversal // Maintains data to correct once completed traversal
private HashMap<Integer, Code> patches = new HashMap<>(); private HashMap<Integer, Code> patches = new HashMap<>();
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// PACKAGE // PACKAGE
@ -76,7 +75,6 @@ public class Encoder implements Visitor<Integer, Object> {
return null; return null;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// DECLARATIONS // DECLARATIONS
@ -183,7 +181,6 @@ public class Encoder implements Visitor<Integer, Object> {
return null; return null;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// TYPES // TYPES
@ -208,7 +205,6 @@ public class Encoder implements Visitor<Integer, Object> {
return null; return null;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// STATEMENTS // STATEMENTS
@ -398,7 +394,6 @@ public class Encoder implements Visitor<Integer, Object> {
return null; return null;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// EXPRESSIONS // EXPRESSIONS
@ -519,7 +514,6 @@ public class Encoder implements Visitor<Integer, Object> {
return null; return null;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// REFERENCES // REFERENCES
@ -614,7 +608,6 @@ public class Encoder implements Visitor<Integer, Object> {
return null; return null;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// TERMINALS // TERMINALS
@ -693,7 +686,6 @@ public class Encoder implements Visitor<Integer, Object> {
return null; return null;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// Convenience Methods // Convenience Methods
@ -702,6 +694,7 @@ public class Encoder implements Visitor<Integer, Object> {
/** /**
* Get size of type for declaration purposes. * Get size of type for declaration purposes.
*
* @param t * @param t
* @return * @return
*/ */

View File

@ -19,8 +19,8 @@ public class Analyzer implements Visitor<IdTable, Type> {
// Predefined // Predefined
private static ArrayList<String> predefined; private static ArrayList<String> predefined;
static
{ static {
predefined = new ArrayList<String>(); predefined = new ArrayList<String>();
predefined.add("class String { }"); predefined.add("class String { }");
predefined.add("class _PrintStream { public void println(int n){} }"); predefined.add("class _PrintStream { public void println(int n){} }");
@ -33,7 +33,6 @@ public class Analyzer implements Visitor<IdTable, Type> {
private ClassDecl currentClassDecl = null; private ClassDecl currentClassDecl = null;
private MethodDecl currentMethodDecl = null; private MethodDecl currentMethodDecl = null;
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// PACKAGE // PACKAGE
@ -78,7 +77,6 @@ public class Analyzer implements Visitor<IdTable, Type> {
return null; return null;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// DECLARATIONS // DECLARATIONS
@ -183,7 +181,6 @@ public class Analyzer implements Visitor<IdTable, Type> {
return null; return null;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// TYPES // TYPES
@ -218,7 +215,6 @@ public class Analyzer implements Visitor<IdTable, Type> {
return type; return type;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// STATEMENTS // STATEMENTS
@ -306,7 +302,8 @@ public class Analyzer implements Visitor<IdTable, Type> {
ParameterDecl pd = md.parameterDeclList.get(i); ParameterDecl pd = md.parameterDeclList.get(i);
if (!match(pd.type, exprType)) { if (!match(pd.type, exprType)) {
Reporter.emit("Parameter " + pd.name + " is of type " + pd.type + " but got " + exprType + " at " + e.posn); Reporter.emit(
"Parameter " + pd.name + " is of type " + pd.type + " but got " + exprType + " at " + e.posn);
} }
} }
@ -362,7 +359,6 @@ public class Analyzer implements Visitor<IdTable, Type> {
return null; return null;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// EXPRESSIONS // EXPRESSIONS
@ -481,7 +477,8 @@ public class Analyzer implements Visitor<IdTable, Type> {
ParameterDecl pd = md.parameterDeclList.get(i); ParameterDecl pd = md.parameterDeclList.get(i);
if (!match(pd.type, exprType)) { if (!match(pd.type, exprType)) {
Reporter.emit("Parameter " + pd.name + " is of type " + pd.type + " but got " + exprType + " at " + e.posn); Reporter.emit(
"Parameter " + pd.name + " is of type " + pd.type + " but got " + exprType + " at " + e.posn);
} }
} }
@ -519,7 +516,6 @@ public class Analyzer implements Visitor<IdTable, Type> {
return new ArrayType(eltType, expr.posn); return new ArrayType(eltType, expr.posn);
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// REFERENCES // REFERENCES
@ -638,7 +634,6 @@ public class Analyzer implements Visitor<IdTable, Type> {
return ref.decl.type; return ref.decl.type;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// TERMINALS // TERMINALS
@ -709,7 +704,6 @@ public class Analyzer implements Visitor<IdTable, Type> {
return new BaseType(TypeKind.BOOLEAN, bool.posn); return new BaseType(TypeKind.BOOLEAN, bool.posn);
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// Convenience Functions // Convenience Functions

View File

@ -14,7 +14,6 @@ public class IdTable {
private IdTable parent; private IdTable parent;
private ArrayList<HashMap<String, Declaration>> scope; private ArrayList<HashMap<String, Declaration>> scope;
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// CONSTRUCTORS // CONSTRUCTORS
@ -38,7 +37,6 @@ public class IdTable {
push(); push();
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// ACTIVE SCOPE // ACTIVE SCOPE
@ -90,7 +88,6 @@ public class IdTable {
scope.get(scope.size() - 1).put(decl.name, decl); scope.get(scope.size() - 1).put(decl.name, decl);
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// GETTERS // GETTERS
@ -105,8 +102,10 @@ public class IdTable {
IdTable current = this; IdTable current = this;
while (current != null) { while (current != null) {
Declaration decl = current.getDeclarationAtScope(name); Declaration decl = current.getDeclarationAtScope(name);
if (decl == null) current = current.parent; if (decl == null)
else return decl; current = current.parent;
else
return decl;
} }
return null; return null;
@ -119,7 +118,8 @@ public class IdTable {
public Declaration getDeclarationAtScope(String name) { public Declaration getDeclarationAtScope(String name) {
for (int i = scope.size() - 1; i >= 0; i--) { for (int i = scope.size() - 1; i >= 0; i--) {
HashMap<String, Declaration> nest = scope.get(i); HashMap<String, Declaration> nest = scope.get(i);
if (nest.containsKey(name)) return nest.get(name); if (nest.containsKey(name))
return nest.get(name);
} }
return null; return null;

View File

@ -17,6 +17,7 @@ public class Reporter {
/** /**
* Redefinitions * Redefinitions
*
* @param d1 * @param d1
* @param d2 * @param d2
*/ */

View File

@ -11,15 +11,9 @@ import miniJava.AbstractSyntaxTrees.Package;
* *
* Program ::= (ClassDeclaration)* eot * Program ::= (ClassDeclaration)* eot
* *
* ClassDeclaration ::= * ClassDeclaration ::= class id { (Declarators id (; | MethodDeclaration))* }
* class id {
* (Declarators id (; | MethodDeclaration))*
* }
* *
* MethodDeclaration ::= * MethodDeclaration ::= (ParameterList?) { Statement* (return Expression ;)? }
* (ParameterList?) {
* Statement* (return Expression ;)?
* }
* *
* Declarators ::= (public | private)? static? Type * Declarators ::= (public | private)? static? Type
* *
@ -33,20 +27,13 @@ import miniJava.AbstractSyntaxTrees.Package;
* *
* BaseRef ::= this | id ([ Expression])? * BaseRef ::= this | id ([ Expression])?
* *
* Statement ::= * Statement ::= {Statement*} | Type id = Expression; | Reference = Expression;
* {Statement*} * | Reference ( ArgumentList? ); | if (Expression) Statement (else Statement)?
* | Type id = Expression;
* | Reference = Expression;
* | Reference ( ArgumentList? );
* | if (Expression) Statement (else Statement)?
* | while (Expression) Statement * | while (Expression) Statement
* *
* Expression ::= * Expression ::= num | true | false | ( Expression ) | new (id() | int [
* num | true | false * Expression ] | id [ Expression ] ) | Reference ((ArgumentList?))? |
* | ( Expression ) * DExpression
* | new (id() | int [ Expression ] | id [ Expression ] )
* | Reference ((ArgumentList?))?
* | DExpression
* *
* DExpression ::= CExpression (|| CExpression)* * DExpression ::= CExpression (|| CExpression)*
* *
@ -75,7 +62,6 @@ public class Parser {
this.stream = new LinkedList<Token>(); this.stream = new LinkedList<Token>();
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// Package // Package
@ -98,7 +84,6 @@ public class Parser {
return new Package(decls, new SourcePosition(0, 0)); return new Package(decls, new SourcePosition(0, 0));
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// DECLARATIONS // DECLARATIONS
@ -219,7 +204,6 @@ public class Parser {
return new MethodDecl(f, pdl, stl, returnExpr, f.posn); return new MethodDecl(f, pdl, stl, returnExpr, f.posn);
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// TYPES // TYPES
@ -279,7 +263,6 @@ public class Parser {
} }
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// Arguments // Arguments
@ -330,7 +313,6 @@ public class Parser {
return el; return el;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// REFERENCES // REFERENCES
@ -391,7 +373,6 @@ public class Parser {
return ref; return ref;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// STATEMENTS // STATEMENTS
@ -563,7 +544,6 @@ public class Parser {
} }
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// EXPRESSIONS // EXPRESSIONS
@ -661,12 +641,14 @@ public class Parser {
} }
} }
default: throw new ParsingException(peek(1).posn); default:
throw new ParsingException(peek(1).posn);
} }
} }
/** /**
* Disjunctive * Disjunctive
*
* @return * @return
* @throws IOException * @throws IOException
*/ */
@ -685,6 +667,7 @@ public class Parser {
/** /**
* Conjunctive * Conjunctive
*
* @return * @return
* @throws IOException * @throws IOException
*/ */
@ -703,6 +686,7 @@ public class Parser {
/** /**
* Equality * Equality
*
* @return * @return
* @throws IOException * @throws IOException
*/ */
@ -721,6 +705,7 @@ public class Parser {
/** /**
* Relational * Relational
*
* @return * @return
* @throws IOException * @throws IOException
*/ */
@ -728,8 +713,8 @@ public class Parser {
Expression expr = parseAExpression(); Expression expr = parseAExpression();
while(peek(1).spelling.equals("<") || peek(1).spelling.equals("<=") while (peek(1).spelling.equals("<") || peek(1).spelling.equals("<=") || peek(1).spelling.equals(">")
|| peek(1).spelling.equals(">") || peek(1).spelling.equals(">=")) { || peek(1).spelling.equals(">=")) {
Token next = accept(Token.TYPE.BINOP); Token next = accept(Token.TYPE.BINOP);
Operator o = new Operator(next, next.posn); Operator o = new Operator(next, next.posn);
expr = new BinaryExpr(o, expr, parseAExpression(), expr.posn); expr = new BinaryExpr(o, expr, parseAExpression(), expr.posn);
@ -740,6 +725,7 @@ public class Parser {
/** /**
* Additive * Additive
*
* @return * @return
* @throws IOException * @throws IOException
*/ */
@ -758,6 +744,7 @@ public class Parser {
/** /**
* Multiplicative * Multiplicative
*
* @return * @return
* @throws IOException * @throws IOException
*/ */
@ -774,7 +761,6 @@ public class Parser {
return expr; return expr;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// Convenience Methods // Convenience Methods
@ -807,8 +793,10 @@ public class Parser {
private Token accept(Token.TYPE type) throws IOException { private Token accept(Token.TYPE type) throws IOException {
Token next = peek(1); Token next = peek(1);
if(next.type == type) stream.poll(); if (next.type == type)
else throw new ParsingException(next.posn); stream.poll();
else
throw new ParsingException(next.posn);
return next; return next;
} }

View File

@ -36,7 +36,6 @@ public class Scanner {
this.predefined = predefined; this.predefined = predefined;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// Scanning // Scanning
@ -68,7 +67,8 @@ public class Scanner {
case '*': case '*':
case '+': case '+':
case '-': { case '-': {
if(peek(c)) throw new ScanningException(posn); if (peek(c))
throw new ScanningException(posn);
token = new Token(spelling, Token.TYPE.BINOP, posn); token = new Token(spelling, Token.TYPE.BINOP, posn);
break; break;
} }
@ -92,7 +92,8 @@ public class Scanner {
// Relational // Relational
case '>': case '>':
case '<': { case '<': {
if (peek('=')) spelling += (char) read(); if (peek('='))
spelling += (char) read();
token = new Token(spelling, Token.TYPE.BINOP, posn); token = new Token(spelling, Token.TYPE.BINOP, posn);
break; break;
} }
@ -193,8 +194,6 @@ public class Scanner {
return token; return token;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// Convenience Methods // Convenience Methods
@ -207,9 +206,7 @@ public class Scanner {
* @return * @return
*/ */
private boolean isAlpha(int c) { private boolean isAlpha(int c) {
return (c >= 'a' && c <= 'z') return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (predefined && c == '_');
|| (c >= 'A' && c <= 'Z')
|| (predefined && c == '_');
} }
/** /**

View File

@ -10,37 +10,10 @@ public class Token {
public enum TYPE { public enum TYPE {
// Terminals // Terminals
ID, ID, NUM, UNOP, BINOP, EQUALS, PERIOD, COMMA, LPAREN, RPAREN, LSQUARE, RSQUARE, LBRACKET, RBRACKET, SEMICOLON,
NUM,
UNOP,
BINOP,
EQUALS,
PERIOD,
COMMA,
LPAREN,
RPAREN,
LSQUARE,
RSQUARE,
LBRACKET,
RBRACKET,
SEMICOLON,
// Keywords // Keywords
IF, IF, ELSE, NEW, INT, VOID, THIS, TRUE, FALSE, CLASS, WHILE, RETURN, BOOLEAN, STATIC, PUBLIC, PRIVATE,
ELSE,
NEW,
INT,
VOID,
THIS,
TRUE,
FALSE,
CLASS,
WHILE,
RETURN,
BOOLEAN,
STATIC,
PUBLIC,
PRIVATE,
// End of Token Stream // End of Token Stream
EOT EOT
@ -48,6 +21,7 @@ public class Token {
// Pair words with enumeration // Pair words with enumeration
public final static HashMap<String, TYPE> keywords; public final static HashMap<String, TYPE> keywords;
static { static {
keywords = new HashMap<String, TYPE>(); keywords = new HashMap<String, TYPE>();
keywords.put("class", TYPE.CLASS); keywords.put("class", TYPE.CLASS);
@ -69,6 +43,7 @@ public class Token {
// Pair symbols with enumeration // Pair symbols with enumeration
public final static HashMap<Integer, TYPE> symbols; public final static HashMap<Integer, TYPE> symbols;
static { static {
symbols = new HashMap<Integer, TYPE>(); symbols = new HashMap<Integer, TYPE>();
symbols.put((int) '.', TYPE.PERIOD); symbols.put((int) '.', TYPE.PERIOD);

View File

@ -16,8 +16,7 @@ public class Checkpoint1 {
static ExecutorService threadPool = Executors.newCachedThreadPool(); static ExecutorService threadPool = Executors.newCachedThreadPool();
public static void main(String[] args) throws IOException, InterruptedException { public static void main(String[] args) throws IOException, InterruptedException {
File testDir = new File(System.getProperty("java.class.path") File testDir = new File(System.getProperty("java.class.path") + "/../tests/pa1_tests");
+ "/../tests/pa1_tests");
int failures = 0; int failures = 0;
for (File x : testDir.listFiles()) { for (File x : testDir.listFiles()) {
int returnCode = runTest(x); int returnCode = runTest(x);
@ -26,8 +25,7 @@ public class Checkpoint1 {
System.out.println(x.getName() + " passed successfully!"); System.out.println(x.getName() + " passed successfully!");
else { else {
failures++; failures++;
System.err.println(x.getName() System.err.println(x.getName() + " failed but should have passed!");
+ " failed but should have passed!");
} }
} else { } else {
if (returnCode == 4) if (returnCode == 4)
@ -42,7 +40,8 @@ public class Checkpoint1 {
} }
private static int runTest(File x) throws IOException, InterruptedException { private static int runTest(File x) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath()).directory(new File(System.getProperty("java.class.path"))); ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath())
.directory(new File(System.getProperty("java.class.path")));
Process p = pb.start(); Process p = pb.start();
threadPool.execute(new ProcessOutputter(p.getInputStream(), false)); threadPool.execute(new ProcessOutputter(p.getInputStream(), false));
p.waitFor(); p.waitFor();
@ -57,6 +56,7 @@ public class Checkpoint1 {
processOutput = new Scanner(_processStream); processOutput = new Scanner(_processStream);
output = _output; output = _output;
} }
@Override @Override
public void run() { public void run() {
while (processOutput.hasNextLine()) { while (processOutput.hasNextLine()) {
@ -66,6 +66,5 @@ public class Checkpoint1 {
} }
} }
} }
} }

View File

@ -17,6 +17,7 @@ public class Checkpoint2 {
private static class ReturnInfo { private static class ReturnInfo {
int returnCode; int returnCode;
String ast; String ast;
public ReturnInfo(int _returnCode, String _ast) { public ReturnInfo(int _returnCode, String _ast) {
returnCode = _returnCode; returnCode = _returnCode;
ast = _ast; ast = _ast;
@ -24,8 +25,7 @@ public class Checkpoint2 {
} }
public static void main(String[] args) throws IOException, InterruptedException { public static void main(String[] args) throws IOException, InterruptedException {
File testDir = new File(System.getProperty("java.class.path") File testDir = new File(System.getProperty("java.class.path") + "/../tests/pa2_tests");
+ "/../tests/pa2_tests");
int failures = 0; int failures = 0;
for (File x : testDir.listFiles()) { for (File x : testDir.listFiles()) {
if (x.getName().endsWith("out") || x.getName().startsWith(".")) if (x.getName().endsWith("out") || x.getName().startsWith("."))
@ -42,11 +42,9 @@ public class Checkpoint2 {
System.err.println(x.getName() + " parsed successfully but has an incorrect AST!"); System.err.println(x.getName() + " parsed successfully but has an incorrect AST!");
failures++; failures++;
} }
} } else {
else {
failures++; failures++;
System.err.println(x.getName() System.err.println(x.getName() + " failed to be parsed!");
+ " failed to be parsed!");
} }
} else { } else {
if (returnCode == 4) if (returnCode == 4)
@ -61,7 +59,8 @@ public class Checkpoint2 {
} }
private static ReturnInfo runTest(File x) throws IOException, InterruptedException { private static ReturnInfo runTest(File x) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath()).directory(new File(System.getProperty("java.class.path"))); ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath())
.directory(new File(System.getProperty("java.class.path")));
pb.redirectErrorStream(true); pb.redirectErrorStream(true);
Process p = pb.start(); Process p = pb.start();
@ -71,7 +70,6 @@ public class Checkpoint2 {
return new ReturnInfo(exitValue, ast); return new ReturnInfo(exitValue, ast);
} }
public static String getAST(InputStream stream) { public static String getAST(InputStream stream) {
Scanner scan = new Scanner(stream); Scanner scan = new Scanner(stream);
String ast = null; String ast = null;

View File

@ -5,7 +5,6 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Scanner; import java.util.Scanner;
/* Automated regression tester for Checkpoint 3 tests /* Automated regression tester for Checkpoint 3 tests
* Created by Max Beckman-Harned * Created by Max Beckman-Harned
* Put your tests in "tests/pa3_tests" folder in your Eclipse workspace directory * Put your tests in "tests/pa3_tests" folder in your Eclipse workspace directory
@ -14,23 +13,20 @@ import java.util.Scanner;
public class Checkpoint3 { public class Checkpoint3 {
public static void main(String[] args) throws IOException, InterruptedException { public static void main(String[] args) throws IOException, InterruptedException {
File testDir = new File(System.getProperty("java.class.path") File testDir = new File(System.getProperty("java.class.path") + "/../tests/pa3_tests");
+ "/../tests/pa3_tests");
int failures = 0; int failures = 0;
for (File x : testDir.listFiles()) { for (File x : testDir.listFiles()) {
if (x.getName().endsWith("out") || x.getName().startsWith(".") || x.getName().endsWith("mJAM") || x.getName().endsWith("asm")) if (x.getName().endsWith("out") || x.getName().startsWith(".") || x.getName().endsWith("mJAM")
|| x.getName().endsWith("asm"))
continue; continue;
int returnCode = runTest(x); int returnCode = runTest(x);
if (x.getName().indexOf("pass") != -1) { if (x.getName().indexOf("pass") != -1) {
if (returnCode == 0) { if (returnCode == 0) {
System.out.println(x.getName() + " processed successfully!"); System.out.println(x.getName() + " processed successfully!");
} } else {
else {
failures++; failures++;
System.err.println(x.getName() System.err.println(x.getName() + " failed to be processed!");
+ " failed to be processed!");
} }
} else { } else {
if (returnCode == 4) if (returnCode == 4)
@ -45,7 +41,8 @@ public class Checkpoint3 {
} }
private static int runTest(File x) throws IOException, InterruptedException { private static int runTest(File x) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath()).directory(new File(System.getProperty("java.class.path"))); ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath())
.directory(new File(System.getProperty("java.class.path")));
pb.redirectErrorStream(true); pb.redirectErrorStream(true);
Process p = pb.start(); Process p = pb.start();
@ -55,7 +52,6 @@ public class Checkpoint3 {
return exitValue; return exitValue;
} }
public static void processStream(InputStream stream) { public static void processStream(InputStream stream) {
Scanner scan = new Scanner(stream); Scanner scan = new Scanner(stream);
while (scan.hasNextLine()) { while (scan.hasNextLine()) {

View File

@ -5,7 +5,6 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Scanner; import java.util.Scanner;
/* Automated regression tester for Checkpoint 4 tests /* Automated regression tester for Checkpoint 4 tests
* Created by Max Beckman-Harned * Created by Max Beckman-Harned
* Put your tests in "tests/pa4_tests" folder in your Eclipse workspace directory * Put your tests in "tests/pa4_tests" folder in your Eclipse workspace directory
@ -14,10 +13,8 @@ import java.util.Scanner;
public class Checkpoint4 { public class Checkpoint4 {
public static void main(String[] args) throws IOException, InterruptedException { public static void main(String[] args) throws IOException, InterruptedException {
File testDir = new File(System.getProperty("java.class.path") File testDir = new File(System.getProperty("java.class.path") + "/../tests/pa4_tests");
+ "/../tests/pa4_tests");
int failures = 0; int failures = 0;
for (File x : testDir.listFiles()) { for (File x : testDir.listFiles()) {
if (x.getName().startsWith(".") || x.getName().endsWith("mJAM") || x.getName().endsWith("asm")) if (x.getName().startsWith(".") || x.getName().endsWith("mJAM") || x.getName().endsWith("asm"))
@ -32,18 +29,16 @@ public class Checkpoint4 {
System.out.println(x.getName() + " ran successfully!"); System.out.println(x.getName() + " ran successfully!");
else { else {
failures++; failures++;
System.err.println(x.getName() + " compiled but did not run successfully--got output " + val); System.err
.println(x.getName() + " compiled but did not run successfully--got output " + val);
} }
} } catch (Exception ex) {
catch(Exception ex) {
failures++; failures++;
System.err.println(x.getName() + " did not output correctly."); System.err.println(x.getName() + " did not output correctly.");
} }
} } else {
else {
failures++; failures++;
System.err.println(x.getName() System.err.println(x.getName() + " failed to be processed!");
+ " failed to be processed!");
} }
} else { } else {
if (returnCode == 4) if (returnCode == 4)
@ -58,7 +53,8 @@ public class Checkpoint4 {
} }
private static int runTest(File x) throws IOException, InterruptedException { private static int runTest(File x) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath()).directory(new File(System.getProperty("java.class.path"))); ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath())
.directory(new File(System.getProperty("java.class.path")));
pb.redirectErrorStream(true); pb.redirectErrorStream(true);
Process p = pb.start(); Process p = pb.start();
@ -69,7 +65,8 @@ public class Checkpoint4 {
} }
private static int executeTest(File x) throws IOException, InterruptedException { private static int executeTest(File x) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("java", "mJAM.Interpreter", x.getPath().replace(".java", ".mJAM")).directory(new File(System.getProperty("java.class.path"))); ProcessBuilder pb = new ProcessBuilder("java", "mJAM.Interpreter", x.getPath().replace(".java", ".mJAM"))
.directory(new File(System.getProperty("java.class.path")));
Process process = pb.start(); Process process = pb.start();
Scanner scan = new Scanner(process.getInputStream()); Scanner scan = new Scanner(process.getInputStream());
@ -94,7 +91,6 @@ public class Checkpoint4 {
return num; return num;
} }
public static void processStream(InputStream stream) { public static void processStream(InputStream stream) {
Scanner scan = new Scanner(stream); Scanner scan = new Scanner(stream);
while (scan.hasNextLine()) { while (scan.hasNextLine()) {