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

@ -1,5 +1,5 @@
package mJAM; package mJAM;
public class Assembler { public class Assembler {
// TBD // TBD
} }

View File

@ -13,297 +13,307 @@ 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
*/ */
public class Disassembler { public class Disassembler {
private String objectFileName; private String objectFileName;
private String asmName; private String asmName;
private FileWriter asmOut; private FileWriter asmOut;
private boolean error = false; private boolean error = false;
private Map<Integer, String> addrToLabel; private Map<Integer, String> addrToLabel;
public Disassembler(String objectFileName) { public Disassembler(String objectFileName) {
this.objectFileName = objectFileName; this.objectFileName = objectFileName;
} }
/** /**
* 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
private void writeR(char leftbracket, int r, char rightbracket) { * the number of the register.
asmWrite(Character.toString(leftbracket)); * @param rightbracket
asmWrite(Machine.intToReg[r].toString()); * the character to print after the register.
asmWrite(Character.toString(rightbracket)); */
} private void writeR(char leftbracket, int r, char rightbracket) {
asmWrite(Character.toString(leftbracket));
asmWrite(Machine.intToReg[r].toString());
asmWrite(Character.toString(rightbracket));
}
/** /**
* Writes a void n-field of an instruction. * Writes a void n-field of an instruction.
*/ */
private void blankN() { private void blankN() {
asmWrite(" "); asmWrite(" ");
} }
// 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
private void writeN(int n) { * the integer to write.
asmWrite(String.format("%-6s","(" + n + ")")); */
} private void writeN(int n) {
asmWrite(String.format("%-6s", "(" + n + ")"));
}
/** /**
* Writes the d-field of an instruction. * Writes the d-field of an instruction.
* @param d the integer to write. *
*/ * @param d
private void writeD(int d) { * the integer to write.
asmWrite(Integer.toString(d)); */
} private void writeD(int d) {
asmWrite(Integer.toString(d));
}
/** /**
* 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
private void writePrimitive(int d) { * the displacment of the primitive routine.
Machine.Prim prim = Machine.intToPrim[d]; */
asmWrite(String.format("%-8s",prim.toString())); private void writePrimitive(int d) {
} Machine.Prim prim = Machine.intToPrim[d];
asmWrite(String.format("%-8s", prim.toString()));
}
/** /**
* Writes the given instruction in assembly-code format. * Writes the given instruction in assembly-code format.
* @param instr the instruction to display. *
*/ * @param instr
private void writeInstruction(Instruction instr) { * the instruction to display.
*/
private void writeInstruction(Instruction instr) {
String targetLabel = "***"; String targetLabel = "***";
// get label of destination addr, if instr transfers control // get label of destination addr, if instr transfers control
if (instr.r == Machine.Reg.CB.ordinal()) if (instr.r == Machine.Reg.CB.ordinal())
targetLabel = addrToLabel.get(instr.d); targetLabel = addrToLabel.get(instr.d);
Machine.Op instruction = Machine.intToOp[instr.op]; Machine.Op instruction = Machine.intToOp[instr.op];
asmWrite(String.format("%-7s",instruction.toString())); asmWrite(String.format("%-7s", instruction.toString()));
switch (instruction) { switch (instruction) {
case LOAD: case LOAD:
blankN(); blankN();
writeD(instr.d); writeD(instr.d);
writeR('[', instr.r, ']'); writeR('[', instr.r, ']');
break; break;
case LOADA: case LOADA:
blankN(); blankN();
writeD(instr.d); writeD(instr.d);
writeR('[', instr.r, ']'); writeR('[', instr.r, ']');
break; break;
case LOADI: case LOADI:
break; break;
case LOADL: case LOADL:
blankN(); blankN();
writeD(instr.d); writeD(instr.d);
break; break;
case STORE: case STORE:
blankN(); blankN();
writeD(instr.d); writeD(instr.d);
writeR('[', instr.r, ']'); writeR('[', instr.r, ']');
break; break;
case STOREI: case STOREI:
break; break;
case CALL: case CALL:
if (instr.r == Machine.Reg.PB.ordinal()) { if (instr.r == Machine.Reg.PB.ordinal()) {
blankN(); blankN();
writePrimitive(instr.d); writePrimitive(instr.d);
} else { } else {
blankN(); blankN();
asmWrite(targetLabel); asmWrite(targetLabel);
} }
break; break;
case CALLI: case CALLI:
blankN(); blankN();
asmWrite(targetLabel); asmWrite(targetLabel);
break; break;
case RETURN: case RETURN:
writeN(instr.n); writeN(instr.n);
writeD(instr.d); writeD(instr.d);
break; break;
case CALLD: case CALLD:
blankN(); blankN();
writeD(instr.d); writeD(instr.d);
break; break;
case PUSH: case PUSH:
blankN(); blankN();
writeD(instr.d); writeD(instr.d);
break; break;
case POP: case POP:
blankN(); blankN();
writeD(instr.d); writeD(instr.d);
break; break;
case JUMP: case JUMP:
blankN(); blankN();
asmWrite(targetLabel); asmWrite(targetLabel);
break; break;
case JUMPI: case JUMPI:
break; break;
case JUMPIF: case JUMPIF:
writeN(instr.n); writeN(instr.n);
asmWrite(targetLabel); asmWrite(targetLabel);
break; break;
case HALT: case HALT:
writeN(instr.n); writeN(instr.n);
break; break;
default: default:
asmWrite("???? "); asmWrite("???? ");
writeN(instr.n); writeN(instr.n);
writeD(instr.d); writeD(instr.d);
writeR('[', instr.r, ']'); writeR('[', instr.r, ']');
break; break;
} }
} }
/** /**
* disassembles program held in code store * disassembles program held in code store
*/ */
void disassembleProgram(String asmFileName) { void disassembleProgram(String asmFileName) {
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; }
}
// collect all addresses that may be the target of a jump instruction // collect all addresses that may be the target of a jump instruction
SortedSet<Integer> targets = new TreeSet<Integer>(); SortedSet<Integer> targets = new TreeSet<Integer>();
for (int addr = Machine.CB; addr < Machine.CT; addr++) { for (int addr = Machine.CB; addr < Machine.CT; addr++) {
Instruction inst = Machine.code[addr]; Instruction inst = Machine.code[addr];
Machine.Op op = Machine.intToOp[inst.op]; Machine.Op op = Machine.intToOp[inst.op];
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
if (inst.r == Machine.Reg.CB.ordinal()) // primitives)
targets.add(inst.d); if (inst.r == Machine.Reg.CB.ordinal())
break; targets.add(inst.d);
case JUMP: break;
// address following an unconditional branch is an implicit target case JUMP:
targets.add(addr+1); // address following an unconditional branch is an implicit
targets.add(inst.d); // target
break; targets.add(addr + 1);
case JUMPIF: targets.add(inst.d);
// a jump of any sort creates a branch target break;
targets.add(inst.d); case JUMPIF:
break; // a jump of any sort creates a branch target
default: targets.add(inst.d);
break; break;
} default:
} break;
}
}
// map branch target addresses to unique labels // map branch target addresses to unique labels
addrToLabel = new HashMap<Integer, String>(); addrToLabel = new HashMap<Integer, String>();
int labelCounter = 10; int labelCounter = 10;
for (Integer addr : targets) { for (Integer addr : targets) {
String label = "L" + labelCounter++ ; String label = "L" + labelCounter++;
addrToLabel.put(addr, label); addrToLabel.put(addr, label);
} }
// disassemble each instruction // disassemble each instruction
for (int addr = Machine.CB; addr < Machine.CT; addr++) { for (int addr = Machine.CB; addr < Machine.CT; addr++) {
// generate instruction address // generate instruction address
asmWrite(String.format("%3d ", addr)); asmWrite(String.format("%3d ", addr));
// if this addr is a branch target, output label // if this addr is a branch target, output label
if (addrToLabel.containsKey(addr)) if (addrToLabel.containsKey(addr))
asmWrite(String.format("%-7s", addrToLabel.get(addr) + ":")); asmWrite(String.format("%-7s", addrToLabel.get(addr) + ":"));
else else
asmWrite(" "); asmWrite(" ");
// instruction // instruction
writeInstruction(Machine.code[addr]); writeInstruction(Machine.code[addr]);
// newline // newline
asmWrite("\n"); asmWrite("\n");
} }
// close output file // close output file
try { try {
asmOut.close(); asmOut.close();
} catch (IOException e) { } catch (IOException e) {
error = true; error = true;
} }
} }
private void asmWrite(String s) { private void asmWrite(String s) {
try { try {
asmOut.write(s); asmOut.write(s);
} catch (IOException e) { } catch (IOException e) {
error = true; error = true;
} }
} }
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("********** mJAM Disassembler (1.0) **********"); System.out.println("********** mJAM Disassembler (1.0) **********");
String objectFileName = "obj.mJAM"; String objectFileName = "obj.mJAM";
if (args.length == 1) if (args.length == 1)
objectFileName = args[0]; objectFileName = args[0];
Disassembler d = new Disassembler(objectFileName); Disassembler d = new Disassembler(objectFileName);
d.disassemble(); d.disassemble();
} }
/** /**
* Disassemble object file * Disassemble object file
* @return true if error encountered else false *
*/ * @return true if error encountered else false
public boolean disassemble() { */
ObjectFile objectFile = new ObjectFile(objectFileName); public boolean disassemble() {
ObjectFile objectFile = new ObjectFile(objectFileName);
// 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";
// disassemble to file // disassemble to file
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; }
}
return false; return false;
} }
} }

View File

@ -7,30 +7,30 @@ package mJAM;
public class Instruction { public class Instruction {
public Instruction() { public Instruction() {
op = 0; op = 0;
r = 0; r = 0;
n = 0; n = 0;
d = 0; d = 0;
} }
public Instruction(int op, int n, int r, int d) { public Instruction(int op, int n, int r, int d) {
this.op = op; this.op = op;
this.n = n; this.n = n;
this.r = r; this.r = r;
this.d = d; this.d = d;
} }
// Java has no type synonyms, so the following representations are // Java has no type synonyms, so the following representations are
// assumed: // assumed:
// //
// type // type
// OpCode = 0..15; {4 bits unsigned} // OpCode = 0..15; {4 bits unsigned}
// Register = 0..15; (4 bits unsigned) // Register = 0..15; (4 bits unsigned)
// Length = 0..255; {8 bits unsigned} // Length = 0..255; {8 bits unsigned}
// Operand = -2147483648 .. +2147483647; (32 bits signed for use with LOADL) // Operand = -2147483648 .. +2147483647; (32 bits signed for use with LOADL)
public int op; // OpCode public int op; // OpCode
public int r; // RegisterNumber public int r; // RegisterNumber
public int n; // Length public int n; // Length
public int d; // Operand public int d; // Operand
} }

File diff suppressed because it is too large Load Diff

View File

@ -2,231 +2,188 @@ 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
*/ */
public final class Machine { 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, CALLI, // indirect call of instance method
LOADL, CALLD, // dynamic call of instance method
STORE, RETURN, PUSH, POP, JUMP, JUMPI, JUMPIF, HALT;
STOREI,
CALL, // direct call of instance method
CALLI, // indirect call of instance method
CALLD, // dynamic call of instance method
RETURN,
PUSH,
POP,
JUMP,
JUMPI,
JUMPIF,
HALT;
}
public static Op [] intToOp = Op.values();
/**
* mJAM registers
*/
public enum Reg {
ZR, // zero, not used
CB, // code base
CT, // code top
CP, // code pointer
PB, // primitives base
PT, // primitives top
SB, // execution stack base
ST, // execution stack top
LB, // locals base
HB, // heap base
HT, // heap top
OB; // object base
}
public static Reg [] intToReg = Reg.values();
/**
* mJAM primitives
*/
public enum Prim {
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;
}
public static Prim [] intToPrim = Prim.values();
// range for int constants
public final static long
minintRep = -2147483648,
maxintRep = 2147483647;
// CODE STORE REGISTERS
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 PT = PB + Prim.values().length; // code space reserved for primitives
// CODE STORE
public static Instruction[] code = new Instruction[PB];
public static int CT = CB;
public static void initCodeGen() {
CT = CB;
}
/**
* Places an instruction, with the given fields, into the next position in the code store
* @param op - operation
* @param n - length
* @param r - register
* @param d - displacement
*/
public static void emit(Op op, int n, Reg r, Prim d) {
emit(op.ordinal(), n, r.ordinal(), d.ordinal());
}
/**
* emit operation with single literal argument d (n,r not used). These are
* operations like LOADL 44, PUSH 3, and CALLD 1
*/
public static void emit(Op op, int d) {
emit(op.ordinal(), 0, 0, d);
}
/**
* emit "call primitive operation" (operation built-in to mJAM). This
* generates CALL primitiveop[PB]
*/
public static void emit(Prim d) {
emit(Op.CALL.ordinal(), 0, Machine.Reg.PB.ordinal(), d.ordinal());
}
/**
* emit operations without arguments. These are operations like
* LOADI and STOREI
*/
public static void emit(Op op) {
emit(op, 0, 0, 0);
}
/**
* emit operation with register r and integer displacement. These are
* operations like JUMP 25[CB] and LOAD 6[LB]
*/
public static void emit(Op op, Reg r, int d) {
emit(op.ordinal(), 0, r.ordinal(), d);
}
/**
* emit operation with n field, and register r and integer displacement. These are
* operations like JUMPIF (1) 25[CB]. In the assembly code the value of n is shown
* in parens.
*/
public static void emit(Op op, int n, Reg r, int d) {
emit(op.ordinal(), n, r.ordinal(), d);
}
/**
* emit operation with integer n, r, d. These are operations
* like RETURN (1) 3 and HALT (4) 0. For RETURN the value
* of d is the number of caller args to pop off the callers
* stack and n is the number of values to return at caller stack
* top. n must be 0 or 1.
*/
public static void emit(Op op, int n, int r, int d) {
emit(op.ordinal(), n, r, d);
}
/**
* helper operation for emit using integer values
*/
private static void emit (int op, int n, int r, int d) {
if (n > 255) {
System.out.println("length of operand can't exceed 255 words");
n = 255; // to allow code generation to continue
} }
if (CT >= Machine.PB)
System.out.println("mJAM: code segment capacity exceeded");
Instruction nextInstr = new Instruction(op, n, r, d); public static Op[] intToOp = Op.values();
/**
* mJAM registers
*/
public enum Reg {
ZR, // zero, not used
CB, // code base
CT, // code top
CP, // code pointer
PB, // primitives base
PT, // primitives top
SB, // execution stack base
ST, // execution stack top
LB, // locals base
HB, // heap base
HT, // heap top
OB; // object base
}
public static Reg[] intToReg = Reg.values();
/**
* mJAM primitives
*/
public enum Prim {
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;
}
public static Prim[] intToPrim = Prim.values();
// range for int constants
public final static long minintRep = -2147483648, maxintRep = 2147483647;
// CODE STORE REGISTERS
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 PT = PB + Prim.values().length; // code space
// reserved for
// primitives
// CODE STORE
public static Instruction[] code = new Instruction[PB];
public static int CT = CB;
public static void initCodeGen() {
CT = CB;
}
/**
* Places an instruction, with the given fields, into the next position in
* the code store
*
* @param op
* - operation
* @param n
* - length
* @param r
* - register
* @param d
* - displacement
*/
public static void emit(Op op, int n, Reg r, Prim d) {
emit(op.ordinal(), n, r.ordinal(), d.ordinal());
}
/**
* emit operation with single literal argument d (n,r not used). These are
* operations like LOADL 44, PUSH 3, and CALLD 1
*/
public static void emit(Op op, int d) {
emit(op.ordinal(), 0, 0, d);
}
/**
* emit "call primitive operation" (operation built-in to mJAM). This
* generates CALL primitiveop[PB]
*/
public static void emit(Prim d) {
emit(Op.CALL.ordinal(), 0, Machine.Reg.PB.ordinal(), d.ordinal());
}
/**
* emit operations without arguments. These are operations like LOADI and
* STOREI
*/
public static void emit(Op op) {
emit(op, 0, 0, 0);
}
/**
* emit operation with register r and integer displacement. These are
* operations like JUMP 25[CB] and LOAD 6[LB]
*/
public static void emit(Op op, Reg r, int d) {
emit(op.ordinal(), 0, r.ordinal(), d);
}
/**
* emit operation with n field, and register r and integer displacement.
* These are operations like JUMPIF (1) 25[CB]. In the assembly code the
* value of n is shown in parens.
*/
public static void emit(Op op, int n, Reg r, int d) {
emit(op.ordinal(), n, r.ordinal(), d);
}
/**
* emit operation with integer n, r, d. These are operations like RETURN (1)
* 3 and HALT (4) 0. For RETURN the value of d is the number of caller args
* to pop off the callers stack and n is the number of values to return at
* caller stack top. n must be 0 or 1.
*/
public static void emit(Op op, int n, int r, int d) {
emit(op.ordinal(), n, r, d);
}
/**
* helper operation for emit using integer values
*/
private static void emit(int op, int n, int r, int d) {
if (n > 255) {
System.out.println("length of operand can't exceed 255 words");
n = 255; // to allow code generation to continue
}
if (CT >= Machine.PB)
System.out.println("mJAM: code segment capacity exceeded");
Instruction nextInstr = new Instruction(op, n, r, d);
Machine.code[CT] = nextInstr; Machine.code[CT] = nextInstr;
CT = CT + 1; CT = CT + 1;
} }
/** /**
* @return address (relative to CB) of next instruction to be generated * @return address (relative to CB) of next instruction to be generated
*/ */
public static int nextInstrAddr() { public static int nextInstrAddr() {
return CT; return CT;
} }
/** /**
* Update the displacement component of the (JUMP or CALL) instruction at addr * Update the displacement component of the (JUMP or CALL) instruction at
* @param addr * addr
* @param displacement *
*/ * @param addr
public static void patch(int addr, int displacement) { * @param displacement
if (addr < 0 || addr >= CT) { */
System.out.println("patch: address of instruction to be patched is out of range"); public static void patch(int addr, int displacement) {
return; if (addr < 0 || addr >= CT) {
} System.out.println("patch: address of instruction to be patched is out of range");
if (displacement < 0 || displacement > CT) { return;
System.out.println("patch: target address of patch is out of range"); }
return; if (displacement < 0 || displacement > CT) {
} System.out.println("patch: target address of patch is out of range");
Machine.code[addr].d = displacement; return;
return; }
} Machine.code[addr].d = displacement;
return;
}
// DATA REPRESENTATION // DATA REPRESENTATION
public final static int public final static int booleanSize = 1, characterSize = 1, integerSize = 1, addressSize = 1,
booleanSize = 1, linkDataSize = 3 * addressSize, // caller's OB, LB, CP
characterSize = 1, falseRep = 0, trueRep = 1, nullRep = 0;
integerSize = 1,
addressSize = 1,
linkDataSize = 3 * addressSize, // caller's OB, LB, CP
falseRep = 0,
trueRep = 1,
nullRep = 0;
} }

View File

@ -12,59 +12,63 @@ import java.io.DataOutputStream;
public class ObjectFile { public class ObjectFile {
String objectFileName; String objectFileName;
public ObjectFile(String objectFileName) { public ObjectFile(String objectFileName) {
super(); super();
this.objectFileName = objectFileName; this.objectFileName = objectFileName;
} }
/** /**
* Write code store as object file * Write code store as object file
* @param output object file *
* @return true if write fails * @param output
*/ * object file
public boolean write(){ * @return true if write fails
boolean failed = false; */
try { public boolean write() {
FileOutputStream objectFile = new FileOutputStream(objectFileName); boolean failed = false;
DataOutputStream is = new DataOutputStream(objectFile); try {
for (int i = Machine.CB; i < Machine.CT; i++ ){ FileOutputStream objectFile = new FileOutputStream(objectFileName);
Instruction inst = Machine.code[i]; DataOutputStream is = new DataOutputStream(objectFile);
is.writeInt(inst.op); for (int i = Machine.CB; i < Machine.CT; i++) {
is.writeInt(inst.n); Instruction inst = Machine.code[i];
is.writeInt(inst.r); is.writeInt(inst.op);
is.writeInt(inst.d); is.writeInt(inst.n);
} is.writeInt(inst.r);
objectFile.close(); is.writeInt(inst.d);
} }
catch (Exception e) {failed = true;} objectFile.close();
return failed; } catch (Exception e) {
} failed = true;
}
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() { */
boolean failed = false; public boolean read() {
try { boolean failed = false;
FileInputStream objectFile = new FileInputStream(objectFileName); try {
DataInputStream is = new DataInputStream(objectFile); FileInputStream objectFile = new FileInputStream(objectFileName);
DataInputStream is = new DataInputStream(objectFile);
Machine.CT = Machine.CB; Machine.CT = Machine.CB;
while (is.available() > 0 && Machine.CT < Machine.PB){ while (is.available() > 0 && Machine.CT < Machine.PB) {
Instruction inst = new Instruction(); Instruction inst = new Instruction();
inst.op = is.readInt(); inst.op = is.readInt();
inst.n = is.readInt(); inst.n = is.readInt();
inst.r = is.readInt(); inst.r = is.readInt();
inst.d = is.readInt(); inst.d = is.readInt();
Machine.code[Machine.CT++] = inst; Machine.code[Machine.CT++] = inst;
} }
objectFile.close(); objectFile.close();
} catch (Exception e) { } catch (Exception e) {
failed = true; failed = true;
} }
return failed; return failed;
} }
} }

View File

@ -4,154 +4,147 @@
* @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(Prim.putintnl);
Machine.emit(Op.LOADL,11); // hello int patchme_coA = Machine.nextInstrAddr();
Machine.emit(Prim.putintnl); Machine.emit(Op.JUMP, Reg.CB, 0); // jump around methods of class A
int patchme_coA = Machine.nextInstrAddr(); // (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
Machine.emit(Op.HALT,4,0,0); // instance of A
Machine.emit(Op.RETURN,1,0,0); // return one value, pop zero args Machine.emit(Op.HALT, 4, 0, 0);
Machine.emit(Op.RETURN, 1, 0, 0); // return one value, pop zero args
// build class object for A at 0[SB] // build class object for A at 0[SB]
int label_coA = Machine.nextInstrAddr(); int label_coA = Machine.nextInstrAddr();
Machine.patch(patchme_coA, label_coA); Machine.patch(patchme_coA, label_coA);
/*coA*/ Machine.emit(Op.LOADL,-1); // no superclass object /* coA */ Machine.emit(Op.LOADL, -1); // no 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_pA); // code addr of p_A Machine.emit(Op.LOADA, Reg.CB, label_pA); // code addr of p_A
/*
* class B extends A { int y; int p(){return x + 22;} }
*/
int patchme_coB = Machine.nextInstrAddr();
Machine.emit(Op.JUMP, Reg.CB, 0); // branch around methods in class B
/* class B extends A { // code for p() in B
* int y; int label_pB = Machine.nextInstrAddr();
* int p(){return x + 22;} /* pB */ Machine.emit(Op.LOAD, Reg.OB, 0); // x at offset 0 in current
* } // instance
*/ Machine.emit(Op.LOADL, 22);
int patchme_coB = Machine.nextInstrAddr(); Machine.emit(Op.HALT, 4, 0, 0);
Machine.emit(Op.JUMP,Reg.CB,0); // branch around methods in class B Machine.emit(Prim.add);
Machine.emit(Op.RETURN, 1, 0, 0); // return one value, pop zero args
// code for p() in B // build class object for B at 3[SB]
int label_pB = Machine.nextInstrAddr(); int label_coB = Machine.nextInstrAddr();
/*pB*/ Machine.emit(Op.LOAD,Reg.OB,0); // x at offset 0 in current instance Machine.patch(patchme_coB, label_coB);
Machine.emit(Op.LOADL,22); /* coB */ Machine.emit(Op.LOADA, Reg.SB, 0); // addr of superclass
Machine.emit(Op.HALT,4,0,0); // object
Machine.emit(Prim.add); Machine.emit(Op.LOADL, 1); // number of methods
Machine.emit(Op.RETURN,1,0,0); // return one value, pop zero args Machine.emit(Op.LOADA, Reg.CB, label_pB); // code addr of p_B
// build class object for B at 3[SB] /*
int label_coB = Machine.nextInstrAddr(); * class C { public static void main(String [] args) { A a = new A();
Machine.patch(patchme_coB, label_coB); * a.x = 33; System.out.println(a.p()); ...
/*coB*/ Machine.emit(Op.LOADA,Reg.SB,0); // addr of superclass object */
Machine.emit(Op.LOADL,1); // number of methods int patchme_coC = Machine.nextInstrAddr();
Machine.emit(Op.LOADA,Reg.CB,label_pB); // code addr of p_B Machine.emit(Op.JUMP, Reg.CB, 0); // branch around methods of class C
// code for main() in C
int label_mainC = Machine.nextInstrAddr();
/* mainC */ Machine.emit(Op.HALT, 4, 0, 0);
// local var "a" will be at 3[LB] after init
Machine.emit(Op.LOADA, Reg.SB, 0); // class descriptor for A
Machine.emit(Op.LOADL, 1); // size of A
Machine.emit(Prim.newobj); // result addr becomes value of "a"
Machine.emit(Op.LOAD, Reg.LB, 3); // value of "a" (heap addr)
Machine.emit(Op.LOADL, 0); // "x" is field 0 in A
Machine.emit(Op.LOADL, 33); // new value 33
Machine.emit(Op.HALT, 4, 0, 0);
Machine.emit(Prim.fieldupd); // a.x = 33
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(Prim.putintnl); // print result
/* class C { /*
* public static void main(String [] args) { * ... A b = new B(); b.x = 44; System.out.println(b.p()); } // end main
* A a = new A(); * } // end class C
* a.x = 33; */
* System.out.println(a.p()); // local var "b" will be at 4[LB] after init
* ... Machine.emit(Op.LOADA, Reg.SB, 3); // class descriptor for B
*/ Machine.emit(Op.LOADL, 2); // size of B
int patchme_coC = Machine.nextInstrAddr(); Machine.emit(Prim.newobj); // result addr becomes value of "b"
Machine.emit(Op.JUMP,Reg.CB,0); // branch around methods of class C Machine.emit(Op.LOAD, Reg.LB, 4); // fetch b
Machine.emit(Op.LOADL, 0); // field 0
Machine.emit(Op.LOADL, 44); // b.x = 44
Machine.emit(Prim.fieldupd);
Machine.emit(Op.HALT, 4, 0, 0);
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(Prim.putintnl); // print result
Machine.emit(Op.RETURN, 0, 0, 1); // return no value (void), pop 1 arg
// (= String [] args)
// code for main() in C // build class descriptor for C at 6[SB]
int label_mainC = Machine.nextInstrAddr(); int label_coC = Machine.nextInstrAddr();
/*mainC*/ Machine.emit(Op.HALT,4,0,0); Machine.patch(patchme_coC, label_coC);
// local var "a" will be at 3[LB] after init /* coC */ Machine.emit(Op.LOADL, -1); // no superclass object
Machine.emit(Op.LOADA,Reg.SB,0); // class descriptor for A Machine.emit(Op.LOADL, 0); // number of methods = 0
Machine.emit(Op.LOADL,1); // size of A
Machine.emit(Prim.newobj); // result addr becomes value of "a"
Machine.emit(Op.LOAD,Reg.LB,3); // value of "a" (heap addr)
Machine.emit(Op.LOADL,0); // "x" is field 0 in A
Machine.emit(Op.LOADL,33); // new value 33
Machine.emit(Op.HALT,4,0,0);
Machine.emit(Prim.fieldupd); // a.x = 33
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(Prim.putintnl); // print result
/* ... /*
* A b = new B(); * End of class declarations - call main
* b.x = 44; */
* System.out.println(b.p()); Machine.emit(Op.LOADL, Machine.nullRep); // put null on stack as value
* } // end main // of main's arg
* } // end class C Machine.emit(Op.CALL, Reg.CB, label_mainC); // call known static main()
*/ Machine.emit(Op.LOADL, 88); // goodbye
// local var "b" will be at 4[LB] after init Machine.emit(Prim.putintnl);
Machine.emit(Op.LOADA,Reg.SB,3); // class descriptor for B Machine.emit(Machine.Op.HALT, 0, 0, 0); // halt
Machine.emit(Op.LOADL,2); // size of B
Machine.emit(Prim.newobj); // result addr becomes value of "b"
Machine.emit(Op.LOAD,Reg.LB,4); // fetch b
Machine.emit(Op.LOADL,0); // field 0
Machine.emit(Op.LOADL,44); // b.x = 44
Machine.emit(Prim.fieldupd);
Machine.emit(Op.HALT,4,0,0);
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(Prim.putintnl); // print result
Machine.emit(Op.RETURN,0,0,1); // return no value (void), pop 1 arg (= String [] args)
// build class descriptor for C at 6[SB] /* write code as an object file */
int label_coC = Machine.nextInstrAddr(); String objectCodeFileName = "test.mJAM";
Machine.patch(patchme_coC, label_coC); ObjectFile objF = new ObjectFile(objectCodeFileName);
/*coC*/ Machine.emit(Op.LOADL,-1); // no superclass object System.out.print("Writing object code file " + objectCodeFileName + " ... ");
Machine.emit(Op.LOADL,0); // number of methods = 0 if (objF.write()) {
System.out.println("FAILED!");
return;
} else
System.out.println("SUCCEEDED");
/* /* create asm file using disassembler */
* End of class declarations - call main String asmCodeFileName = "test.asm";
*/ System.out.print("Writing assembly file ... ");
Machine.emit(Op.LOADL,Machine.nullRep); // put null on stack as value of main's arg Disassembler d = new Disassembler(objectCodeFileName);
Machine.emit(Op.CALL,Reg.CB,label_mainC); // call known static main() if (d.disassemble()) {
Machine.emit(Op.LOADL,88); // goodbye System.out.println("FAILED!");
Machine.emit(Prim.putintnl); return;
Machine.emit(Machine.Op.HALT,0,0,0); // halt } else
System.out.println("SUCCEEDED");
/* write code as an object file */ /* run code */
String objectCodeFileName = "test.mJAM"; System.out.println("Running code ... ");
ObjectFile objF = new ObjectFile(objectCodeFileName); Interpreter.debug(objectCodeFileName, asmCodeFileName);
System.out.print("Writing object code file " + objectCodeFileName + " ... ");
if (objF.write()) {
System.out.println("FAILED!");
return;
}
else
System.out.println("SUCCEEDED");
/* create asm file using disassembler */ System.out.println("*** mJAM execution completed");
String asmCodeFileName = "test.asm"; }
System.out.print("Writing assembly file ... ");
Disassembler d = new Disassembler(objectCodeFileName);
if (d.disassemble()) {
System.out.println("FAILED!");
return;
}
else
System.out.println("SUCCEEDED");
/* run code */
System.out.println("Running code ... ");
Interpreter.debug(objectCodeFileName, asmCodeFileName);
System.out.println("*** mJAM execution completed");
}
} }

View File

@ -9,19 +9,19 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public abstract class AST { public abstract class AST {
public AST(SourcePosition posn) { public AST(SourcePosition posn) {
this.posn = posn; this.posn = posn;
} }
public String toString() { public String toString() {
String fullClassName = this.getClass().getName(); String fullClassName = this.getClass().getName();
String cn = fullClassName.substring(1 + fullClassName.lastIndexOf('.')); String cn = fullClassName.substring(1 + fullClassName.lastIndexOf('.'));
if (ASTDisplay.showPosition) if (ASTDisplay.showPosition)
cn = cn + " " + posn.toString(); cn = cn + " " + posn.toString();
return cn; return cn;
} }
public abstract <A, R> R visit(Visitor<A, R> v, A o); public abstract <A, R> R visit(Visitor<A, R> v, A o);
public SourcePosition posn; public SourcePosition posn;
} }

View File

@ -18,341 +18,339 @@ package miniJava.AbstractSyntaxTrees;
*/ */
public class ASTDisplay implements Visitor<String, Object> { public class ASTDisplay implements Visitor<String, Object> {
public static boolean showPosition = false; public static boolean showPosition = false;
/** /**
* print text representation of AST to stdout * print text representation of AST to stdout
* *
* @param ast * @param ast
* root node of AST * root node of AST
*/ */
public void showTree(AST ast) { public void showTree(AST ast) {
System.out.println("======= AST Display ========================="); System.out.println("======= AST Display =========================");
ast.visit(this, ""); ast.visit(this, "");
System.out.println("============================================="); System.out.println("=============================================");
} }
// methods to format output // methods to format output
/** /**
* display arbitrary text for a node * display arbitrary text for a node
* *
* @param prefix * @param prefix
* spacing to indicate depth in AST * spacing to indicate depth in AST
* @param text * @param text
* preformatted node display * preformatted node display
*/ */
private void show(String prefix, String text) { private void show(String prefix, String text) {
System.out.println(prefix + text); System.out.println(prefix + text);
} }
/** /**
* display AST node by name * display AST node by name
* *
* @param prefix * @param prefix
* spacing to indicate depth in AST * spacing to indicate depth in AST
* @param node * @param node
* AST node, will be shown by name * AST node, will be shown by name
*/ */
private void show(String prefix, AST node) { private void show(String prefix, AST node) {
System.out.println(prefix + node.toString()); System.out.println(prefix + node.toString());
} }
/** /**
* quote a string * quote a string
* *
* @param text * @param text
* string to quote * string to quote
*/ */
private String quote(String text) { private String quote(String text) {
return ("\"" + text + "\""); return ("\"" + text + "\"");
} }
/** /**
* increase depth in AST * increase depth in AST
* *
* @param prefix * @param prefix
* current spacing to indicate depth in AST * current spacing to indicate depth in AST
* @return new spacing * @return new spacing
*/ */
private String indent(String prefix) { private String indent(String prefix) {
return prefix + " "; return prefix + " ";
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// PACKAGE // PACKAGE
// //
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
public Object visitPackage(Package prog, String arg) { public Object visitPackage(Package prog, String arg) {
show(arg, prog); show(arg, prog);
ClassDeclList cl = prog.classDeclList; ClassDeclList cl = prog.classDeclList;
show(arg, " ClassDeclList [" + cl.size() + "]"); show(arg, " ClassDeclList [" + cl.size() + "]");
String pfx = arg + " . "; String pfx = arg + " . ";
for (ClassDecl c : prog.classDeclList) { for (ClassDecl c : prog.classDeclList) {
c.visit(this, pfx); c.visit(this, pfx);
} }
return null; return null;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// DECLARATIONS // DECLARATIONS
// //
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
public Object visitClassDecl(ClassDecl clas, String arg) { public Object visitClassDecl(ClassDecl clas, String arg) {
show(arg, clas); show(arg, clas);
show(indent(arg), quote(clas.name) + " classname"); show(indent(arg), quote(clas.name) + " classname");
show(arg, " FieldDeclList [" + clas.fieldDeclList.size() + "]"); show(arg, " FieldDeclList [" + clas.fieldDeclList.size() + "]");
String pfx = arg + " . "; String pfx = arg + " . ";
for (FieldDecl f : clas.fieldDeclList) for (FieldDecl f : clas.fieldDeclList)
f.visit(this, pfx); f.visit(this, pfx);
show(arg, " MethodDeclList [" + clas.methodDeclList.size() + "]"); show(arg, " MethodDeclList [" + clas.methodDeclList.size() + "]");
for (MethodDecl m : clas.methodDeclList) for (MethodDecl m : clas.methodDeclList)
m.visit(this, pfx); m.visit(this, pfx);
return null; return null;
} }
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; show(arg, " ParameterDeclList [" + pdl.size() + "]");
show(arg, " ParameterDeclList [" + pdl.size() + "]"); String pfx = ((String) arg) + " . ";
String pfx = ((String) arg) + " . "; for (ParameterDecl pd : pdl) {
for (ParameterDecl pd : pdl) { pd.visit(this, pfx);
pd.visit(this, pfx); }
} StatementList sl = m.statementList;
StatementList sl = m.statementList; show(arg, " StmtList [" + sl.size() + "]");
show(arg, " StmtList [" + sl.size() + "]"); for (Statement s : sl) {
for (Statement s : sl) { s.visit(this, pfx);
s.visit(this, pfx); }
} if (m.returnExp != null) {
if (m.returnExp != null) { m.returnExp.visit(this, indent(arg));
m.returnExp.visit(this, indent(arg)); }
} return null;
return null; }
}
public Object visitParameterDecl(ParameterDecl pd, String arg) { public Object visitParameterDecl(ParameterDecl pd, String arg) {
show(arg, pd); show(arg, pd);
pd.type.visit(this, indent(arg)); pd.type.visit(this, indent(arg));
show(indent(arg), quote(pd.name) + "parametername "); show(indent(arg), quote(pd.name) + "parametername ");
return null; return null;
} }
public Object visitVarDecl(VarDecl vd, String arg) { public Object visitVarDecl(VarDecl vd, String arg) {
show(arg, vd); show(arg, vd);
vd.type.visit(this, indent(arg)); vd.type.visit(this, indent(arg));
show(indent(arg), quote(vd.name) + " varname"); show(indent(arg), quote(vd.name) + " varname");
return null; return null;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// TYPES // TYPES
// //
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
public Object visitBaseType(BaseType type, String arg) { public Object visitBaseType(BaseType type, String arg) {
show(arg, type.typeKind + " " + type.toString()); show(arg, type.typeKind + " " + type.toString());
return null; return null;
} }
public Object visitClassType(ClassType type, String arg) { public Object visitClassType(ClassType type, String arg) {
show(arg, type); show(arg, type);
show(indent(arg), quote(type.className.spelling) + " classname"); show(indent(arg), quote(type.className.spelling) + " classname");
return null; return null;
} }
public Object visitArrayType(ArrayType type, String arg) { public Object visitArrayType(ArrayType type, String arg) {
show(arg, type); show(arg, type);
type.eltType.visit(this, indent(arg)); type.eltType.visit(this, indent(arg));
return null; return null;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// STATEMENTS // STATEMENTS
// //
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
public Object visitBlockStmt(BlockStmt stmt, String arg) { public Object visitBlockStmt(BlockStmt stmt, String arg) {
show(arg, stmt); show(arg, stmt);
StatementList sl = stmt.sl; StatementList sl = stmt.sl;
show(arg, " StatementList [" + sl.size() + "]"); show(arg, " StatementList [" + sl.size() + "]");
String pfx = arg + " . "; String pfx = arg + " . ";
for (Statement s : sl) { for (Statement s : sl) {
s.visit(this, pfx); s.visit(this, pfx);
} }
return null; return null;
} }
public Object visitVardeclStmt(VarDeclStmt stmt, String arg) { public Object visitVardeclStmt(VarDeclStmt stmt, String arg) {
show(arg, stmt); show(arg, stmt);
stmt.varDecl.visit(this, indent(arg)); stmt.varDecl.visit(this, indent(arg));
stmt.initExp.visit(this, indent(arg)); stmt.initExp.visit(this, indent(arg));
return null; return null;
} }
public Object visitAssignStmt(AssignStmt stmt, String arg) { public Object visitAssignStmt(AssignStmt stmt, String arg) {
show(arg, stmt); show(arg, stmt);
stmt.ref.visit(this, indent(arg)); stmt.ref.visit(this, indent(arg));
stmt.val.visit(this, indent(arg)); stmt.val.visit(this, indent(arg));
return null; return null;
} }
public Object visitCallStmt(CallStmt stmt, String arg) { public Object visitCallStmt(CallStmt stmt, String arg) {
show(arg, stmt); show(arg, stmt);
stmt.methodRef.visit(this, indent(arg)); stmt.methodRef.visit(this, indent(arg));
ExprList al = stmt.argList; ExprList al = stmt.argList;
show(arg, " ExprList [" + al.size() + "]"); show(arg, " ExprList [" + al.size() + "]");
String pfx = arg + " . "; String pfx = arg + " . ";
for (Expression e : al) { for (Expression e : al) {
e.visit(this, pfx); e.visit(this, pfx);
} }
return null; return null;
} }
public Object visitIfStmt(IfStmt stmt, String arg) { public Object visitIfStmt(IfStmt stmt, String arg) {
show(arg, stmt); show(arg, stmt);
stmt.cond.visit(this, indent(arg)); stmt.cond.visit(this, indent(arg));
stmt.thenStmt.visit(this, indent(arg)); stmt.thenStmt.visit(this, indent(arg));
if (stmt.elseStmt != null) if (stmt.elseStmt != null)
stmt.elseStmt.visit(this, indent(arg)); stmt.elseStmt.visit(this, indent(arg));
return null; return null;
} }
public Object visitWhileStmt(WhileStmt stmt, String arg) { public Object visitWhileStmt(WhileStmt stmt, String arg) {
show(arg, stmt); show(arg, stmt);
stmt.cond.visit(this, indent(arg)); stmt.cond.visit(this, indent(arg));
stmt.body.visit(this, indent(arg)); stmt.body.visit(this, indent(arg));
return null; return null;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// EXPRESSIONS // EXPRESSIONS
// //
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
public Object visitUnaryExpr(UnaryExpr expr, String arg) { public Object visitUnaryExpr(UnaryExpr expr, String arg) {
show(arg, expr); show(arg, expr);
expr.operator.visit(this, indent(arg)); expr.operator.visit(this, indent(arg));
expr.expr.visit(this, indent(indent(arg))); expr.expr.visit(this, indent(indent(arg)));
return null; return null;
} }
public Object visitBinaryExpr(BinaryExpr expr, String arg) { public Object visitBinaryExpr(BinaryExpr expr, String arg) {
show(arg, expr); show(arg, expr);
expr.operator.visit(this, indent(arg)); expr.operator.visit(this, indent(arg));
expr.left.visit(this, indent(indent(arg))); expr.left.visit(this, indent(indent(arg)));
expr.right.visit(this, indent(indent(arg))); expr.right.visit(this, indent(indent(arg)));
return null; return null;
} }
public Object visitRefExpr(RefExpr expr, String arg) { public Object visitRefExpr(RefExpr expr, String arg) {
show(arg, expr); show(arg, expr);
expr.ref.visit(this, indent(arg)); expr.ref.visit(this, indent(arg));
return null; return null;
} }
public Object visitCallExpr(CallExpr expr, String arg) { public Object visitCallExpr(CallExpr expr, String arg) {
show(arg, expr); show(arg, expr);
expr.functionRef.visit(this, indent(arg)); expr.functionRef.visit(this, indent(arg));
ExprList al = expr.argList; ExprList al = expr.argList;
show(arg, " ExprList + [" + al.size() + "]"); show(arg, " ExprList + [" + al.size() + "]");
String pfx = arg + " . "; String pfx = arg + " . ";
for (Expression e : al) { for (Expression e : al) {
e.visit(this, pfx); e.visit(this, pfx);
} }
return null; return null;
} }
public Object visitLiteralExpr(LiteralExpr expr, String arg) { public Object visitLiteralExpr(LiteralExpr expr, String arg) {
show(arg, expr); show(arg, expr);
expr.literal.visit(this, indent(arg)); expr.literal.visit(this, indent(arg));
return null; return null;
} }
public Object visitNewArrayExpr(NewArrayExpr expr, String arg) { public Object visitNewArrayExpr(NewArrayExpr expr, String arg) {
show(arg, expr); show(arg, expr);
expr.eltType.visit(this, indent(arg)); expr.eltType.visit(this, indent(arg));
expr.sizeExpr.visit(this, indent(arg)); expr.sizeExpr.visit(this, indent(arg));
return null; return null;
} }
public Object visitNewObjectExpr(NewObjectExpr expr, String arg) { public Object visitNewObjectExpr(NewObjectExpr expr, String arg) {
show(arg, expr); show(arg, expr);
expr.classtype.visit(this, indent(arg)); expr.classtype.visit(this, indent(arg));
return null; return null;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// REFERENCES // REFERENCES
// //
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
public Object visitQualifiedRef(QualifiedRef qr, String arg) { public Object visitQualifiedRef(QualifiedRef qr, String arg) {
show(arg, qr); show(arg, qr);
qr.id.visit(this, indent(arg)); qr.id.visit(this, indent(arg));
qr.ref.visit(this, indent(arg)); qr.ref.visit(this, indent(arg));
return null; return null;
} }
public Object visitIndexedRef(IndexedRef ir, String arg) { public Object visitIndexedRef(IndexedRef ir, String arg) {
show(arg, ir); show(arg, ir);
ir.indexExpr.visit(this, indent(arg)); ir.indexExpr.visit(this, indent(arg));
ir.ref.visit(this, indent(arg)); ir.ref.visit(this, indent(arg));
return null; return null;
} }
public Object visitIdRef(IdRef ref, String arg) { public Object visitIdRef(IdRef ref, String arg) {
show(arg, ref); show(arg, ref);
ref.id.visit(this, indent(arg)); ref.id.visit(this, indent(arg));
return null; return null;
} }
public Object visitThisRef(ThisRef ref, String arg) { public Object visitThisRef(ThisRef ref, String arg) {
show(arg, ref); show(arg, ref);
return null; return null;
} }
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// //
// TERMINALS // TERMINALS
// //
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
public Object visitIdentifier(Identifier id, String arg) { public Object visitIdentifier(Identifier id, String arg) {
show(arg, quote(id.spelling) + " " + id.toString()); show(arg, quote(id.spelling) + " " + id.toString());
return null; return null;
} }
public Object visitOperator(Operator op, String arg) { public Object visitOperator(Operator op, String arg) {
show(arg, quote(op.spelling) + " " + op.toString()); show(arg, quote(op.spelling) + " " + op.toString());
return null; return null;
} }
public Object visitIntLiteral(IntLiteral num, String arg) { public Object visitIntLiteral(IntLiteral num, String arg) {
show(arg, quote(num.spelling) + " " + num.toString()); show(arg, quote(num.spelling) + " " + num.toString());
return null; return null;
} }
public Object visitBooleanLiteral(BooleanLiteral bool, String arg) { public Object visitBooleanLiteral(BooleanLiteral bool, String arg) {
show(arg, quote(bool.spelling) + " " + bool.toString()); show(arg, quote(bool.spelling) + " " + bool.toString());
return null; return null;
} }
} }

View File

@ -10,18 +10,18 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public class ArrayType extends Type { public class ArrayType extends Type {
public ArrayType(Type eltType, SourcePosition posn) { public ArrayType(Type eltType, SourcePosition posn) {
super(TypeKind.ARRAY, posn); super(TypeKind.ARRAY, posn);
this.eltType = eltType; this.eltType = eltType;
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitArrayType(this, o); return v.visitArrayType(this, o);
} }
public String toString() { public String toString() {
return eltType + " Array"; return eltType + " Array";
} }
public Type eltType; public Type eltType;
} }

View File

@ -8,16 +8,16 @@ package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition; import miniJava.SyntacticAnalyzer.SourcePosition;
public class AssignStmt extends Statement { public class AssignStmt extends Statement {
public AssignStmt(Reference r, Expression e, SourcePosition posn) { public AssignStmt(Reference r, Expression e, SourcePosition posn) {
super(posn); super(posn);
ref = r; ref = r;
val = e; val = e;
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitAssignStmt(this, o); return v.visitAssignStmt(this, o);
} }
public Reference ref; public Reference ref;
public Expression val; public Expression val;
} }

View File

@ -8,15 +8,15 @@ package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition; import miniJava.SyntacticAnalyzer.SourcePosition;
public class BaseType extends Type { public class BaseType extends Type {
public BaseType(TypeKind t, SourcePosition posn) { public BaseType(TypeKind t, SourcePosition posn) {
super(t, posn); super(t, posn);
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitBaseType(this, o); return v.visitBaseType(this, o);
} }
public String toString() { public String toString() {
return typeKind.toString(); return typeKind.toString();
} }
} }

View File

@ -8,19 +8,18 @@ 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; right = e2;
right = e2; }
}
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitBinaryExpr(this, o); return v.visitBinaryExpr(this, o);
} }
public Operator operator; public Operator operator;
public Expression left; public Expression left;
public Expression right; public Expression right;
} }

View File

@ -8,14 +8,14 @@ package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition; import miniJava.SyntacticAnalyzer.SourcePosition;
public class BlockStmt extends Statement { public class BlockStmt extends Statement {
public BlockStmt(StatementList sl, SourcePosition posn) { public BlockStmt(StatementList sl, SourcePosition posn) {
super(posn); super(posn);
this.sl = sl; this.sl = sl;
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitBlockStmt(this, o); return v.visitBlockStmt(this, o);
} }
public StatementList sl; public StatementList sl;
} }

View File

@ -9,11 +9,11 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public class BooleanLiteral extends Literal { public class BooleanLiteral extends Literal {
public BooleanLiteral(String spelling, SourcePosition posn) { public BooleanLiteral(String spelling, SourcePosition posn) {
super(spelling, posn); super(spelling, posn);
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitBooleanLiteral(this, o); return v.visitBooleanLiteral(this, o);
} }
} }

View File

@ -8,16 +8,16 @@ package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition; import miniJava.SyntacticAnalyzer.SourcePosition;
public class CallExpr extends Expression { public class CallExpr extends Expression {
public CallExpr(Reference f, ExprList el, SourcePosition posn) { public CallExpr(Reference f, ExprList el, SourcePosition posn) {
super(posn); super(posn);
functionRef = f; functionRef = f;
argList = el; argList = el;
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitCallExpr(this, o); return v.visitCallExpr(this, o);
} }
public Reference functionRef; public Reference functionRef;
public ExprList argList; public ExprList argList;
} }

View File

@ -8,16 +8,16 @@ package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition; import miniJava.SyntacticAnalyzer.SourcePosition;
public class CallStmt extends Statement { public class CallStmt extends Statement {
public CallStmt(Reference m, ExprList el, SourcePosition posn) { public CallStmt(Reference m, ExprList el, SourcePosition posn) {
super(posn); super(posn);
methodRef = m; methodRef = m;
argList = el; argList = el;
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitCallStmt(this, o); return v.visitCallStmt(this, o);
} }
public Reference methodRef; public Reference methodRef;
public ExprList argList; public ExprList argList;
} }

View File

@ -9,17 +9,16 @@ 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; }
}
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitClassDecl(this, o); return v.visitClassDecl(this, o);
} }
public FieldDeclList fieldDeclList; public FieldDeclList fieldDeclList;
public MethodDeclList methodDeclList; public MethodDeclList methodDeclList;
} }

View File

@ -8,25 +8,25 @@ package miniJava.AbstractSyntaxTrees;
import java.util.*; import java.util.*;
public class ClassDeclList implements Iterable<ClassDecl> { public class ClassDeclList implements Iterable<ClassDecl> {
public ClassDeclList() { public ClassDeclList() {
classDeclList = new ArrayList<ClassDecl>(); classDeclList = new ArrayList<ClassDecl>();
} }
public void add(ClassDecl cd) { public void add(ClassDecl cd) {
classDeclList.add(cd); classDeclList.add(cd);
} }
public ClassDecl get(int i) { public ClassDecl get(int i) {
return classDeclList.get(i); return classDeclList.get(i);
} }
public int size() { public int size() {
return classDeclList.size(); return classDeclList.size();
} }
public Iterator<ClassDecl> iterator() { public Iterator<ClassDecl> iterator() {
return classDeclList.iterator(); return classDeclList.iterator();
} }
private List<ClassDecl> classDeclList; private List<ClassDecl> classDeclList;
} }

View File

@ -8,18 +8,18 @@ package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition; import miniJava.SyntacticAnalyzer.SourcePosition;
public class ClassType extends Type { public class ClassType extends Type {
public ClassType(Identifier cn, SourcePosition posn) { public ClassType(Identifier cn, SourcePosition posn) {
super(TypeKind.CLASS, posn); super(TypeKind.CLASS, posn);
className = cn; className = cn;
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitClassType(this, o); return v.visitClassType(this, o);
} }
public String toString() { public String toString() {
return "Class " + className.spelling; return "Class " + className.spelling;
} }
public Identifier className; public Identifier className;
} }

View File

@ -11,14 +11,14 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public abstract class Declaration extends AST { public abstract class Declaration extends AST {
public Declaration(String name, Type type, SourcePosition posn) { public Declaration(String name, Type type, SourcePosition posn) {
super(posn); super(posn);
this.name = name; this.name = name;
this.type = type; this.type = type;
} }
public RuntimeEntity entity; public RuntimeEntity entity;
public IdTable table; public IdTable table;
public String name; public String name;
public Type type; public Type type;
} }

View File

@ -8,16 +8,15 @@ 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; this.posn = posn;
this.posn = posn; }
}
public boolean isPrivate; public boolean isPrivate;
public boolean isStatic; public boolean isStatic;
public Type mt; public Type mt;
public SourcePosition posn; public SourcePosition posn;
} }

View File

@ -8,25 +8,25 @@ package miniJava.AbstractSyntaxTrees;
import java.util.*; import java.util.*;
public class ExprList implements Iterable<Expression> { public class ExprList implements Iterable<Expression> {
public ExprList() { public ExprList() {
elist = new ArrayList<Expression>(); elist = new ArrayList<Expression>();
} }
public void add(Expression e) { public void add(Expression e) {
elist.add(e); elist.add(e);
} }
public Expression get(int i) { public Expression get(int i) {
return elist.get(i); return elist.get(i);
} }
public int size() { public int size() {
return elist.size(); return elist.size();
} }
public Iterator<Expression> iterator() { public Iterator<Expression> iterator() {
return elist.iterator(); return elist.iterator();
} }
private List<Expression> elist; private List<Expression> elist;
} }

View File

@ -9,8 +9,8 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public abstract class Expression extends AST { public abstract class Expression extends AST {
public Expression(SourcePosition posn) { public Expression(SourcePosition posn) {
super(posn); super(posn);
} }
} }

View File

@ -9,20 +9,19 @@ 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); }
}
public FieldDecl(MemberDecl md, SourcePosition posn) { public FieldDecl(MemberDecl md, SourcePosition posn) {
super(md, posn); super(md, posn);
} }
public FieldDecl(Declarators d, String name) { public FieldDecl(Declarators d, String name) {
super(d.isPrivate, d.isStatic, d.mt, name, d.posn); super(d.isPrivate, d.isStatic, d.mt, name, d.posn);
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitFieldDecl(this, o); return v.visitFieldDecl(this, o);
} }
} }

View File

@ -8,25 +8,25 @@ package miniJava.AbstractSyntaxTrees;
import java.util.*; import java.util.*;
public class FieldDeclList implements Iterable<FieldDecl> { public class FieldDeclList implements Iterable<FieldDecl> {
public FieldDeclList() { public FieldDeclList() {
fieldDeclList = new ArrayList<FieldDecl>(); fieldDeclList = new ArrayList<FieldDecl>();
} }
public void add(FieldDecl cd) { public void add(FieldDecl cd) {
fieldDeclList.add(cd); fieldDeclList.add(cd);
} }
public FieldDecl get(int i) { public FieldDecl get(int i) {
return fieldDeclList.get(i); return fieldDeclList.get(i);
} }
public int size() { public int size() {
return fieldDeclList.size(); return fieldDeclList.size();
} }
public Iterator<FieldDecl> iterator() { public Iterator<FieldDecl> iterator() {
return fieldDeclList.iterator(); return fieldDeclList.iterator();
} }
private List<FieldDecl> fieldDeclList; private List<FieldDecl> fieldDeclList;
} }

View File

@ -9,14 +9,14 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public class IdRef extends Reference { public class IdRef extends Reference {
public IdRef(Identifier id, SourcePosition posn) { public IdRef(Identifier id, SourcePosition posn) {
super(posn); super(posn);
this.id = id; this.id = id;
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitIdRef(this, o); return v.visitIdRef(this, o);
} }
public Identifier id; public Identifier id;
} }

View File

@ -10,14 +10,14 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public class Identifier extends Terminal { public class Identifier extends Terminal {
public Identifier(String s, SourcePosition posn) { public Identifier(String s, SourcePosition posn) {
super(s, posn); super(s, posn);
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitIdentifier(this, o); return v.visitIdentifier(this, o);
} }
public Declaration decl; public Declaration decl;
public RuntimeEntity entity; public RuntimeEntity entity;
} }

View File

@ -8,25 +8,25 @@ package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition; import miniJava.SyntacticAnalyzer.SourcePosition;
public class IfStmt extends Statement { public class IfStmt extends Statement {
public IfStmt(Expression b, Statement t, Statement e, SourcePosition posn) { public IfStmt(Expression b, Statement t, Statement e, SourcePosition posn) {
super(posn); super(posn);
cond = b; cond = b;
thenStmt = t; thenStmt = t;
elseStmt = e; elseStmt = e;
} }
public IfStmt(Expression b, Statement t, SourcePosition posn) { public IfStmt(Expression b, Statement t, SourcePosition posn) {
super(posn); super(posn);
cond = b; cond = b;
thenStmt = t; thenStmt = t;
elseStmt = null; elseStmt = null;
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitIfStmt(this, o); return v.visitIfStmt(this, o);
} }
public Expression cond; public Expression cond;
public Statement thenStmt; public Statement thenStmt;
public Statement elseStmt; public Statement elseStmt;
} }

View File

@ -9,16 +9,16 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public class IndexedRef extends Reference { public class IndexedRef extends Reference {
public IndexedRef(Reference ref, Expression expr, SourcePosition posn) { public IndexedRef(Reference ref, Expression expr, SourcePosition posn) {
super(posn); super(posn);
this.ref = ref; this.ref = ref;
this.indexExpr = expr; this.indexExpr = expr;
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitIndexedRef(this, o); return v.visitIndexedRef(this, o);
} }
public Reference ref; public Reference ref;
public Expression indexExpr; public Expression indexExpr;
} }

View File

@ -9,11 +9,11 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public class IntLiteral extends Literal { public class IntLiteral extends Literal {
public IntLiteral(String s, SourcePosition posn) { public IntLiteral(String s, SourcePosition posn) {
super(s, posn); super(s, posn);
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitIntLiteral(this, o); return v.visitIntLiteral(this, o);
} }
} }

View File

@ -9,7 +9,7 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public abstract class Literal extends Terminal { public abstract class Literal extends Terminal {
public Literal(String spelling, SourcePosition posn) { public Literal(String spelling, SourcePosition posn) {
super(spelling, posn); super(spelling, posn);
} }
} }

View File

@ -8,14 +8,14 @@ package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition; import miniJava.SyntacticAnalyzer.SourcePosition;
public class LiteralExpr extends Expression { public class LiteralExpr extends Expression {
public LiteralExpr(Literal c, SourcePosition posn) { public LiteralExpr(Literal c, SourcePosition posn) {
super(posn); super(posn);
literal = c; literal = c;
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitLiteralExpr(this, o); return v.visitLiteralExpr(this, o);
} }
public Literal literal; public Literal literal;
} }

View File

@ -9,8 +9,8 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public abstract class LocalDecl extends Declaration { public abstract class LocalDecl extends Declaration {
public LocalDecl(String name, Type t, SourcePosition posn) { public LocalDecl(String name, Type t, SourcePosition posn) {
super(name, t, posn); super(name, t, posn);
} }
} }

View File

@ -9,19 +9,18 @@ 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; }
}
public MemberDecl(MemberDecl md, SourcePosition posn) { public MemberDecl(MemberDecl md, SourcePosition posn) {
super(md.name, md.type, posn); super(md.name, md.type, posn);
this.isPrivate = md.isPrivate; this.isPrivate = md.isPrivate;
this.isStatic = md.isStatic; this.isStatic = md.isStatic;
} }
public boolean isPrivate; public boolean isPrivate;
public boolean isStatic; public boolean isStatic;
} }

View File

@ -9,19 +9,18 @@ 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; returnExp = e;
returnExp = e; }
}
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitMethodDecl(this, o); return v.visitMethodDecl(this, o);
} }
public ParameterDeclList parameterDeclList; public ParameterDeclList parameterDeclList;
public StatementList statementList; public StatementList statementList;
public Expression returnExp; public Expression returnExp;
} }

View File

@ -8,25 +8,25 @@ package miniJava.AbstractSyntaxTrees;
import java.util.*; import java.util.*;
public class MethodDeclList implements Iterable<MethodDecl> { public class MethodDeclList implements Iterable<MethodDecl> {
public MethodDeclList() { public MethodDeclList() {
methodDeclList = new ArrayList<MethodDecl>(); methodDeclList = new ArrayList<MethodDecl>();
} }
public void add(MethodDecl cd) { public void add(MethodDecl cd) {
methodDeclList.add(cd); methodDeclList.add(cd);
} }
public MethodDecl get(int i) { public MethodDecl get(int i) {
return methodDeclList.get(i); return methodDeclList.get(i);
} }
public int size() { public int size() {
return methodDeclList.size(); return methodDeclList.size();
} }
public Iterator<MethodDecl> iterator() { public Iterator<MethodDecl> iterator() {
return methodDeclList.iterator(); return methodDeclList.iterator();
} }
private List<MethodDecl> methodDeclList; private List<MethodDecl> methodDeclList;
} }

View File

@ -8,16 +8,16 @@ package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition; import miniJava.SyntacticAnalyzer.SourcePosition;
public class NewArrayExpr extends NewExpr { public class NewArrayExpr extends NewExpr {
public NewArrayExpr(Type et, Expression e, SourcePosition posn) { public NewArrayExpr(Type et, Expression e, SourcePosition posn) {
super(posn); super(posn);
eltType = et; eltType = et;
sizeExpr = e; sizeExpr = e;
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitNewArrayExpr(this, o); return v.visitNewArrayExpr(this, o);
} }
public Type eltType; public Type eltType;
public Expression sizeExpr; public Expression sizeExpr;
} }

View File

@ -9,7 +9,7 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public abstract class NewExpr extends Expression { public abstract class NewExpr extends Expression {
public NewExpr(SourcePosition posn) { public NewExpr(SourcePosition posn) {
super(posn); super(posn);
} }
} }

View File

@ -8,14 +8,14 @@ package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition; import miniJava.SyntacticAnalyzer.SourcePosition;
public class NewObjectExpr extends NewExpr { public class NewObjectExpr extends NewExpr {
public NewObjectExpr(ClassType ct, SourcePosition posn) { public NewObjectExpr(ClassType ct, SourcePosition posn) {
super(posn); super(posn);
classtype = ct; classtype = ct;
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitNewObjectExpr(this, o); return v.visitNewObjectExpr(this, o);
} }
public ClassType classtype; public ClassType classtype;
} }

View File

@ -10,13 +10,13 @@ import miniJava.SyntacticAnalyzer.Token;
public class Operator extends Terminal { public class Operator extends Terminal {
public Operator(Token t, SourcePosition posn) { public Operator(Token t, SourcePosition posn) {
super(t.spelling, posn); super(t.spelling, posn);
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitOperator(this, o); return v.visitOperator(this, o);
} }
public Token token; public Token token;
} }

View File

@ -9,14 +9,14 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public class Package extends AST { public class Package extends AST {
public Package(ClassDeclList cdl, SourcePosition posn) { public Package(ClassDeclList cdl, SourcePosition posn) {
super(posn); super(posn);
classDeclList = cdl; classDeclList = cdl;
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitPackage(this, o); return v.visitPackage(this, o);
} }
public ClassDeclList classDeclList; public ClassDeclList classDeclList;
} }

View File

@ -9,11 +9,11 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public class ParameterDecl extends LocalDecl { public class ParameterDecl extends LocalDecl {
public ParameterDecl(Type t, String name, SourcePosition posn) { public ParameterDecl(Type t, String name, SourcePosition posn) {
super(name, t, posn); super(name, t, posn);
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitParameterDecl(this, o); return v.visitParameterDecl(this, o);
} }
} }

View File

@ -8,25 +8,25 @@ package miniJava.AbstractSyntaxTrees;
import java.util.*; import java.util.*;
public class ParameterDeclList implements Iterable<ParameterDecl> { public class ParameterDeclList implements Iterable<ParameterDecl> {
public ParameterDeclList() { public ParameterDeclList() {
parameterDeclList = new ArrayList<ParameterDecl>(); parameterDeclList = new ArrayList<ParameterDecl>();
} }
public void add(ParameterDecl s) { public void add(ParameterDecl s) {
parameterDeclList.add(s); parameterDeclList.add(s);
} }
public ParameterDecl get(int i) { public ParameterDecl get(int i) {
return parameterDeclList.get(i); return parameterDeclList.get(i);
} }
public int size() { public int size() {
return parameterDeclList.size(); return parameterDeclList.size();
} }
public Iterator<ParameterDecl> iterator() { public Iterator<ParameterDecl> iterator() {
return parameterDeclList.iterator(); return parameterDeclList.iterator();
} }
private List<ParameterDecl> parameterDeclList; private List<ParameterDecl> parameterDeclList;
} }

View File

@ -9,17 +9,17 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public class QualifiedRef extends Reference { public class QualifiedRef extends Reference {
public QualifiedRef(Reference ref, Identifier id, SourcePosition posn) { public QualifiedRef(Reference ref, Identifier id, SourcePosition posn) {
super(posn); super(posn);
this.ref = ref; this.ref = ref;
this.id = id; this.id = id;
} }
@Override @Override
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitQualifiedRef(this, o); return v.visitQualifiedRef(this, o);
} }
public Reference ref; public Reference ref;
public Identifier id; public Identifier id;
} }

View File

@ -8,14 +8,14 @@ package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition; import miniJava.SyntacticAnalyzer.SourcePosition;
public class RefExpr extends Expression { public class RefExpr extends Expression {
public RefExpr(Reference r, SourcePosition posn) { public RefExpr(Reference r, SourcePosition posn) {
super(posn); super(posn);
ref = r; ref = r;
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitRefExpr(this, o); return v.visitRefExpr(this, o);
} }
public Reference ref; public Reference ref;
} }

View File

@ -9,11 +9,11 @@ import miniJava.CodeGenerator.RuntimeEntity;
import miniJava.SyntacticAnalyzer.SourcePosition; import miniJava.SyntacticAnalyzer.SourcePosition;
public abstract class Reference extends AST { public abstract class Reference extends AST {
public Reference(SourcePosition posn) { public Reference(SourcePosition posn) {
super(posn); super(posn);
} }
public String spelling; public String spelling;
public Declaration decl; public Declaration decl;
public RuntimeEntity entity; public RuntimeEntity entity;
} }

View File

@ -9,8 +9,8 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public abstract class Statement extends AST { public abstract class Statement extends AST {
public Statement(SourcePosition posn) { public Statement(SourcePosition posn) {
super(posn); super(posn);
} }
} }

View File

@ -8,25 +8,25 @@ package miniJava.AbstractSyntaxTrees;
import java.util.*; import java.util.*;
public class StatementList implements Iterable<Statement> { public class StatementList implements Iterable<Statement> {
public StatementList() { public StatementList() {
slist = new ArrayList<Statement>(); slist = new ArrayList<Statement>();
} }
public void add(Statement s) { public void add(Statement s) {
slist.add(s); slist.add(s);
} }
public Statement get(int i) { public Statement get(int i) {
return slist.get(i); return slist.get(i);
} }
public int size() { public int size() {
return slist.size(); return slist.size();
} }
public Iterator<Statement> iterator() { public Iterator<Statement> iterator() {
return slist.iterator(); return slist.iterator();
} }
private List<Statement> slist; private List<Statement> slist;
} }

View File

@ -9,10 +9,10 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
abstract public class Terminal extends AST { abstract public class Terminal extends AST {
public Terminal(String s, SourcePosition posn) { public Terminal(String s, SourcePosition posn) {
super(posn); super(posn);
spelling = s; spelling = s;
} }
public String spelling; public String spelling;
} }

View File

@ -9,13 +9,13 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public class ThisRef extends Reference { public class ThisRef extends Reference {
public ThisRef(SourcePosition posn) { public ThisRef(SourcePosition posn) {
super(posn); super(posn);
} }
@Override @Override
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitThisRef(this, o); return v.visitThisRef(this, o);
} }
} }

View File

@ -9,11 +9,11 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
abstract public class Type extends AST { abstract public class Type extends AST {
public Type(TypeKind typ, SourcePosition posn) { public Type(TypeKind typ, SourcePosition posn) {
super(posn); super(posn);
typeKind = typ; typeKind = typ;
} }
public TypeKind typeKind; public TypeKind typeKind;
} }

View File

@ -6,5 +6,5 @@
package miniJava.AbstractSyntaxTrees; package miniJava.AbstractSyntaxTrees;
public enum TypeKind { public enum TypeKind {
VOID, INT, BOOLEAN, CLASS, ARRAY, UNSUPPORTED, ERROR; VOID, INT, BOOLEAN, CLASS, ARRAY, UNSUPPORTED, ERROR;
} }

View File

@ -8,16 +8,16 @@ package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition; import miniJava.SyntacticAnalyzer.SourcePosition;
public class UnaryExpr extends Expression { public class UnaryExpr extends Expression {
public UnaryExpr(Operator o, Expression e, SourcePosition posn) { public UnaryExpr(Operator o, Expression e, SourcePosition posn) {
super(posn); super(posn);
operator = o; operator = o;
expr = e; expr = e;
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitUnaryExpr(this, o); return v.visitUnaryExpr(this, o);
} }
public Operator operator; public Operator operator;
public Expression expr; public Expression expr;
} }

View File

@ -9,11 +9,11 @@ import miniJava.SyntacticAnalyzer.SourcePosition;
public class VarDecl extends LocalDecl { public class VarDecl extends LocalDecl {
public VarDecl(Type t, String name, SourcePosition posn) { public VarDecl(Type t, String name, SourcePosition posn) {
super(name, t, posn); super(name, t, posn);
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitVarDecl(this, o); return v.visitVarDecl(this, o);
} }
} }

View File

@ -8,16 +8,16 @@ package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition; import miniJava.SyntacticAnalyzer.SourcePosition;
public class VarDeclStmt extends Statement { public class VarDeclStmt extends Statement {
public VarDeclStmt(VarDecl vd, Expression e, SourcePosition posn) { public VarDeclStmt(VarDecl vd, Expression e, SourcePosition posn) {
super(posn); super(posn);
varDecl = vd; varDecl = vd;
initExp = e; initExp = e;
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitVardeclStmt(this, o); return v.visitVardeclStmt(this, o);
} }
public VarDecl varDecl; public VarDecl varDecl;
public Expression initExp; public Expression initExp;
} }

View File

@ -11,70 +11,70 @@ package miniJava.AbstractSyntaxTrees;
*/ */
public interface Visitor<ArgType, ResultType> { public interface Visitor<ArgType, ResultType> {
// Package // Package
public ResultType visitPackage(Package prog, ArgType arg); public ResultType visitPackage(Package prog, ArgType arg);
// Declarations // Declarations
public ResultType visitClassDecl(ClassDecl cd, ArgType arg); public ResultType visitClassDecl(ClassDecl cd, ArgType arg);
public ResultType visitFieldDecl(FieldDecl fd, ArgType arg); public ResultType visitFieldDecl(FieldDecl fd, ArgType arg);
public ResultType visitMethodDecl(MethodDecl md, ArgType arg); public ResultType visitMethodDecl(MethodDecl md, ArgType arg);
public ResultType visitParameterDecl(ParameterDecl pd, ArgType arg); public ResultType visitParameterDecl(ParameterDecl pd, ArgType arg);
public ResultType visitVarDecl(VarDecl decl, ArgType arg); public ResultType visitVarDecl(VarDecl decl, ArgType arg);
// Types // Types
public ResultType visitBaseType(BaseType type, ArgType arg); public ResultType visitBaseType(BaseType type, ArgType arg);
public ResultType visitClassType(ClassType type, ArgType arg); public ResultType visitClassType(ClassType type, ArgType arg);
public ResultType visitArrayType(ArrayType type, ArgType arg); public ResultType visitArrayType(ArrayType type, ArgType arg);
// Statements // Statements
public ResultType visitBlockStmt(BlockStmt stmt, ArgType arg); public ResultType visitBlockStmt(BlockStmt stmt, ArgType arg);
public ResultType visitVardeclStmt(VarDeclStmt stmt, ArgType arg); public ResultType visitVardeclStmt(VarDeclStmt stmt, ArgType arg);
public ResultType visitAssignStmt(AssignStmt stmt, ArgType arg); public ResultType visitAssignStmt(AssignStmt stmt, ArgType arg);
public ResultType visitCallStmt(CallStmt stmt, ArgType arg); public ResultType visitCallStmt(CallStmt stmt, ArgType arg);
public ResultType visitIfStmt(IfStmt stmt, ArgType arg); public ResultType visitIfStmt(IfStmt stmt, ArgType arg);
public ResultType visitWhileStmt(WhileStmt stmt, ArgType arg); public ResultType visitWhileStmt(WhileStmt stmt, ArgType arg);
// Expressions // Expressions
public ResultType visitUnaryExpr(UnaryExpr expr, ArgType arg); public ResultType visitUnaryExpr(UnaryExpr expr, ArgType arg);
public ResultType visitBinaryExpr(BinaryExpr expr, ArgType arg); public ResultType visitBinaryExpr(BinaryExpr expr, ArgType arg);
public ResultType visitRefExpr(RefExpr expr, ArgType arg); public ResultType visitRefExpr(RefExpr expr, ArgType arg);
public ResultType visitCallExpr(CallExpr expr, ArgType arg); public ResultType visitCallExpr(CallExpr expr, ArgType arg);
public ResultType visitLiteralExpr(LiteralExpr expr, ArgType arg); public ResultType visitLiteralExpr(LiteralExpr expr, ArgType arg);
public ResultType visitNewObjectExpr(NewObjectExpr expr, ArgType arg); public ResultType visitNewObjectExpr(NewObjectExpr expr, ArgType arg);
public ResultType visitNewArrayExpr(NewArrayExpr expr, ArgType arg); public ResultType visitNewArrayExpr(NewArrayExpr expr, ArgType arg);
// References // References
public ResultType visitQualifiedRef(QualifiedRef ref, ArgType arg); public ResultType visitQualifiedRef(QualifiedRef ref, ArgType arg);
public ResultType visitIndexedRef(IndexedRef ref, ArgType arg); public ResultType visitIndexedRef(IndexedRef ref, ArgType arg);
public ResultType visitIdRef(IdRef ref, ArgType arg); public ResultType visitIdRef(IdRef ref, ArgType arg);
public ResultType visitThisRef(ThisRef ref, ArgType arg); public ResultType visitThisRef(ThisRef ref, ArgType arg);
// Terminals // Terminals
public ResultType visitIdentifier(Identifier id, ArgType arg); public ResultType visitIdentifier(Identifier id, ArgType arg);
public ResultType visitOperator(Operator op, ArgType arg); public ResultType visitOperator(Operator op, ArgType arg);
public ResultType visitIntLiteral(IntLiteral num, ArgType arg); public ResultType visitIntLiteral(IntLiteral num, ArgType arg);
public ResultType visitBooleanLiteral(BooleanLiteral bool, ArgType arg); public ResultType visitBooleanLiteral(BooleanLiteral bool, ArgType arg);
} }

View File

@ -8,16 +8,16 @@ package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition; import miniJava.SyntacticAnalyzer.SourcePosition;
public class WhileStmt extends Statement { public class WhileStmt extends Statement {
public WhileStmt(Expression b, Statement s, SourcePosition posn) { public WhileStmt(Expression b, Statement s, SourcePosition posn) {
super(posn); super(posn);
cond = b; cond = b;
body = s; body = s;
} }
public <A, R> R visit(Visitor<A, R> v, A o) { public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitWhileStmt(this, o); return v.visitWhileStmt(this, o);
} }
public Expression cond; public Expression cond;
public Statement body; public Statement body;
} }

View File

@ -5,51 +5,52 @@ import miniJava.AbstractSyntaxTrees.*;
public class Code { public class Code {
public boolean addr; public boolean addr;
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 decl * @param op
* @param addr * @param decl
*/ * @param addr
public Code(Declaration decl, boolean addr) { */
this.decl = decl; public Code(Declaration decl, boolean addr) {
this.addr = addr; this.decl = decl;
} this.addr = addr;
}
/** /**
* *
* @param index * @param index
*/ */
public void modify(int instr) { public void modify(int instr) {
// Setup size // Setup size
switch(decl.type.typeKind) { switch (decl.type.typeKind) {
case ARRAY: case ARRAY:
case CLASS: case CLASS:
Machine.code[instr].n = Machine.addressSize; Machine.code[instr].n = Machine.addressSize;
case INT: case INT:
Machine.code[instr].n = Machine.integerSize; Machine.code[instr].n = Machine.integerSize;
case BOOLEAN: case BOOLEAN:
Machine.code[instr].n = Machine.booleanSize; Machine.code[instr].n = Machine.booleanSize;
case VOID: case VOID:
Machine.code[instr].n = 0; Machine.code[instr].n = 0;
default: default:
Machine.code[instr].n = -1; Machine.code[instr].n = -1;
} }
// Setup displacement // Setup displacement
if(addr) { if (addr) {
Machine.code[instr].d += decl.entity.addr; Machine.code[instr].d += decl.entity.addr;
} else { } else {
Machine.code[instr].d += decl.entity.size; Machine.code[instr].d += decl.entity.size;
} }
// Setup register // Setup register
Machine.code[instr].r = decl.entity.reg.ordinal(); Machine.code[instr].r = decl.entity.reg.ordinal();
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -4,16 +4,16 @@ import mJAM.Machine.Reg;
public class RuntimeEntity { public class RuntimeEntity {
public Reg reg; public Reg reg;
public int size; public int size;
public int addr; public int addr;
RuntimeEntity parent = null; RuntimeEntity parent = null;
public RuntimeEntity(int size, int addr, Reg reg) { public RuntimeEntity(int size, int addr, Reg reg) {
this.reg = reg; this.reg = reg;
this.size = size; this.size = size;
this.addr = addr; this.addr = addr;
} }
} }

View File

@ -19,58 +19,58 @@ import miniJava.ContextualAnalyzer.Reporter;
public class Compiler { public class Compiler {
public static final int rc = 4; public static final int rc = 4;
public static void main(String[] args) { public static void main(String[] args) {
if (args.length == 0) { if (args.length == 0) {
System.out.println("No file specified"); System.out.println("No file specified");
System.exit(rc); System.exit(rc);
} }
try (FileReader input = new FileReader(args[0])) { try (FileReader input = new FileReader(args[0])) {
// Setup // Setup
Scanner scanner = new Scanner(new BufferedReader(input)); Scanner scanner = new Scanner(new BufferedReader(input));
Parser parser = new Parser(scanner); Parser parser = new Parser(scanner);
Package p = parser.parse(); Package p = parser.parse();
// Display // Display
// ASTDisplay display = new ASTDisplay(); // ASTDisplay display = new ASTDisplay();
// display.showTree(p); // display.showTree(p);
// Contextual Analyzer // Contextual Analyzer
IdTable table = new IdTable(); IdTable table = new IdTable();
Analyzer analyzer = new Analyzer(); Analyzer analyzer = new Analyzer();
analyzer.visitPackage(p, table); analyzer.visitPackage(p, table);
// Compilation // Compilation
if(Reporter.error) { if (Reporter.error) {
System.exit(rc); System.exit(rc);
} else { } else {
// Build mJAM assembly // Build mJAM assembly
Encoder encoder = new Encoder(); Encoder encoder = new Encoder();
encoder.visitPackage(p, null); encoder.visitPackage(p, null);
// Create object file // Create object file
int pos = args[0].lastIndexOf(".java"); int pos = args[0].lastIndexOf(".java");
String objectFileName = args[0].substring(0, pos) + ".mJAM"; String objectFileName = args[0].substring(0, pos) + ".mJAM";
ObjectFile objF = new ObjectFile(objectFileName); ObjectFile objF = new ObjectFile(objectFileName);
if(objF.write()) { if (objF.write()) {
Reporter.emit("Object File Failed."); Reporter.emit("Object File Failed.");
} }
} }
System.exit(0); System.exit(0);
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Reporter.emit(e.getMessage()); Reporter.emit(e.getMessage());
} catch (IOException e) { } catch (IOException e) {
Reporter.emit(e.getMessage()); Reporter.emit(e.getMessage());
} }
System.exit(rc); System.exit(rc);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -11,117 +11,117 @@ import miniJava.AbstractSyntaxTrees.*;
*/ */
public class IdTable { public class IdTable {
private IdTable parent; private IdTable parent;
private ArrayList<HashMap<String, Declaration>> scope; private ArrayList<HashMap<String, Declaration>> scope;
// /////////////////////////////////////////////////////////////////////////////
//
// CONSTRUCTORS
//
// /////////////////////////////////////////////////////////////////////////////
// ///////////////////////////////////////////////////////////////////////////// /**
// *
// CONSTRUCTORS */
// public IdTable() {
// ///////////////////////////////////////////////////////////////////////////// this(null);
}
/** /**
* *
*/ * @param parent
public IdTable() { */
this(null); public IdTable(IdTable parent) {
} this.parent = parent;
this.scope = new ArrayList<>();
push();
}
/** // /////////////////////////////////////////////////////////////////////////////
* //
* @param parent // ACTIVE SCOPE
*/ //
public IdTable(IdTable parent) { // /////////////////////////////////////////////////////////////////////////////
this.parent = parent;
this.scope = new ArrayList<>();
push();
}
/**
*
*/
public void pop() {
int last = scope.size() - 1;
scope.remove(last);
}
// ///////////////////////////////////////////////////////////////////////////// /**
// *
// ACTIVE SCOPE */
// public void push() {
// ///////////////////////////////////////////////////////////////////////////// HashMap<String, Declaration> nested = new HashMap<>();
scope.add(nested);
}
/** /**
* *
*/ */
public void pop() { public void add(Declaration decl) {
int last = scope.size() - 1; for (int i = 0; i < scope.size(); i++) {
scope.remove(last); HashMap<String, Declaration> nest = scope.get(i);
} if (nest.containsKey(decl.name)) {
/** Declaration prev = nest.get(decl.name);
*
*/
public void push() {
HashMap<String, Declaration> nested = new HashMap<>();
scope.add(nested);
}
/** if (decl instanceof ClassDecl) {
* Reporter.report(decl, prev, "Class");
*/ } else if (decl instanceof FieldDecl) {
public void add(Declaration decl) { Reporter.report(decl, prev, "Field");
for(int i = 0; i < scope.size(); i++) { } else if (decl instanceof MethodDecl) {
HashMap<String, Declaration> nest = scope.get(i); Reporter.report(decl, prev, "Method");
if(nest.containsKey(decl.name)) { } else if (decl instanceof ParameterDecl) {
Reporter.report(decl, prev, "Parameter");
} else if (decl instanceof VarDecl) {
Reporter.report(decl, prev, "Variable");
}
Declaration prev = nest.get(decl.name); System.exit(Compiler.rc);
}
}
if(decl instanceof ClassDecl) { scope.get(scope.size() - 1).put(decl.name, decl);
Reporter.report(decl, prev, "Class"); }
} else if(decl instanceof FieldDecl) {
Reporter.report(decl, prev, "Field");
} else if(decl instanceof MethodDecl) {
Reporter.report(decl, prev, "Method");
} else if(decl instanceof ParameterDecl) {
Reporter.report(decl, prev, "Parameter");
} else if(decl instanceof VarDecl) {
Reporter.report(decl, prev, "Variable");
}
System.exit(Compiler.rc); // /////////////////////////////////////////////////////////////////////////////
} //
} // GETTERS
//
// /////////////////////////////////////////////////////////////////////////////
scope.get(scope.size()-1).put(decl.name, decl); /**
} *
* @param name
*/
public Declaration getDeclaration(String name) {
IdTable current = this;
while (current != null) {
Declaration decl = current.getDeclarationAtScope(name);
if (decl == null)
current = current.parent;
else
return decl;
}
return null;
}
// ///////////////////////////////////////////////////////////////////////////// /**
// *
// GETTERS * @param name
// */
// ///////////////////////////////////////////////////////////////////////////// public Declaration getDeclarationAtScope(String name) {
for (int i = scope.size() - 1; i >= 0; i--) {
HashMap<String, Declaration> nest = scope.get(i);
if (nest.containsKey(name))
return nest.get(name);
}
/** return null;
* }
* @param name
*/
public Declaration getDeclaration(String name) {
IdTable current = this;
while (current != null) {
Declaration decl = current.getDeclarationAtScope(name);
if (decl == null) current = current.parent;
else return decl;
}
return null;
}
/**
*
* @param name
*/
public Declaration getDeclarationAtScope(String name) {
for (int i = scope.size() - 1; i >= 0; i--) {
HashMap<String, Declaration> nest = scope.get(i);
if (nest.containsKey(name)) return nest.get(name);
}
return null;
}
} }

View File

@ -4,24 +4,25 @@ import miniJava.AbstractSyntaxTrees.Declaration;
public class Reporter { public class Reporter {
public static boolean error = false; public static boolean error = false;
/** /**
* *
* @param message * @param message
*/ */
public static void emit(String message) { public static void emit(String message) {
error = true; error = true;
System.out.println("***" + message); System.out.println("***" + message);
} }
/** /**
* Redefinitions * Redefinitions
* @param d1 *
* @param d2 * @param d1
*/ * @param d2
public static void report(Declaration d1, Declaration d2, String prefix) { */
emit(prefix + " at " + d1.posn + " previously defined at " + d2.posn); public static void report(Declaration d1, Declaration d2, String prefix) {
} emit(prefix + " at " + d1.posn + " previously defined at " + d2.posn);
}
} }

File diff suppressed because it is too large Load Diff

View File

@ -7,10 +7,10 @@ import java.io.IOException;
*/ */
public class ParsingException extends IOException { public class ParsingException extends IOException {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public ParsingException(SourcePosition posn) { public ParsingException(SourcePosition posn) {
super("Parsing error at " + posn); super("Parsing error at " + posn);
} }
} }

View File

@ -4,303 +4,300 @@ import java.io.*;
public class Scanner { public class Scanner {
private int col = 1; private int col = 1;
private int line = 1; private int line = 1;
private boolean predefined; private boolean predefined;
private BufferedReader input; private BufferedReader input;
/** /**
* *
* @param input * @param input
*/ */
public Scanner(BufferedReader input) { public Scanner(BufferedReader input) {
this(input, false); this(input, false);
} }
/** /**
* *
* @param input * @param input
* @param predefined * @param predefined
*/ */
public Scanner(String input, boolean predefined) { public Scanner(String input, boolean predefined) {
this(new BufferedReader(new StringReader(input)), predefined); this(new BufferedReader(new StringReader(input)), predefined);
} }
/** /**
* *
* @param input * @param input
* @param predefined * @param predefined
*/ */
public Scanner(BufferedReader input, boolean predefined) { public Scanner(BufferedReader input, boolean predefined) {
this.input = input; this.input = input;
this.predefined = predefined; this.predefined = predefined;
} }
// /////////////////////////////////////////////////////////////////////////////
//
// Scanning
//
// /////////////////////////////////////////////////////////////////////////////
// ///////////////////////////////////////////////////////////////////////////// /**
// *
// Scanning * @return
// * @throws IOException
// ///////////////////////////////////////////////////////////////////////////// */
public Token scan() throws IOException {
Token token = null;
String spelling = "";
/** while (token == null) {
*
* @return
* @throws IOException
*/
public Token scan() throws IOException {
Token token = null;
String spelling = "";
while (token == null) { int c = read();
SourcePosition posn = new SourcePosition(col, line);
int c = read(); if (c == -1) {
SourcePosition posn = new SourcePosition(col, line); token = new Token("", Token.TYPE.EOT, posn);
} else {
spelling += (char) c;
if(c == -1) { switch (c) {
token = new Token("", Token.TYPE.EOT, posn);
} else {
spelling += (char) c;
switch(c) { // Operators
case '*':
case '+':
case '-': {
if (peek(c))
throw new ScanningException(posn);
token = new Token(spelling, Token.TYPE.BINOP, posn);
break;
}
// Operators // Comment
case '*': case '/': {
case '+': if (peek('*')) {
case '-': { read();
if(peek(c)) throw new ScanningException(posn); readMultiLineComment();
token = new Token(spelling, Token.TYPE.BINOP, posn); spelling = "";
break; } else if (peek('/')) {
} readSingleLineComment();
spelling = "";
} else {
token = new Token(spelling, Token.TYPE.BINOP, posn);
}
// Comment break;
case '/': { }
if(peek('*')) {
read();
readMultiLineComment();
spelling = "";
} else if(peek('/')) {
readSingleLineComment();
spelling = "";
} else {
token = new Token(spelling, Token.TYPE.BINOP, posn);
}
break; // Relational
} case '>':
case '<': {
if (peek('='))
spelling += (char) read();
token = new Token(spelling, Token.TYPE.BINOP, posn);
break;
}
// Relational // Negation
case '>': case '!': {
case '<': { if (peek('=')) {
if (peek('=')) spelling += (char) read(); spelling += (char) read();
token = new Token(spelling, Token.TYPE.BINOP, posn); token = new Token(spelling, Token.TYPE.BINOP, posn);
break; } else {
} token = new Token(spelling, Token.TYPE.UNOP, posn);
}
// Negation break;
case '!': { }
if(peek('=')) {
spelling += (char) read();
token = new Token(spelling, Token.TYPE.BINOP, posn);
} else {
token = new Token(spelling, Token.TYPE.UNOP, posn);
}
break; // Logical
} case '&':
case '|': {
if (!peek(c)) {
throw new ScanningException(posn);
} else {
spelling += (char) read();
token = new Token(spelling, Token.TYPE.BINOP, posn);
}
// Logical break;
case '&': }
case '|': {
if(!peek(c)) {
throw new ScanningException(posn);
} else {
spelling += (char) read();
token = new Token(spelling, Token.TYPE.BINOP, posn);
}
break; // Other Operators
} case '=': {
if (peek('=')) {
spelling += (char) read();
token = new Token(spelling, Token.TYPE.BINOP, posn);
} else {
token = new Token(spelling, Token.TYPE.EQUALS, posn);
}
// Other Operators break;
case '=': { }
if(peek('=')) {
spelling += (char) read();
token = new Token(spelling, Token.TYPE.BINOP, posn);
} else {
token = new Token(spelling, Token.TYPE.EQUALS, posn);
}
break; // Miscellaneous
} case '.':
case ',':
case '[':
case ']':
case '{':
case '}':
case '(':
case ')':
case ';': {
token = new Token(spelling, Token.symbols.get(c), posn);
break;
}
// Miscellaneous default: {
case '.':
case ',':
case '[':
case ']':
case '{':
case '}':
case '(':
case ')':
case ';': {
token = new Token(spelling, Token.symbols.get(c), posn);
break;
}
default: { // Identifier or keyword
if (isAlpha(c)) {
int next = peek();
while (isAlpha(next) || isDigit(next) || next == '_') {
spelling += (char) read();
next = peek();
}
// Identifier or keyword if (Token.keywords.containsKey(spelling)) {
if(isAlpha(c)) { token = new Token(spelling, Token.keywords.get(spelling), posn);
int next = peek(); } else {
while(isAlpha(next) || isDigit(next) || next == '_') { token = new Token(spelling, Token.TYPE.ID, posn);
spelling += (char) read(); }
next = peek(); }
}
if(Token.keywords.containsKey(spelling)) { // Number
token = new Token(spelling, Token.keywords.get(spelling), posn); else if (isDigit(c)) {
} else { int next = peek();
token = new Token(spelling, Token.TYPE.ID, posn); while (isDigit(next)) {
} spelling += (char) read();
} next = peek();
}
// Number token = new Token(spelling, Token.TYPE.NUM, posn);
else if(isDigit(c)) { }
int next = peek();
while(isDigit(next)) {
spelling += (char) read();
next = peek();
}
token = new Token(spelling, Token.TYPE.NUM, posn); // Whitespace
} else if (isWhitespace(c)) {
spelling = "";
}
// Whitespace // Unrecognized Character
else if(isWhitespace(c)) { else {
spelling = ""; throw new ScanningException(posn);
} }
}
}
}
}
// Unrecognized Character return token;
else { }
throw new ScanningException(posn);
}
}
}
}
}
return token; // /////////////////////////////////////////////////////////////////////////////
} //
// Convenience Methods
//
// /////////////////////////////////////////////////////////////////////////////
/**
*
* @param c
* @return
*/
private boolean isAlpha(int c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (predefined && c == '_');
}
/**
*
* @param c
* @return
*/
private boolean isDigit(int c) {
return c >= '0' && c <= '9';
}
// ///////////////////////////////////////////////////////////////////////////// /**
// *
// Convenience Methods * @param c
// * @return
// ///////////////////////////////////////////////////////////////////////////// */
private boolean isWhitespace(int c) {
return c == ' ' || c == '\n' || c == '\r' || c == '\t';
}
/** /**
* *
* @param c * @return
* @return * @throws IOException
*/ */
private boolean isAlpha(int c) { private int peek() throws IOException {
return (c >= 'a' && c <= 'z') input.mark(1);
|| (c >= 'A' && c <= 'Z') int next = input.read();
|| (predefined && c == '_'); input.reset();
}
/** return next;
* }
* @param c
* @return
*/
private boolean isDigit(int c) {
return c >= '0' && c <= '9';
}
/** /**
* *
* @param c * @param c
* @return * @return
*/ * @throws IOException
private boolean isWhitespace(int c) { */
return c == ' ' || c == '\n' || c == '\r' || c == '\t'; private boolean peek(int c) throws IOException {
} input.mark(1);
int next = input.read();
input.reset();
/** return c == next;
* }
* @return
* @throws IOException
*/
private int peek() throws IOException {
input.mark(1);
int next = input.read();
input.reset();
return next; /**
} *
* @return
* @throws IOException
*/
private int read() throws IOException {
int next = input.read();
if (next == '\n' || next == '\r') {
col = 1;
line += 1;
} else {
col += 1;
}
/** return next;
* }
* @param c
* @return
* @throws IOException
*/
private boolean peek(int c) throws IOException {
input.mark(1);
int next = input.read();
input.reset();
return c == next; /**
} *
* @throws IOException
*/
private void readSingleLineComment() throws IOException {
col = 1;
line += 1;
input.readLine();
}
/** /**
* *
* @return * @throws IOException
* @throws IOException */
*/ private void readMultiLineComment() throws IOException {
private int read() throws IOException { int prev = '\0';
int next = input.read(); int current = '\0';
if(next == '\n' || next == '\r') {
col = 1;
line += 1;
} else {
col += 1;
}
return next; while (prev != '*' || current != '/') {
} prev = current;
current = read();
/** // Unterminated
* if (current == -1) {
* @throws IOException SourcePosition posn = new SourcePosition(line, col);
*/ throw new ScanningException(posn);
private void readSingleLineComment() throws IOException { }
col = 1; }
line += 1; }
input.readLine();
}
/**
*
* @throws IOException
*/
private void readMultiLineComment() throws IOException {
int prev = '\0';
int current = '\0';
while(prev != '*' || current != '/') {
prev = current;
current = read();
// Unterminated
if(current == -1) {
SourcePosition posn = new SourcePosition(line, col);
throw new ScanningException(posn);
}
}
}
} }

View File

@ -7,10 +7,10 @@ import java.io.IOException;
*/ */
public class ScanningException extends IOException { public class ScanningException extends IOException {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public ScanningException(SourcePosition posn) { public ScanningException(SourcePosition posn) {
super("Scanning error at " + posn); super("Scanning error at " + posn);
} }
} }

View File

@ -5,16 +5,16 @@ package miniJava.SyntacticAnalyzer;
*/ */
public class SourcePosition { public class SourcePosition {
public final int col; public final int col;
public final int line; public final int line;
public SourcePosition(int col, int line) { public SourcePosition(int col, int line) {
this.col = col; this.col = col;
this.line = line; this.line = line;
} }
@Override @Override
public String toString() { public String toString() {
return "(Line: " + line + ", Column: " + col + ")"; return "(Line: " + line + ", Column: " + col + ")";
} }
} }

View File

@ -7,88 +7,63 @@ import java.util.HashMap;
*/ */
public class Token { 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
}; };
// Pair words with enumeration // Pair words with enumeration
public final static HashMap<String, TYPE> keywords; public final static HashMap<String, TYPE> keywords;
static {
keywords = new HashMap<String, TYPE>();
keywords.put("class", TYPE.CLASS);
keywords.put("return", TYPE.RETURN);
keywords.put("public", TYPE.PUBLIC);
keywords.put("private", TYPE.PRIVATE);
keywords.put("static", TYPE.STATIC);
keywords.put("int", TYPE.INT);
keywords.put("boolean", TYPE.BOOLEAN);
keywords.put("void", TYPE.VOID);
keywords.put("this", TYPE.THIS);
keywords.put("if", TYPE.IF);
keywords.put("else", TYPE.ELSE);
keywords.put("while", TYPE.WHILE);
keywords.put("true", TYPE.TRUE);
keywords.put("false", TYPE.FALSE);
keywords.put("new", TYPE.NEW);
}
// Pair symbols with enumeration static {
public final static HashMap<Integer, TYPE> symbols; keywords = new HashMap<String, TYPE>();
static { keywords.put("class", TYPE.CLASS);
symbols = new HashMap<Integer, TYPE>(); keywords.put("return", TYPE.RETURN);
symbols.put((int) '.', TYPE.PERIOD); keywords.put("public", TYPE.PUBLIC);
symbols.put((int) ',', TYPE.COMMA); keywords.put("private", TYPE.PRIVATE);
symbols.put((int) '[', TYPE.LSQUARE); keywords.put("static", TYPE.STATIC);
symbols.put((int) ']', TYPE.RSQUARE); keywords.put("int", TYPE.INT);
symbols.put((int) '{', TYPE.LBRACKET); keywords.put("boolean", TYPE.BOOLEAN);
symbols.put((int) '}', TYPE.RBRACKET); keywords.put("void", TYPE.VOID);
symbols.put((int) '(', TYPE.LPAREN); keywords.put("this", TYPE.THIS);
symbols.put((int) ')', TYPE.RPAREN); keywords.put("if", TYPE.IF);
symbols.put((int) ';', TYPE.SEMICOLON); keywords.put("else", TYPE.ELSE);
} keywords.put("while", TYPE.WHILE);
keywords.put("true", TYPE.TRUE);
keywords.put("false", TYPE.FALSE);
keywords.put("new", TYPE.NEW);
}
public final TYPE type; // Pair symbols with enumeration
public final String spelling; public final static HashMap<Integer, TYPE> symbols;
public final SourcePosition posn;
public Token(String spelling, TYPE type, SourcePosition posn) { static {
this.type = type; symbols = new HashMap<Integer, TYPE>();
this.posn = posn; symbols.put((int) '.', TYPE.PERIOD);
this.spelling = spelling; symbols.put((int) ',', TYPE.COMMA);
} symbols.put((int) '[', TYPE.LSQUARE);
symbols.put((int) ']', TYPE.RSQUARE);
symbols.put((int) '{', TYPE.LBRACKET);
symbols.put((int) '}', TYPE.RBRACKET);
symbols.put((int) '(', TYPE.LPAREN);
symbols.put((int) ')', TYPE.RPAREN);
symbols.put((int) ';', TYPE.SEMICOLON);
}
public final TYPE type;
public final String spelling;
public final SourcePosition posn;
public Token(String spelling, TYPE type, SourcePosition posn) {
this.type = type;
this.posn = posn;
this.spelling = spelling;
}
} }

View File

@ -13,59 +13,58 @@ import java.util.concurrent.Executors;
*/ */
public class Checkpoint1 { 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); if (x.getName().indexOf("pass") != -1) {
if (x.getName().indexOf("pass") != -1) { if (returnCode == 0)
if (returnCode == 0) System.out.println(x.getName() + " passed successfully!");
System.out.println(x.getName() + " passed successfully!"); else {
else { failures++;
failures++; System.err.println(x.getName() + " failed but should have passed!");
System.err.println(x.getName() }
+ " failed but should have passed!"); } else {
} if (returnCode == 4)
} else { System.out.println(x.getName() + " failed successfully!");
if (returnCode == 4) else {
System.out.println(x.getName() + " failed successfully!"); System.err.println(x.getName() + " did not fail properly!");
else { failures++;
System.err.println(x.getName() + " did not fail properly!"); }
failures++; }
} }
} System.out.println(failures + " failures in all.");
} }
System.out.println(failures + " failures in all.");
}
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())
Process p = pb.start(); .directory(new File(System.getProperty("java.class.path")));
threadPool.execute(new ProcessOutputter(p.getInputStream(), false)); Process p = pb.start();
p.waitFor(); threadPool.execute(new ProcessOutputter(p.getInputStream(), false));
return p.exitValue(); p.waitFor();
} return p.exitValue();
}
static class ProcessOutputter implements Runnable { static class ProcessOutputter implements Runnable {
private Scanner processOutput; private Scanner processOutput;
private boolean output; private boolean output;
public ProcessOutputter(InputStream _processStream, boolean _output) { public ProcessOutputter(InputStream _processStream, boolean _output) {
processOutput = new Scanner(_processStream); processOutput = new Scanner(_processStream);
output = _output; output = _output;
} }
@Override
public void run() {
while(processOutput.hasNextLine()) {
String line = processOutput.nextLine();
if (output)
System.out.println(line);
}
}
@Override
public void run() {
while (processOutput.hasNextLine()) {
String line = processOutput.nextLine();
if (output)
System.out.println(line);
}
}
} }
} }

View File

@ -14,85 +14,83 @@ import java.util.Scanner;
public class Checkpoint2 { 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) {
returnCode = _returnCode;
ast = _ast;
}
}
public static void main(String[] args) throws IOException, InterruptedException { public ReturnInfo(int _returnCode, String _ast) {
File testDir = new File(System.getProperty("java.class.path") returnCode = _returnCode;
+ "/../tests/pa2_tests"); ast = _ast;
int failures = 0; }
for (File x : testDir.listFiles()) { }
if (x.getName().endsWith("out") || x.getName().startsWith("."))
continue;
ReturnInfo info = runTest(x);
int returnCode = info.returnCode;
String ast = info.ast;
if (x.getName().indexOf("pass") != -1) {
if (returnCode == 0) {
String actualAST = getAST(new FileInputStream(x.getPath() + ".out"));
if (actualAST.equals(ast))
System.out.println(x.getName() + " parsed successfully and has a correct AST!");
else {
System.err.println(x.getName() + " parsed successfully but has an incorrect AST!");
failures++;
}
}
else {
failures++;
System.err.println(x.getName()
+ " failed to be parsed!");
}
} else {
if (returnCode == 4)
System.out.println(x.getName() + " failed successfully!");
else {
System.err.println(x.getName() + " did not fail properly!");
failures++;
}
}
}
System.out.println(failures + " failures in all.");
}
private static ReturnInfo runTest(File x) throws IOException, InterruptedException { public static void main(String[] args) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath()).directory(new File(System.getProperty("java.class.path"))); File testDir = new File(System.getProperty("java.class.path") + "/../tests/pa2_tests");
pb.redirectErrorStream(true); int failures = 0;
Process p = pb.start(); for (File x : testDir.listFiles()) {
if (x.getName().endsWith("out") || x.getName().startsWith("."))
continue;
ReturnInfo info = runTest(x);
int returnCode = info.returnCode;
String ast = info.ast;
if (x.getName().indexOf("pass") != -1) {
if (returnCode == 0) {
String actualAST = getAST(new FileInputStream(x.getPath() + ".out"));
if (actualAST.equals(ast))
System.out.println(x.getName() + " parsed successfully and has a correct AST!");
else {
System.err.println(x.getName() + " parsed successfully but has an incorrect AST!");
failures++;
}
} else {
failures++;
System.err.println(x.getName() + " failed to be parsed!");
}
} else {
if (returnCode == 4)
System.out.println(x.getName() + " failed successfully!");
else {
System.err.println(x.getName() + " did not fail properly!");
failures++;
}
}
}
System.out.println(failures + " failures in all.");
}
String ast = getAST(p.getInputStream()); private static ReturnInfo runTest(File x) throws IOException, InterruptedException {
p.waitFor(); ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath())
int exitValue = p.exitValue(); .directory(new File(System.getProperty("java.class.path")));
return new ReturnInfo(exitValue, ast); pb.redirectErrorStream(true);
} Process p = pb.start();
String ast = getAST(p.getInputStream());
p.waitFor();
int exitValue = p.exitValue();
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;
while (scan.hasNextLine()) { while (scan.hasNextLine()) {
String line = scan.nextLine(); String line = scan.nextLine();
if (line.equals("======= AST Display =========================")) { if (line.equals("======= AST Display =========================")) {
line = scan.nextLine(); line = scan.nextLine();
while(scan.hasNext() && !line.equals("=============================================")) { while (scan.hasNext() && !line.equals("=============================================")) {
ast += line + "\n"; ast += line + "\n";
line = scan.nextLine(); line = scan.nextLine();
} }
} }
if (line.startsWith("*** ")) if (line.startsWith("*** "))
System.out.println(line); System.out.println(line);
if (line.startsWith("ERROR")) { if (line.startsWith("ERROR")) {
System.out.println(line); System.out.println(line);
while(scan.hasNext()) while (scan.hasNext())
System.out.println(scan.next()); System.out.println(scan.next());
} }
} }
scan.close(); scan.close();
return ast; return ast;
} }
} }

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,60 +13,57 @@ import java.util.Scanner;
public class Checkpoint3 { public class Checkpoint3 {
public static void main(String[] args) throws IOException, InterruptedException {
File testDir = new File(System.getProperty("java.class.path") + "/../tests/pa3_tests");
int failures = 0;
for (File x : testDir.listFiles()) {
if (x.getName().endsWith("out") || x.getName().startsWith(".") || x.getName().endsWith("mJAM")
|| x.getName().endsWith("asm"))
continue;
int returnCode = runTest(x);
if (x.getName().indexOf("pass") != -1) {
if (returnCode == 0) {
System.out.println(x.getName() + " processed successfully!");
} else {
failures++;
System.err.println(x.getName() + " failed to be processed!");
}
} else {
if (returnCode == 4)
System.out.println(x.getName() + " failed successfully!");
else {
System.err.println(x.getName() + " did not fail properly!");
failures++;
}
}
}
System.out.println(failures + " failures in all.");
}
public static void main(String[] args) throws IOException, InterruptedException { private static int runTest(File x) throws IOException, InterruptedException {
File testDir = new File(System.getProperty("java.class.path") ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath())
+ "/../tests/pa3_tests"); .directory(new File(System.getProperty("java.class.path")));
int failures = 0; pb.redirectErrorStream(true);
for (File x : testDir.listFiles()) { Process p = pb.start();
if (x.getName().endsWith("out") || x.getName().startsWith(".") || x.getName().endsWith("mJAM") || x.getName().endsWith("asm"))
continue;
int returnCode = runTest(x);
if (x.getName().indexOf("pass") != -1) {
if (returnCode == 0) {
System.out.println(x.getName() + " processed successfully!");
}
else {
failures++;
System.err.println(x.getName()
+ " failed to be processed!");
}
} else {
if (returnCode == 4)
System.out.println(x.getName() + " failed successfully!");
else {
System.err.println(x.getName() + " did not fail properly!");
failures++;
}
}
}
System.out.println(failures + " failures in all.");
}
private static int runTest(File x) throws IOException, InterruptedException { processStream(p.getInputStream());
ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath()).directory(new File(System.getProperty("java.class.path"))); p.waitFor();
pb.redirectErrorStream(true); int exitValue = p.exitValue();
Process p = pb.start(); return exitValue;
}
processStream(p.getInputStream()); public static void processStream(InputStream stream) {
p.waitFor(); Scanner scan = new Scanner(stream);
int exitValue = p.exitValue(); while (scan.hasNextLine()) {
return exitValue; String line = scan.nextLine();
} if (line.startsWith("*** "))
System.out.println(line);
if (line.startsWith("ERROR")) {
public static void processStream(InputStream stream) { System.out.println(line);
Scanner scan = new Scanner(stream); // while(scan.hasNext())
while (scan.hasNextLine()) { // System.out.println(scan.next());
String line = scan.nextLine(); }
if (line.startsWith("*** ")) }
System.out.println(line); scan.close();
if (line.startsWith("ERROR")) { }
System.out.println(line);
//while(scan.hasNext())
//System.out.println(scan.next());
}
}
scan.close();
}
} }

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,99 +13,96 @@ import java.util.Scanner;
public class Checkpoint4 { public class Checkpoint4 {
public static void main(String[] args) throws IOException, InterruptedException {
File testDir = new File(System.getProperty("java.class.path") + "/../tests/pa4_tests");
int failures = 0;
for (File x : testDir.listFiles()) {
if (x.getName().startsWith(".") || x.getName().endsWith("mJAM") || x.getName().endsWith("asm"))
continue;
int returnCode = runTest(x);
if (x.getName().indexOf("pass") != -1) {
if (returnCode == 0) {
try {
int val = executeTest(x);
int expected = Integer.parseInt(x.getName().substring(5, 7));
if (val == expected)
System.out.println(x.getName() + " ran successfully!");
else {
failures++;
System.err
.println(x.getName() + " compiled but did not run successfully--got output " + val);
}
} catch (Exception ex) {
failures++;
System.err.println(x.getName() + " did not output correctly.");
}
} else {
failures++;
System.err.println(x.getName() + " failed to be processed!");
}
} else {
if (returnCode == 4)
System.out.println(x.getName() + " failed successfully!");
else {
System.err.println(x.getName() + " did not fail properly!");
failures++;
}
}
}
System.out.println(failures + " failures in all.");
}
public static void main(String[] args) throws IOException, InterruptedException { private static int runTest(File x) throws IOException, InterruptedException {
File testDir = new File(System.getProperty("java.class.path") ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath())
+ "/../tests/pa4_tests"); .directory(new File(System.getProperty("java.class.path")));
int failures = 0; pb.redirectErrorStream(true);
for (File x : testDir.listFiles()) { Process p = pb.start();
if (x.getName().startsWith(".") || x.getName().endsWith("mJAM") || x.getName().endsWith("asm"))
continue;
int returnCode = runTest(x);
if (x.getName().indexOf("pass") != -1) {
if (returnCode == 0) {
try {
int val = executeTest(x);
int expected = Integer.parseInt(x.getName().substring(5,7));
if (val == expected)
System.out.println(x.getName() + " ran successfully!");
else {
failures++;
System.err.println(x.getName() + " compiled but did not run successfully--got output " + val);
}
}
catch(Exception ex) {
failures++;
System.err.println(x.getName() + " did not output correctly.");
}
}
else {
failures++;
System.err.println(x.getName()
+ " failed to be processed!");
}
} else {
if (returnCode == 4)
System.out.println(x.getName() + " failed successfully!");
else {
System.err.println(x.getName() + " did not fail properly!");
failures++;
}
}
}
System.out.println(failures + " failures in all.");
}
private static int runTest(File x) throws IOException, InterruptedException { processStream(p.getInputStream());
ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath()).directory(new File(System.getProperty("java.class.path"))); p.waitFor();
pb.redirectErrorStream(true); int exitValue = p.exitValue();
Process p = pb.start(); return exitValue;
}
processStream(p.getInputStream()); private static int executeTest(File x) throws IOException, InterruptedException {
p.waitFor(); ProcessBuilder pb = new ProcessBuilder("java", "mJAM.Interpreter", x.getPath().replace(".java", ".mJAM"))
int exitValue = p.exitValue(); .directory(new File(System.getProperty("java.class.path")));
return exitValue; Process process = pb.start();
}
private static int executeTest(File x) throws IOException, InterruptedException { Scanner scan = new Scanner(process.getInputStream());
ProcessBuilder pb = new ProcessBuilder("java", "mJAM.Interpreter", x.getPath().replace(".java", ".mJAM")).directory(new File(System.getProperty("java.class.path"))); int num = -1;
Process process = pb.start(); while (scan.hasNextLine()) {
String line = scan.nextLine();
if (line.startsWith(">>> ")) {
num = Integer.parseInt(line.substring(4));
System.out.println("Result = " + num);
break;
}
}
while (scan.hasNextLine()) {
String line = scan.nextLine();
if (line.startsWith("*** ")) {
System.out.println(line);
break;
}
}
scan.close();
Scanner scan = new Scanner(process.getInputStream()); return num;
int num = -1; }
while (scan.hasNextLine()) {
String line = scan.nextLine();
if (line.startsWith(">>> ")) {
num = Integer.parseInt(line.substring(4));
System.out.println("Result = " + num);
break;
}
}
while (scan.hasNextLine()) {
String line = scan.nextLine();
if (line.startsWith("*** ")) {
System.out.println(line);
break;
}
}
scan.close();
return num; public static void processStream(InputStream stream) {
} Scanner scan = new Scanner(stream);
while (scan.hasNextLine()) {
String line = scan.nextLine();
public static void processStream(InputStream stream) { if (line.startsWith("*** "))
Scanner scan = new Scanner(stream); System.out.println(line);
while (scan.hasNextLine()) { if (line.startsWith("ERROR")) {
String line = scan.nextLine(); System.out.println(line);
if (line.startsWith("*** ")) // while(scan.hasNext())
System.out.println(line); // System.out.println(scan.next());
if (line.startsWith("ERROR")) { }
System.out.println(line); }
//while(scan.hasNext()) scan.close();
//System.out.println(scan.next()); }
}
}
scan.close();
}
} }