format
parent
518ca35a68
commit
72f3b2b497
|
@ -1,5 +1,5 @@
|
||||||
package mJAM;
|
package mJAM;
|
||||||
|
|
||||||
public class Assembler {
|
public class Assembler {
|
||||||
// TBD
|
// TBD
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
|
||||||
* @param instr the instruction to display.
|
|
||||||
*/
|
|
||||||
private void writeInstruction(Instruction instr) {
|
|
||||||
|
|
||||||
String targetLabel = "***";
|
/**
|
||||||
// get label of destination addr, if instr transfers control
|
* Writes the given instruction in assembly-code format.
|
||||||
if (instr.r == Machine.Reg.CB.ordinal())
|
*
|
||||||
targetLabel = addrToLabel.get(instr.d);
|
* @param instr
|
||||||
|
* the instruction to display.
|
||||||
|
*/
|
||||||
|
private void writeInstruction(Instruction instr) {
|
||||||
|
|
||||||
Machine.Op instruction = Machine.intToOp[instr.op];
|
String targetLabel = "***";
|
||||||
asmWrite(String.format("%-7s",instruction.toString()));
|
// get label of destination addr, if instr transfers control
|
||||||
switch (instruction) {
|
if (instr.r == Machine.Reg.CB.ordinal())
|
||||||
case LOAD:
|
targetLabel = addrToLabel.get(instr.d);
|
||||||
blankN();
|
|
||||||
writeD(instr.d);
|
|
||||||
writeR('[', instr.r, ']');
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LOADA:
|
Machine.Op instruction = Machine.intToOp[instr.op];
|
||||||
blankN();
|
asmWrite(String.format("%-7s", instruction.toString()));
|
||||||
writeD(instr.d);
|
switch (instruction) {
|
||||||
writeR('[', instr.r, ']');
|
case LOAD:
|
||||||
break;
|
blankN();
|
||||||
|
writeD(instr.d);
|
||||||
|
writeR('[', instr.r, ']');
|
||||||
|
break;
|
||||||
|
|
||||||
case LOADI:
|
case LOADA:
|
||||||
break;
|
blankN();
|
||||||
|
writeD(instr.d);
|
||||||
|
writeR('[', instr.r, ']');
|
||||||
|
break;
|
||||||
|
|
||||||
case LOADL:
|
case LOADI:
|
||||||
blankN();
|
break;
|
||||||
writeD(instr.d);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case STORE:
|
case LOADL:
|
||||||
blankN();
|
blankN();
|
||||||
writeD(instr.d);
|
writeD(instr.d);
|
||||||
writeR('[', instr.r, ']');
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case STOREI:
|
case STORE:
|
||||||
break;
|
blankN();
|
||||||
|
writeD(instr.d);
|
||||||
|
writeR('[', instr.r, ']');
|
||||||
|
break;
|
||||||
|
|
||||||
case CALL:
|
case STOREI:
|
||||||
if (instr.r == Machine.Reg.PB.ordinal()) {
|
break;
|
||||||
blankN();
|
|
||||||
writePrimitive(instr.d);
|
|
||||||
} else {
|
|
||||||
blankN();
|
|
||||||
asmWrite(targetLabel);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CALLI:
|
case CALL:
|
||||||
blankN();
|
if (instr.r == Machine.Reg.PB.ordinal()) {
|
||||||
asmWrite(targetLabel);
|
blankN();
|
||||||
break;
|
writePrimitive(instr.d);
|
||||||
|
} else {
|
||||||
|
blankN();
|
||||||
|
asmWrite(targetLabel);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case RETURN:
|
case CALLI:
|
||||||
writeN(instr.n);
|
blankN();
|
||||||
writeD(instr.d);
|
asmWrite(targetLabel);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CALLD:
|
case RETURN:
|
||||||
blankN();
|
writeN(instr.n);
|
||||||
writeD(instr.d);
|
writeD(instr.d);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUSH:
|
case CALLD:
|
||||||
blankN();
|
blankN();
|
||||||
writeD(instr.d);
|
writeD(instr.d);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POP:
|
case PUSH:
|
||||||
blankN();
|
blankN();
|
||||||
writeD(instr.d);
|
writeD(instr.d);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JUMP:
|
case POP:
|
||||||
blankN();
|
blankN();
|
||||||
asmWrite(targetLabel);
|
writeD(instr.d);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JUMPI:
|
case JUMP:
|
||||||
break;
|
blankN();
|
||||||
|
asmWrite(targetLabel);
|
||||||
|
break;
|
||||||
|
|
||||||
case JUMPIF:
|
case JUMPI:
|
||||||
writeN(instr.n);
|
break;
|
||||||
asmWrite(targetLabel);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HALT:
|
case JUMPIF:
|
||||||
writeN(instr.n);
|
writeN(instr.n);
|
||||||
break;
|
asmWrite(targetLabel);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
case HALT:
|
||||||
asmWrite("???? ");
|
writeN(instr.n);
|
||||||
writeN(instr.n);
|
break;
|
||||||
writeD(instr.d);
|
|
||||||
writeR('[', instr.r, ']');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
default:
|
||||||
* disassembles program held in code store
|
asmWrite("???? ");
|
||||||
*/
|
writeN(instr.n);
|
||||||
void disassembleProgram(String asmFileName) {
|
writeD(instr.d);
|
||||||
|
writeR('[', instr.r, ']');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
/**
|
||||||
asmOut = new FileWriter(asmFileName);
|
* disassembles program held in code store
|
||||||
} catch (IOException e) {
|
*/
|
||||||
System.out.println("Disassembler: can not create asm output file "
|
void disassembleProgram(String asmFileName) {
|
||||||
+ asmName);
|
|
||||||
error = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// collect all addresses that may be the target of a jump instruction
|
try {
|
||||||
SortedSet<Integer> targets = new TreeSet<Integer>();
|
asmOut = new FileWriter(asmFileName);
|
||||||
for (int addr = Machine.CB; addr < Machine.CT; addr++) {
|
} catch (IOException e) {
|
||||||
Instruction inst = Machine.code[addr];
|
System.out.println("Disassembler: can not create asm output file " + asmName);
|
||||||
Machine.Op op = Machine.intToOp[inst.op];
|
error = true;
|
||||||
switch (op) {
|
return;
|
||||||
case CALL:
|
}
|
||||||
case CALLI:
|
|
||||||
// only consider calls (branches) within code memory (i.e. not primitives)
|
|
||||||
if (inst.r == Machine.Reg.CB.ordinal())
|
|
||||||
targets.add(inst.d);
|
|
||||||
break;
|
|
||||||
case JUMP:
|
|
||||||
// address following an unconditional branch is an implicit target
|
|
||||||
targets.add(addr+1);
|
|
||||||
targets.add(inst.d);
|
|
||||||
break;
|
|
||||||
case JUMPIF:
|
|
||||||
// a jump of any sort creates a branch target
|
|
||||||
targets.add(inst.d);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// map branch target addresses to unique labels
|
// collect all addresses that may be the target of a jump instruction
|
||||||
addrToLabel = new HashMap<Integer, String>();
|
SortedSet<Integer> targets = new TreeSet<Integer>();
|
||||||
int labelCounter = 10;
|
for (int addr = Machine.CB; addr < Machine.CT; addr++) {
|
||||||
for (Integer addr : targets) {
|
Instruction inst = Machine.code[addr];
|
||||||
String label = "L" + labelCounter++ ;
|
Machine.Op op = Machine.intToOp[inst.op];
|
||||||
addrToLabel.put(addr, label);
|
switch (op) {
|
||||||
}
|
case CALL:
|
||||||
|
case CALLI:
|
||||||
|
// only consider calls (branches) within code memory (i.e. not
|
||||||
|
// primitives)
|
||||||
|
if (inst.r == Machine.Reg.CB.ordinal())
|
||||||
|
targets.add(inst.d);
|
||||||
|
break;
|
||||||
|
case JUMP:
|
||||||
|
// address following an unconditional branch is an implicit
|
||||||
|
// target
|
||||||
|
targets.add(addr + 1);
|
||||||
|
targets.add(inst.d);
|
||||||
|
break;
|
||||||
|
case JUMPIF:
|
||||||
|
// a jump of any sort creates a branch target
|
||||||
|
targets.add(inst.d);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// disassemble each instruction
|
// map branch target addresses to unique labels
|
||||||
for (int addr = Machine.CB; addr < Machine.CT; addr++) {
|
addrToLabel = new HashMap<Integer, String>();
|
||||||
|
int labelCounter = 10;
|
||||||
// generate instruction address
|
for (Integer addr : targets) {
|
||||||
asmWrite(String.format("%3d ", addr));
|
String label = "L" + labelCounter++;
|
||||||
|
addrToLabel.put(addr, label);
|
||||||
|
}
|
||||||
|
|
||||||
// if this addr is a branch target, output label
|
// disassemble each instruction
|
||||||
if (addrToLabel.containsKey(addr))
|
for (int addr = Machine.CB; addr < Machine.CT; addr++) {
|
||||||
asmWrite(String.format("%-7s", addrToLabel.get(addr) + ":"));
|
|
||||||
else
|
|
||||||
asmWrite(" ");
|
|
||||||
|
|
||||||
// instruction
|
// generate instruction address
|
||||||
writeInstruction(Machine.code[addr]);
|
asmWrite(String.format("%3d ", addr));
|
||||||
|
|
||||||
// newline
|
// if this addr is a branch target, output label
|
||||||
asmWrite("\n");
|
if (addrToLabel.containsKey(addr))
|
||||||
}
|
asmWrite(String.format("%-7s", addrToLabel.get(addr) + ":"));
|
||||||
|
else
|
||||||
|
asmWrite(" ");
|
||||||
|
|
||||||
// close output file
|
// instruction
|
||||||
try {
|
writeInstruction(Machine.code[addr]);
|
||||||
asmOut.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void asmWrite(String s) {
|
// newline
|
||||||
try {
|
asmWrite("\n");
|
||||||
asmOut.write(s);
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
// close output file
|
||||||
System.out.println("********** mJAM Disassembler (1.0) **********");
|
try {
|
||||||
String objectFileName = "obj.mJAM";
|
asmOut.close();
|
||||||
if (args.length == 1)
|
} catch (IOException e) {
|
||||||
objectFileName = args[0];
|
error = true;
|
||||||
Disassembler d = new Disassembler(objectFileName);
|
}
|
||||||
d.disassemble();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
private void asmWrite(String s) {
|
||||||
* Disassemble object file
|
try {
|
||||||
* @return true if error encountered else false
|
asmOut.write(s);
|
||||||
*/
|
} catch (IOException e) {
|
||||||
public boolean disassemble() {
|
error = true;
|
||||||
ObjectFile objectFile = new ObjectFile(objectFileName);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// read object file into code store
|
public static void main(String[] args) {
|
||||||
if (objectFile.read()) {
|
System.out.println("********** mJAM Disassembler (1.0) **********");
|
||||||
System.out.println("Disassembler: unable to read object file"
|
String objectFileName = "obj.mJAM";
|
||||||
+ objectFileName);
|
if (args.length == 1)
|
||||||
return true;
|
objectFileName = args[0];
|
||||||
}
|
Disassembler d = new Disassembler(objectFileName);
|
||||||
|
d.disassemble();
|
||||||
|
}
|
||||||
|
|
||||||
// assembler-code output file name
|
/**
|
||||||
if (objectFileName.endsWith(".mJAM"))
|
* Disassemble object file
|
||||||
asmName = objectFileName.substring(0, objectFileName.length() - 5)
|
*
|
||||||
+ ".asm";
|
* @return true if error encountered else false
|
||||||
else
|
*/
|
||||||
asmName = objectFileName + ".asm";
|
public boolean disassemble() {
|
||||||
|
ObjectFile objectFile = new ObjectFile(objectFileName);
|
||||||
|
|
||||||
// disassemble to file
|
// read object file into code store
|
||||||
disassembleProgram(asmName);
|
if (objectFile.read()) {
|
||||||
|
System.out.println("Disassembler: unable to read object file" + objectFileName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (error) {
|
// assembler-code output file name
|
||||||
System.out.println("Disassembler: unable to write asm file"
|
if (objectFileName.endsWith(".mJAM"))
|
||||||
+ asmName);
|
asmName = objectFileName.substring(0, objectFileName.length() - 5) + ".asm";
|
||||||
return true;
|
else
|
||||||
}
|
asmName = objectFileName + ".asm";
|
||||||
|
|
||||||
return false;
|
// disassemble to file
|
||||||
}
|
disassembleProgram(asmName);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
System.out.println("Disassembler: unable to write asm file" + asmName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
@ -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
|
|
||||||
*/
|
|
||||||
public enum Op {
|
|
||||||
LOAD,
|
|
||||||
LOADA,
|
|
||||||
LOADI,
|
|
||||||
LOADL,
|
|
||||||
STORE,
|
|
||||||
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 instructions
|
||||||
* mJAM registers
|
*/
|
||||||
*/
|
public enum Op {
|
||||||
public enum Reg {
|
LOAD, LOADA, LOADI, LOADL, STORE, STOREI, CALL, // direct call of
|
||||||
ZR, // zero, not used
|
// instance method
|
||||||
CB, // code base
|
CALLI, // indirect call of instance method
|
||||||
CT, // code top
|
CALLD, // dynamic call of instance method
|
||||||
CP, // code pointer
|
RETURN, PUSH, POP, JUMP, JUMPI, JUMPIF, HALT;
|
||||||
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");
|
public static Op[] intToOp = Op.values();
|
||||||
|
|
||||||
Instruction nextInstr = new Instruction(op, n, r, d);
|
/**
|
||||||
|
* 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;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,60 +11,64 @@ import java.io.FileOutputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
|
|
||||||
public class ObjectFile {
|
public class ObjectFile {
|
||||||
|
|
||||||
String objectFileName;
|
|
||||||
|
|
||||||
public ObjectFile(String objectFileName) {
|
String objectFileName;
|
||||||
super();
|
|
||||||
this.objectFileName = objectFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write code store as object file
|
|
||||||
* @param output object file
|
|
||||||
* @return true if write fails
|
|
||||||
*/
|
|
||||||
public boolean write(){
|
|
||||||
boolean failed = false;
|
|
||||||
try {
|
|
||||||
FileOutputStream objectFile = new FileOutputStream(objectFileName);
|
|
||||||
DataOutputStream is = new DataOutputStream(objectFile);
|
|
||||||
for (int i = Machine.CB; i < Machine.CT; i++ ){
|
|
||||||
Instruction inst = Machine.code[i];
|
|
||||||
is.writeInt(inst.op);
|
|
||||||
is.writeInt(inst.n);
|
|
||||||
is.writeInt(inst.r);
|
|
||||||
is.writeInt(inst.d);
|
|
||||||
}
|
|
||||||
objectFile.close();
|
|
||||||
}
|
|
||||||
catch (Exception e) {failed = true;}
|
|
||||||
return failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
public ObjectFile(String objectFileName) {
|
||||||
* Read object file into code store, setting CT
|
super();
|
||||||
* @return true if object code read fails
|
this.objectFileName = objectFileName;
|
||||||
*/
|
}
|
||||||
public boolean read() {
|
|
||||||
boolean failed = false;
|
/**
|
||||||
try {
|
* Write code store as object file
|
||||||
FileInputStream objectFile = new FileInputStream(objectFileName);
|
*
|
||||||
DataInputStream is = new DataInputStream(objectFile);
|
* @param output
|
||||||
|
* object file
|
||||||
Machine.CT = Machine.CB;
|
* @return true if write fails
|
||||||
while (is.available() > 0 && Machine.CT < Machine.PB){
|
*/
|
||||||
Instruction inst = new Instruction();
|
public boolean write() {
|
||||||
inst.op = is.readInt();
|
boolean failed = false;
|
||||||
inst.n = is.readInt();
|
try {
|
||||||
inst.r = is.readInt();
|
FileOutputStream objectFile = new FileOutputStream(objectFileName);
|
||||||
inst.d = is.readInt();
|
DataOutputStream is = new DataOutputStream(objectFile);
|
||||||
Machine.code[Machine.CT++] = inst;
|
for (int i = Machine.CB; i < Machine.CT; i++) {
|
||||||
}
|
Instruction inst = Machine.code[i];
|
||||||
objectFile.close();
|
is.writeInt(inst.op);
|
||||||
} catch (Exception e) {
|
is.writeInt(inst.n);
|
||||||
failed = true;
|
is.writeInt(inst.r);
|
||||||
}
|
is.writeInt(inst.d);
|
||||||
return failed;
|
}
|
||||||
}
|
objectFile.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
return failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read object file into code store, setting CT
|
||||||
|
*
|
||||||
|
* @return true if object code read fails
|
||||||
|
*/
|
||||||
|
public boolean read() {
|
||||||
|
boolean failed = false;
|
||||||
|
try {
|
||||||
|
FileInputStream objectFile = new FileInputStream(objectFileName);
|
||||||
|
DataInputStream is = new DataInputStream(objectFile);
|
||||||
|
|
||||||
|
Machine.CT = Machine.CB;
|
||||||
|
while (is.available() > 0 && Machine.CT < Machine.PB) {
|
||||||
|
Instruction inst = new Instruction();
|
||||||
|
inst.op = is.readInt();
|
||||||
|
inst.n = is.readInt();
|
||||||
|
inst.r = is.readInt();
|
||||||
|
inst.d = is.readInt();
|
||||||
|
Machine.code[Machine.CT++] = inst;
|
||||||
|
}
|
||||||
|
objectFile.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
return failed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
|
||||||
System.out.println("Generating test program object code");
|
|
||||||
|
|
||||||
/* class A {
|
|
||||||
* int x;
|
|
||||||
* int p(){return x;}
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
Machine.emit(Op.LOADL,11); // hello
|
|
||||||
Machine.emit(Prim.putintnl);
|
|
||||||
int patchme_coA = Machine.nextInstrAddr();
|
|
||||||
Machine.emit(Op.JUMP,Reg.CB,0); // jump around methods of class A (branch to /*coA*/)
|
|
||||||
|
|
||||||
// code for p() in A
|
|
||||||
int label_pA = Machine.nextInstrAddr();
|
|
||||||
/*pA*/ Machine.emit(Op.LOAD,Reg.OB,0); // x at offset 0 in current instance of A
|
|
||||||
Machine.emit(Op.HALT,4,0,0);
|
|
||||||
Machine.emit(Op.RETURN,1,0,0); // return one value, pop zero args
|
|
||||||
|
|
||||||
// build class object for A at 0[SB]
|
|
||||||
int label_coA = Machine.nextInstrAddr();
|
|
||||||
Machine.patch(patchme_coA, label_coA);
|
|
||||||
/*coA*/ Machine.emit(Op.LOADL,-1); // no superclass object
|
|
||||||
Machine.emit(Op.LOADL,1); // number of methods
|
|
||||||
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
|
|
||||||
|
|
||||||
// code for p() in B
|
|
||||||
int label_pB = Machine.nextInstrAddr();
|
|
||||||
/*pB*/ Machine.emit(Op.LOAD,Reg.OB,0); // x at offset 0 in current instance
|
|
||||||
Machine.emit(Op.LOADL,22);
|
|
||||||
Machine.emit(Op.HALT,4,0,0);
|
|
||||||
Machine.emit(Prim.add);
|
|
||||||
Machine.emit(Op.RETURN,1,0,0); // return one value, pop zero args
|
|
||||||
|
|
||||||
// build class object for B at 3[SB]
|
|
||||||
int label_coB = Machine.nextInstrAddr();
|
|
||||||
Machine.patch(patchme_coB, label_coB);
|
|
||||||
/*coB*/ Machine.emit(Op.LOADA,Reg.SB,0); // addr of superclass object
|
|
||||||
Machine.emit(Op.LOADL,1); // number of methods
|
|
||||||
Machine.emit(Op.LOADA,Reg.CB,label_pB); // code addr of p_B
|
|
||||||
|
|
||||||
|
Machine.initCodeGen();
|
||||||
/* class C {
|
System.out.println("Generating test program object code");
|
||||||
* public static void main(String [] args) {
|
|
||||||
* A a = new A();
|
|
||||||
* a.x = 33;
|
|
||||||
* System.out.println(a.p());
|
|
||||||
* ...
|
|
||||||
*/
|
|
||||||
int patchme_coC = Machine.nextInstrAddr();
|
|
||||||
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
|
|
||||||
|
|
||||||
/* ...
|
|
||||||
* A b = new B();
|
|
||||||
* b.x = 44;
|
|
||||||
* System.out.println(b.p());
|
|
||||||
* } // end main
|
|
||||||
* } // end class C
|
|
||||||
*/
|
|
||||||
// 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
|
|
||||||
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]
|
|
||||||
int label_coC = Machine.nextInstrAddr();
|
|
||||||
Machine.patch(patchme_coC, label_coC);
|
|
||||||
/*coC*/ Machine.emit(Op.LOADL,-1); // no superclass object
|
|
||||||
Machine.emit(Op.LOADL,0); // number of methods = 0
|
|
||||||
|
|
||||||
/*
|
|
||||||
* End of class declarations - call main
|
|
||||||
*/
|
|
||||||
Machine.emit(Op.LOADL,Machine.nullRep); // put null on stack as value of main's arg
|
|
||||||
Machine.emit(Op.CALL,Reg.CB,label_mainC); // call known static main()
|
|
||||||
Machine.emit(Op.LOADL,88); // goodbye
|
|
||||||
Machine.emit(Prim.putintnl);
|
|
||||||
Machine.emit(Machine.Op.HALT,0,0,0); // halt
|
|
||||||
|
|
||||||
/* write code as an object file */
|
/*
|
||||||
String objectCodeFileName = "test.mJAM";
|
* class A { int x; int p(){return x;} }
|
||||||
ObjectFile objF = new ObjectFile(objectCodeFileName);
|
*/
|
||||||
System.out.print("Writing object code file " + objectCodeFileName + " ... ");
|
Machine.emit(Op.LOADL, 11); // hello
|
||||||
if (objF.write()) {
|
Machine.emit(Prim.putintnl);
|
||||||
System.out.println("FAILED!");
|
int patchme_coA = Machine.nextInstrAddr();
|
||||||
return;
|
Machine.emit(Op.JUMP, Reg.CB, 0); // jump around methods of class A
|
||||||
}
|
// (branch to /*coA*/)
|
||||||
else
|
|
||||||
System.out.println("SUCCEEDED");
|
|
||||||
|
|
||||||
/* create asm file using disassembler */
|
|
||||||
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");
|
// code for p() in A
|
||||||
}
|
int label_pA = Machine.nextInstrAddr();
|
||||||
|
/* pA */ Machine.emit(Op.LOAD, Reg.OB, 0); // x at offset 0 in current
|
||||||
|
// instance of A
|
||||||
|
Machine.emit(Op.HALT, 4, 0, 0);
|
||||||
|
Machine.emit(Op.RETURN, 1, 0, 0); // return one value, pop zero args
|
||||||
|
|
||||||
|
// build class object for A at 0[SB]
|
||||||
|
int label_coA = Machine.nextInstrAddr();
|
||||||
|
Machine.patch(patchme_coA, label_coA);
|
||||||
|
/* coA */ Machine.emit(Op.LOADL, -1); // no superclass object
|
||||||
|
Machine.emit(Op.LOADL, 1); // number of methods
|
||||||
|
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
|
||||||
|
|
||||||
|
// code for p() in B
|
||||||
|
int label_pB = Machine.nextInstrAddr();
|
||||||
|
/* pB */ Machine.emit(Op.LOAD, Reg.OB, 0); // x at offset 0 in current
|
||||||
|
// instance
|
||||||
|
Machine.emit(Op.LOADL, 22);
|
||||||
|
Machine.emit(Op.HALT, 4, 0, 0);
|
||||||
|
Machine.emit(Prim.add);
|
||||||
|
Machine.emit(Op.RETURN, 1, 0, 0); // return one value, pop zero args
|
||||||
|
|
||||||
|
// build class object for B at 3[SB]
|
||||||
|
int label_coB = Machine.nextInstrAddr();
|
||||||
|
Machine.patch(patchme_coB, label_coB);
|
||||||
|
/* coB */ Machine.emit(Op.LOADA, Reg.SB, 0); // addr of superclass
|
||||||
|
// object
|
||||||
|
Machine.emit(Op.LOADL, 1); // number of methods
|
||||||
|
Machine.emit(Op.LOADA, Reg.CB, label_pB); // code addr of p_B
|
||||||
|
|
||||||
|
/*
|
||||||
|
* class C { public static void main(String [] args) { A a = new A();
|
||||||
|
* a.x = 33; System.out.println(a.p()); ...
|
||||||
|
*/
|
||||||
|
int patchme_coC = Machine.nextInstrAddr();
|
||||||
|
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
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ... A b = new B(); b.x = 44; System.out.println(b.p()); } // end main
|
||||||
|
* } // end class C
|
||||||
|
*/
|
||||||
|
// 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
|
||||||
|
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]
|
||||||
|
int label_coC = Machine.nextInstrAddr();
|
||||||
|
Machine.patch(patchme_coC, label_coC);
|
||||||
|
/* coC */ Machine.emit(Op.LOADL, -1); // no superclass object
|
||||||
|
Machine.emit(Op.LOADL, 0); // number of methods = 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* End of class declarations - call main
|
||||||
|
*/
|
||||||
|
Machine.emit(Op.LOADL, Machine.nullRep); // put null on stack as value
|
||||||
|
// of main's arg
|
||||||
|
Machine.emit(Op.CALL, Reg.CB, label_mainC); // call known static main()
|
||||||
|
Machine.emit(Op.LOADL, 88); // goodbye
|
||||||
|
Machine.emit(Prim.putintnl);
|
||||||
|
Machine.emit(Machine.Op.HALT, 0, 0, 0); // halt
|
||||||
|
|
||||||
|
/* write code as an object file */
|
||||||
|
String objectCodeFileName = "test.mJAM";
|
||||||
|
ObjectFile objF = new ObjectFile(objectCodeFileName);
|
||||||
|
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 */
|
||||||
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
|
||||||
return eltType + " Array";
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type eltType;
|
public String toString() {
|
||||||
|
return eltType + " Array";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type eltType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
|
||||||
return "Class " + className.spelling;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier className;
|
public String toString() {
|
||||||
|
return "Class " + className.spelling;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Identifier className;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,52 +4,53 @@ import mJAM.Machine;
|
||||||
import miniJava.AbstractSyntaxTrees.*;
|
import miniJava.AbstractSyntaxTrees.*;
|
||||||
|
|
||||||
public class Code {
|
public class Code {
|
||||||
|
|
||||||
public boolean addr;
|
|
||||||
public Declaration decl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If addr true, returns the address of the declaration.
|
|
||||||
* Otherwise, uses the size of the declaration in its place.
|
|
||||||
* @param op
|
|
||||||
* @param decl
|
|
||||||
* @param addr
|
|
||||||
*/
|
|
||||||
public Code(Declaration decl, boolean addr) {
|
|
||||||
this.decl = decl;
|
|
||||||
this.addr = addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param index
|
|
||||||
*/
|
|
||||||
public void modify(int instr) {
|
|
||||||
|
|
||||||
// Setup size
|
public boolean addr;
|
||||||
switch(decl.type.typeKind) {
|
public Declaration decl;
|
||||||
case ARRAY:
|
|
||||||
case CLASS:
|
/**
|
||||||
Machine.code[instr].n = Machine.addressSize;
|
* If addr true, returns the address of the declaration. Otherwise, uses the
|
||||||
case INT:
|
* size of the declaration in its place.
|
||||||
Machine.code[instr].n = Machine.integerSize;
|
*
|
||||||
case BOOLEAN:
|
* @param op
|
||||||
Machine.code[instr].n = Machine.booleanSize;
|
* @param decl
|
||||||
case VOID:
|
* @param addr
|
||||||
Machine.code[instr].n = 0;
|
*/
|
||||||
default:
|
public Code(Declaration decl, boolean addr) {
|
||||||
Machine.code[instr].n = -1;
|
this.decl = decl;
|
||||||
}
|
this.addr = addr;
|
||||||
|
}
|
||||||
// Setup displacement
|
|
||||||
if(addr) {
|
/**
|
||||||
Machine.code[instr].d += decl.entity.addr;
|
*
|
||||||
} else {
|
* @param index
|
||||||
Machine.code[instr].d += decl.entity.size;
|
*/
|
||||||
}
|
public void modify(int instr) {
|
||||||
|
|
||||||
// Setup register
|
// Setup size
|
||||||
Machine.code[instr].r = decl.entity.reg.ordinal();
|
switch (decl.type.typeKind) {
|
||||||
}
|
case ARRAY:
|
||||||
|
case CLASS:
|
||||||
|
Machine.code[instr].n = Machine.addressSize;
|
||||||
|
case INT:
|
||||||
|
Machine.code[instr].n = Machine.integerSize;
|
||||||
|
case BOOLEAN:
|
||||||
|
Machine.code[instr].n = Machine.booleanSize;
|
||||||
|
case VOID:
|
||||||
|
Machine.code[instr].n = 0;
|
||||||
|
default:
|
||||||
|
Machine.code[instr].n = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup displacement
|
||||||
|
if (addr) {
|
||||||
|
Machine.code[instr].d += decl.entity.addr;
|
||||||
|
} else {
|
||||||
|
Machine.code[instr].d += decl.entity.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup register
|
||||||
|
Machine.code[instr].r = decl.entity.reg.ordinal();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
// ASTDisplay display = new ASTDisplay();
|
|
||||||
// display.showTree(p);
|
|
||||||
|
|
||||||
// Contextual Analyzer
|
|
||||||
IdTable table = new IdTable();
|
|
||||||
Analyzer analyzer = new Analyzer();
|
|
||||||
analyzer.visitPackage(p, table);
|
|
||||||
|
|
||||||
// Compilation
|
|
||||||
if(Reporter.error) {
|
|
||||||
System.exit(rc);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// Build mJAM assembly
|
|
||||||
Encoder encoder = new Encoder();
|
|
||||||
encoder.visitPackage(p, null);
|
|
||||||
|
|
||||||
// Create object file
|
|
||||||
int pos = args[0].lastIndexOf(".java");
|
|
||||||
String objectFileName = args[0].substring(0, pos) + ".mJAM";
|
|
||||||
ObjectFile objF = new ObjectFile(objectFileName);
|
|
||||||
if(objF.write()) {
|
|
||||||
Reporter.emit("Object File Failed.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
System.exit(0);
|
|
||||||
|
|
||||||
} catch (FileNotFoundException e) {
|
// Display
|
||||||
Reporter.emit(e.getMessage());
|
// ASTDisplay display = new ASTDisplay();
|
||||||
} catch (IOException e) {
|
// display.showTree(p);
|
||||||
Reporter.emit(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
System.exit(rc);
|
// Contextual Analyzer
|
||||||
}
|
IdTable table = new IdTable();
|
||||||
|
Analyzer analyzer = new Analyzer();
|
||||||
|
analyzer.visitPackage(p, table);
|
||||||
|
|
||||||
|
// Compilation
|
||||||
|
if (Reporter.error) {
|
||||||
|
System.exit(rc);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Build mJAM assembly
|
||||||
|
Encoder encoder = new Encoder();
|
||||||
|
encoder.visitPackage(p, null);
|
||||||
|
|
||||||
|
// Create object file
|
||||||
|
int pos = args[0].lastIndexOf(".java");
|
||||||
|
String objectFileName = args[0].substring(0, pos) + ".mJAM";
|
||||||
|
ObjectFile objF = new ObjectFile(objectFileName);
|
||||||
|
if (objF.write()) {
|
||||||
|
Reporter.emit("Object File Failed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.exit(0);
|
||||||
|
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
Reporter.emit(e.getMessage());
|
||||||
|
} catch (IOException e) {
|
||||||
|
Reporter.emit(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
System.exit(rc);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,118 +10,118 @@ import miniJava.AbstractSyntaxTrees.*;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class IdTable {
|
public class IdTable {
|
||||||
|
|
||||||
private IdTable parent;
|
|
||||||
private ArrayList<HashMap<String, Declaration>> scope;
|
|
||||||
|
|
||||||
|
|
||||||
// /////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// CONSTRUCTORS
|
|
||||||
//
|
|
||||||
// /////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/**
|
private IdTable parent;
|
||||||
*
|
private ArrayList<HashMap<String, Declaration>> scope;
|
||||||
*/
|
|
||||||
public IdTable() {
|
|
||||||
this(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param parent
|
|
||||||
*/
|
|
||||||
public IdTable(IdTable parent) {
|
|
||||||
this.parent = parent;
|
|
||||||
this.scope = new ArrayList<>();
|
|
||||||
push();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// /////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// ACTIVE SCOPE
|
|
||||||
//
|
|
||||||
// /////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/**
|
// /////////////////////////////////////////////////////////////////////////////
|
||||||
*
|
//
|
||||||
*/
|
// CONSTRUCTORS
|
||||||
public void pop() {
|
//
|
||||||
int last = scope.size() - 1;
|
// /////////////////////////////////////////////////////////////////////////////
|
||||||
scope.remove(last);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void push() {
|
|
||||||
HashMap<String, Declaration> nested = new HashMap<>();
|
|
||||||
scope.add(nested);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void add(Declaration decl) {
|
|
||||||
for(int i = 0; i < scope.size(); i++) {
|
|
||||||
HashMap<String, Declaration> nest = scope.get(i);
|
|
||||||
if(nest.containsKey(decl.name)) {
|
|
||||||
|
|
||||||
Declaration prev = nest.get(decl.name);
|
|
||||||
|
|
||||||
if(decl instanceof ClassDecl) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scope.get(scope.size()-1).put(decl.name, decl);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// /////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// GETTERS
|
|
||||||
//
|
|
||||||
// /////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param name
|
*/
|
||||||
*/
|
public IdTable() {
|
||||||
public Declaration getDeclaration(String name) {
|
this(null);
|
||||||
IdTable current = this;
|
}
|
||||||
while (current != null) {
|
|
||||||
Declaration decl = current.getDeclarationAtScope(name);
|
|
||||||
if (decl == null) current = current.parent;
|
|
||||||
else return decl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
/**
|
||||||
}
|
*
|
||||||
|
* @param parent
|
||||||
/**
|
*/
|
||||||
*
|
public IdTable(IdTable parent) {
|
||||||
* @param name
|
this.parent = parent;
|
||||||
*/
|
this.scope = new ArrayList<>();
|
||||||
public Declaration getDeclarationAtScope(String name) {
|
push();
|
||||||
for (int i = scope.size() - 1; i >= 0; i--) {
|
}
|
||||||
HashMap<String, Declaration> nest = scope.get(i);
|
|
||||||
if (nest.containsKey(name)) return nest.get(name);
|
// /////////////////////////////////////////////////////////////////////////////
|
||||||
}
|
//
|
||||||
|
// ACTIVE SCOPE
|
||||||
return null;
|
//
|
||||||
}
|
// /////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void pop() {
|
||||||
|
int last = scope.size() - 1;
|
||||||
|
scope.remove(last);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void push() {
|
||||||
|
HashMap<String, Declaration> nested = new HashMap<>();
|
||||||
|
scope.add(nested);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void add(Declaration decl) {
|
||||||
|
for (int i = 0; i < scope.size(); i++) {
|
||||||
|
HashMap<String, Declaration> nest = scope.get(i);
|
||||||
|
if (nest.containsKey(decl.name)) {
|
||||||
|
|
||||||
|
Declaration prev = nest.get(decl.name);
|
||||||
|
|
||||||
|
if (decl instanceof ClassDecl) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.get(scope.size() - 1).put(decl.name, decl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// /////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// GETTERS
|
||||||
|
//
|
||||||
|
// /////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,25 +3,26 @@ package miniJava.ContextualAnalyzer;
|
||||||
import miniJava.AbstractSyntaxTrees.Declaration;
|
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
|
@ -6,11 +6,11 @@ import java.io.IOException;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ParsingException extends IOException {
|
public class ParsingException extends IOException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public ParsingException(SourcePosition posn) {
|
private static final long serialVersionUID = 1L;
|
||||||
super("Parsing error at " + posn);
|
|
||||||
}
|
public ParsingException(SourcePosition posn) {
|
||||||
|
super("Parsing error at " + posn);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -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
|
|
||||||
*/
|
|
||||||
public Scanner(BufferedReader input) {
|
|
||||||
this(input, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param input
|
|
||||||
* @param predefined
|
|
||||||
*/
|
|
||||||
public Scanner(String input, boolean predefined) {
|
|
||||||
this(new BufferedReader(new StringReader(input)), predefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param input
|
|
||||||
* @param predefined
|
|
||||||
*/
|
|
||||||
public Scanner(BufferedReader input, boolean predefined) {
|
|
||||||
this.input = input;
|
|
||||||
this.predefined = predefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// /////////////////////////////////////////////////////////////////////////////
|
/**
|
||||||
//
|
*
|
||||||
// Scanning
|
* @param input
|
||||||
//
|
*/
|
||||||
// /////////////////////////////////////////////////////////////////////////////
|
public Scanner(BufferedReader input) {
|
||||||
|
this(input, false);
|
||||||
/**
|
}
|
||||||
*
|
|
||||||
* @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);
|
|
||||||
|
|
||||||
if(c == -1) {
|
|
||||||
token = new Token("", Token.TYPE.EOT, posn);
|
|
||||||
} else {
|
|
||||||
spelling += (char) c;
|
|
||||||
|
|
||||||
switch(c) {
|
|
||||||
|
|
||||||
// Operators
|
/**
|
||||||
case '*':
|
*
|
||||||
case '+':
|
* @param input
|
||||||
case '-': {
|
* @param predefined
|
||||||
if(peek(c)) throw new ScanningException(posn);
|
*/
|
||||||
token = new Token(spelling, Token.TYPE.BINOP, posn);
|
public Scanner(String input, boolean predefined) {
|
||||||
break;
|
this(new BufferedReader(new StringReader(input)), predefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comment
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Negation
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Miscellaneous
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Token.keywords.containsKey(spelling)) {
|
|
||||||
token = new Token(spelling, Token.keywords.get(spelling), posn);
|
|
||||||
} else {
|
|
||||||
token = new Token(spelling, Token.TYPE.ID, posn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Number
|
|
||||||
else if(isDigit(c)) {
|
|
||||||
int next = peek();
|
|
||||||
while(isDigit(next)) {
|
|
||||||
spelling += (char) read();
|
|
||||||
next = peek();
|
|
||||||
}
|
|
||||||
|
|
||||||
token = new Token(spelling, Token.TYPE.NUM, posn);
|
/**
|
||||||
}
|
*
|
||||||
|
* @param input
|
||||||
// Whitespace
|
* @param predefined
|
||||||
else if(isWhitespace(c)) {
|
*/
|
||||||
spelling = "";
|
public Scanner(BufferedReader input, boolean predefined) {
|
||||||
}
|
this.input = input;
|
||||||
|
this.predefined = predefined;
|
||||||
// Unrecognized Character
|
}
|
||||||
else {
|
|
||||||
throw new ScanningException(posn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return token;
|
// /////////////////////////////////////////////////////////////////////////////
|
||||||
}
|
//
|
||||||
|
// Scanning
|
||||||
|
//
|
||||||
|
// /////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public Token scan() throws IOException {
|
||||||
|
Token token = null;
|
||||||
|
String spelling = "";
|
||||||
|
|
||||||
|
while (token == null) {
|
||||||
// /////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// 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';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param c
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private boolean isWhitespace(int c) {
|
|
||||||
return c == ' ' || c == '\n' || c == '\r' || c == '\t';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
private int peek() throws IOException {
|
|
||||||
input.mark(1);
|
|
||||||
int next = input.read();
|
|
||||||
input.reset();
|
|
||||||
|
|
||||||
return next;
|
int c = read();
|
||||||
}
|
SourcePosition posn = new SourcePosition(col, line);
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param c
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
private boolean peek(int c) throws IOException {
|
|
||||||
input.mark(1);
|
|
||||||
int next = input.read();
|
|
||||||
input.reset();
|
|
||||||
|
|
||||||
return c == next;
|
if (c == -1) {
|
||||||
}
|
token = new Token("", Token.TYPE.EOT, posn);
|
||||||
|
} else {
|
||||||
/**
|
spelling += (char) c;
|
||||||
*
|
|
||||||
* @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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
private void readSingleLineComment() throws IOException {
|
|
||||||
col = 1;
|
|
||||||
line += 1;
|
|
||||||
input.readLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
switch (c) {
|
||||||
*
|
|
||||||
* @throws IOException
|
// Operators
|
||||||
*/
|
case '*':
|
||||||
private void readMultiLineComment() throws IOException {
|
case '+':
|
||||||
int prev = '\0';
|
case '-': {
|
||||||
int current = '\0';
|
if (peek(c))
|
||||||
|
throw new ScanningException(posn);
|
||||||
while(prev != '*' || current != '/') {
|
token = new Token(spelling, Token.TYPE.BINOP, posn);
|
||||||
prev = current;
|
break;
|
||||||
current = read();
|
}
|
||||||
|
|
||||||
// Unterminated
|
// Comment
|
||||||
if(current == -1) {
|
case '/': {
|
||||||
SourcePosition posn = new SourcePosition(line, col);
|
if (peek('*')) {
|
||||||
throw new ScanningException(posn);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Negation
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Miscellaneous
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Token.keywords.containsKey(spelling)) {
|
||||||
|
token = new Token(spelling, Token.keywords.get(spelling), posn);
|
||||||
|
} else {
|
||||||
|
token = new Token(spelling, Token.TYPE.ID, posn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Number
|
||||||
|
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 = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unrecognized Character
|
||||||
|
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';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean isWhitespace(int c) {
|
||||||
|
return c == ' ' || c == '\n' || c == '\r' || c == '\t';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private int peek() throws IOException {
|
||||||
|
input.mark(1);
|
||||||
|
int next = input.read();
|
||||||
|
input.reset();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,11 @@ import java.io.IOException;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ScanningException extends IOException {
|
public class ScanningException extends IOException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public ScanningException(SourcePosition posn) {
|
private static final long serialVersionUID = 1L;
|
||||||
super("Scanning error at " + posn);
|
|
||||||
}
|
public ScanningException(SourcePosition posn) {
|
||||||
|
super("Scanning error at " + posn);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,88 +7,63 @@ import java.util.HashMap;
|
||||||
*/
|
*/
|
||||||
public class Token {
|
public class Token {
|
||||||
|
|
||||||
public enum TYPE {
|
public enum TYPE {
|
||||||
|
|
||||||
// Terminals
|
|
||||||
ID,
|
|
||||||
NUM,
|
|
||||||
UNOP,
|
|
||||||
BINOP,
|
|
||||||
EQUALS,
|
|
||||||
PERIOD,
|
|
||||||
COMMA,
|
|
||||||
LPAREN,
|
|
||||||
RPAREN,
|
|
||||||
LSQUARE,
|
|
||||||
RSQUARE,
|
|
||||||
LBRACKET,
|
|
||||||
RBRACKET,
|
|
||||||
SEMICOLON,
|
|
||||||
|
|
||||||
// Keywords
|
// Terminals
|
||||||
IF,
|
ID, NUM, UNOP, BINOP, EQUALS, PERIOD, COMMA, LPAREN, RPAREN, LSQUARE, RSQUARE, LBRACKET, RBRACKET, SEMICOLON,
|
||||||
ELSE,
|
|
||||||
NEW,
|
|
||||||
INT,
|
|
||||||
VOID,
|
|
||||||
THIS,
|
|
||||||
TRUE,
|
|
||||||
FALSE,
|
|
||||||
CLASS,
|
|
||||||
WHILE,
|
|
||||||
RETURN,
|
|
||||||
BOOLEAN,
|
|
||||||
STATIC,
|
|
||||||
PUBLIC,
|
|
||||||
PRIVATE,
|
|
||||||
|
|
||||||
// End of Token Stream
|
// Keywords
|
||||||
EOT
|
IF, ELSE, NEW, INT, VOID, THIS, TRUE, FALSE, CLASS, WHILE, RETURN, BOOLEAN, STATIC, PUBLIC, PRIVATE,
|
||||||
};
|
|
||||||
|
|
||||||
// Pair words with enumeration
|
// End of Token Stream
|
||||||
public final static HashMap<String, TYPE> keywords;
|
EOT
|
||||||
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
|
|
||||||
public final static HashMap<Integer, TYPE> symbols;
|
|
||||||
static {
|
|
||||||
symbols = new HashMap<Integer, TYPE>();
|
|
||||||
symbols.put((int) '.', TYPE.PERIOD);
|
|
||||||
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;
|
// Pair words with enumeration
|
||||||
public final String spelling;
|
public final static HashMap<String, TYPE> keywords;
|
||||||
public final SourcePosition posn;
|
|
||||||
|
|
||||||
public Token(String spelling, TYPE type, SourcePosition posn) {
|
static {
|
||||||
this.type = type;
|
keywords = new HashMap<String, TYPE>();
|
||||||
this.posn = posn;
|
keywords.put("class", TYPE.CLASS);
|
||||||
this.spelling = spelling;
|
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
|
||||||
|
public final static HashMap<Integer, TYPE> symbols;
|
||||||
|
|
||||||
|
static {
|
||||||
|
symbols = new HashMap<Integer, TYPE>();
|
||||||
|
symbols.put((int) '.', TYPE.PERIOD);
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,60 +12,59 @@ import java.util.concurrent.Executors;
|
||||||
* Put your tests in "tests/pa1_tests" folder in your Eclipse workspace directory
|
* Put your tests in "tests/pa1_tests" folder in your Eclipse workspace directory
|
||||||
*/
|
*/
|
||||||
public class Checkpoint1 {
|
public class Checkpoint1 {
|
||||||
|
|
||||||
static ExecutorService threadPool = Executors.newCachedThreadPool();
|
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException, InterruptedException {
|
static ExecutorService threadPool = Executors.newCachedThreadPool();
|
||||||
File testDir = new File(System.getProperty("java.class.path")
|
|
||||||
+ "/../tests/pa1_tests");
|
public static void main(String[] args) throws IOException, InterruptedException {
|
||||||
int failures = 0;
|
File testDir = new File(System.getProperty("java.class.path") + "/../tests/pa1_tests");
|
||||||
for (File x : testDir.listFiles()) {
|
int failures = 0;
|
||||||
int returnCode = runTest(x);
|
for (File x : testDir.listFiles()) {
|
||||||
if (x.getName().indexOf("pass") != -1) {
|
int returnCode = runTest(x);
|
||||||
if (returnCode == 0)
|
if (x.getName().indexOf("pass") != -1) {
|
||||||
System.out.println(x.getName() + " passed successfully!");
|
if (returnCode == 0)
|
||||||
else {
|
System.out.println(x.getName() + " passed successfully!");
|
||||||
failures++;
|
else {
|
||||||
System.err.println(x.getName()
|
failures++;
|
||||||
+ " failed but should have passed!");
|
System.err.println(x.getName() + " failed but should have passed!");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (returnCode == 4)
|
if (returnCode == 4)
|
||||||
System.out.println(x.getName() + " failed successfully!");
|
System.out.println(x.getName() + " failed successfully!");
|
||||||
else {
|
else {
|
||||||
System.err.println(x.getName() + " did not fail properly!");
|
System.err.println(x.getName() + " did not fail properly!");
|
||||||
failures++;
|
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 {
|
|
||||||
private Scanner processOutput;
|
static class ProcessOutputter implements Runnable {
|
||||||
private boolean output;
|
private Scanner processOutput;
|
||||||
|
private boolean output;
|
||||||
public ProcessOutputter(InputStream _processStream, boolean _output) {
|
|
||||||
processOutput = new Scanner(_processStream);
|
public ProcessOutputter(InputStream _processStream, boolean _output) {
|
||||||
output = _output;
|
processOutput = new Scanner(_processStream);
|
||||||
}
|
output = _output;
|
||||||
@Override
|
}
|
||||||
public void run() {
|
|
||||||
while(processOutput.hasNextLine()) {
|
@Override
|
||||||
String line = processOutput.nextLine();
|
public void run() {
|
||||||
if (output)
|
while (processOutput.hasNextLine()) {
|
||||||
System.out.println(line);
|
String line = processOutput.nextLine();
|
||||||
}
|
if (output)
|
||||||
}
|
System.out.println(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,86 +13,84 @@ import java.util.Scanner;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class Checkpoint2 {
|
public class Checkpoint2 {
|
||||||
|
|
||||||
private static class ReturnInfo {
|
|
||||||
int returnCode;
|
|
||||||
String ast;
|
|
||||||
public ReturnInfo(int _returnCode, String _ast) {
|
|
||||||
returnCode = _returnCode;
|
|
||||||
ast = _ast;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException, InterruptedException {
|
|
||||||
File testDir = new File(System.getProperty("java.class.path")
|
|
||||||
+ "/../tests/pa2_tests");
|
|
||||||
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 {
|
|
||||||
ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath()).directory(new File(System.getProperty("java.class.path")));
|
|
||||||
pb.redirectErrorStream(true);
|
|
||||||
Process p = pb.start();
|
|
||||||
|
|
||||||
String ast = getAST(p.getInputStream());
|
private static class ReturnInfo {
|
||||||
p.waitFor();
|
int returnCode;
|
||||||
int exitValue = p.exitValue();
|
String ast;
|
||||||
return new ReturnInfo(exitValue, ast);
|
|
||||||
}
|
public ReturnInfo(int _returnCode, String _ast) {
|
||||||
|
returnCode = _returnCode;
|
||||||
|
ast = _ast;
|
||||||
public static String getAST(InputStream stream) {
|
}
|
||||||
Scanner scan = new Scanner(stream);
|
}
|
||||||
String ast = null;
|
|
||||||
while (scan.hasNextLine()) {
|
public static void main(String[] args) throws IOException, InterruptedException {
|
||||||
String line = scan.nextLine();
|
File testDir = new File(System.getProperty("java.class.path") + "/../tests/pa2_tests");
|
||||||
if (line.equals("======= AST Display =========================")) {
|
int failures = 0;
|
||||||
line = scan.nextLine();
|
for (File x : testDir.listFiles()) {
|
||||||
while(scan.hasNext() && !line.equals("=============================================")) {
|
if (x.getName().endsWith("out") || x.getName().startsWith("."))
|
||||||
ast += line + "\n";
|
continue;
|
||||||
line = scan.nextLine();
|
ReturnInfo info = runTest(x);
|
||||||
}
|
int returnCode = info.returnCode;
|
||||||
}
|
String ast = info.ast;
|
||||||
if (line.startsWith("*** "))
|
if (x.getName().indexOf("pass") != -1) {
|
||||||
System.out.println(line);
|
if (returnCode == 0) {
|
||||||
if (line.startsWith("ERROR")) {
|
String actualAST = getAST(new FileInputStream(x.getPath() + ".out"));
|
||||||
System.out.println(line);
|
if (actualAST.equals(ast))
|
||||||
while(scan.hasNext())
|
System.out.println(x.getName() + " parsed successfully and has a correct AST!");
|
||||||
System.out.println(scan.next());
|
else {
|
||||||
}
|
System.err.println(x.getName() + " parsed successfully but has an incorrect AST!");
|
||||||
}
|
failures++;
|
||||||
scan.close();
|
}
|
||||||
return ast;
|
} 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 {
|
||||||
|
ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath())
|
||||||
|
.directory(new File(System.getProperty("java.class.path")));
|
||||||
|
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) {
|
||||||
|
Scanner scan = new Scanner(stream);
|
||||||
|
String ast = null;
|
||||||
|
while (scan.hasNextLine()) {
|
||||||
|
String line = scan.nextLine();
|
||||||
|
if (line.equals("======= AST Display =========================")) {
|
||||||
|
line = scan.nextLine();
|
||||||
|
while (scan.hasNext() && !line.equals("=============================================")) {
|
||||||
|
ast += line + "\n";
|
||||||
|
line = scan.nextLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (line.startsWith("*** "))
|
||||||
|
System.out.println(line);
|
||||||
|
if (line.startsWith("ERROR")) {
|
||||||
|
System.out.println(line);
|
||||||
|
while (scan.hasNext())
|
||||||
|
System.out.println(scan.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scan.close();
|
||||||
|
return ast;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
@ -13,61 +12,58 @@ 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.");
|
|
||||||
}
|
|
||||||
|
|
||||||
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")));
|
|
||||||
pb.redirectErrorStream(true);
|
|
||||||
Process p = pb.start();
|
|
||||||
|
|
||||||
processStream(p.getInputStream());
|
public static void main(String[] args) throws IOException, InterruptedException {
|
||||||
p.waitFor();
|
File testDir = new File(System.getProperty("java.class.path") + "/../tests/pa3_tests");
|
||||||
int exitValue = p.exitValue();
|
int failures = 0;
|
||||||
return exitValue;
|
for (File x : testDir.listFiles()) {
|
||||||
}
|
if (x.getName().endsWith("out") || x.getName().startsWith(".") || x.getName().endsWith("mJAM")
|
||||||
|
|| x.getName().endsWith("asm"))
|
||||||
|
continue;
|
||||||
public static void processStream(InputStream stream) {
|
int returnCode = runTest(x);
|
||||||
Scanner scan = new Scanner(stream);
|
if (x.getName().indexOf("pass") != -1) {
|
||||||
while (scan.hasNextLine()) {
|
if (returnCode == 0) {
|
||||||
String line = scan.nextLine();
|
System.out.println(x.getName() + " processed successfully!");
|
||||||
if (line.startsWith("*** "))
|
} else {
|
||||||
System.out.println(line);
|
failures++;
|
||||||
if (line.startsWith("ERROR")) {
|
System.err.println(x.getName() + " failed to be processed!");
|
||||||
System.out.println(line);
|
}
|
||||||
//while(scan.hasNext())
|
} else {
|
||||||
//System.out.println(scan.next());
|
if (returnCode == 4)
|
||||||
}
|
System.out.println(x.getName() + " failed successfully!");
|
||||||
}
|
else {
|
||||||
scan.close();
|
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 {
|
||||||
|
ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath())
|
||||||
|
.directory(new File(System.getProperty("java.class.path")));
|
||||||
|
pb.redirectErrorStream(true);
|
||||||
|
Process p = pb.start();
|
||||||
|
|
||||||
|
processStream(p.getInputStream());
|
||||||
|
p.waitFor();
|
||||||
|
int exitValue = p.exitValue();
|
||||||
|
return exitValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void processStream(InputStream stream) {
|
||||||
|
Scanner scan = new Scanner(stream);
|
||||||
|
while (scan.hasNextLine()) {
|
||||||
|
String line = scan.nextLine();
|
||||||
|
if (line.startsWith("*** "))
|
||||||
|
System.out.println(line);
|
||||||
|
if (line.startsWith("ERROR")) {
|
||||||
|
System.out.println(line);
|
||||||
|
// while(scan.hasNext())
|
||||||
|
// System.out.println(scan.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scan.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
@ -13,100 +12,97 @@ 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.");
|
|
||||||
}
|
|
||||||
|
|
||||||
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")));
|
|
||||||
pb.redirectErrorStream(true);
|
|
||||||
Process p = pb.start();
|
|
||||||
|
|
||||||
processStream(p.getInputStream());
|
public static void main(String[] args) throws IOException, InterruptedException {
|
||||||
p.waitFor();
|
File testDir = new File(System.getProperty("java.class.path") + "/../tests/pa4_tests");
|
||||||
int exitValue = p.exitValue();
|
int failures = 0;
|
||||||
return exitValue;
|
for (File x : testDir.listFiles()) {
|
||||||
}
|
if (x.getName().startsWith(".") || x.getName().endsWith("mJAM") || x.getName().endsWith("asm"))
|
||||||
|
continue;
|
||||||
private static int executeTest(File x) throws IOException, InterruptedException {
|
int returnCode = runTest(x);
|
||||||
ProcessBuilder pb = new ProcessBuilder("java", "mJAM.Interpreter", x.getPath().replace(".java", ".mJAM")).directory(new File(System.getProperty("java.class.path")));
|
if (x.getName().indexOf("pass") != -1) {
|
||||||
Process process = pb.start();
|
if (returnCode == 0) {
|
||||||
|
try {
|
||||||
Scanner scan = new Scanner(process.getInputStream());
|
int val = executeTest(x);
|
||||||
int num = -1;
|
int expected = Integer.parseInt(x.getName().substring(5, 7));
|
||||||
while (scan.hasNextLine()) {
|
if (val == expected)
|
||||||
String line = scan.nextLine();
|
System.out.println(x.getName() + " ran successfully!");
|
||||||
if (line.startsWith(">>> ")) {
|
else {
|
||||||
num = Integer.parseInt(line.substring(4));
|
failures++;
|
||||||
System.out.println("Result = " + num);
|
System.err
|
||||||
break;
|
.println(x.getName() + " compiled but did not run successfully--got output " + val);
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception ex) {
|
||||||
while (scan.hasNextLine()) {
|
failures++;
|
||||||
String line = scan.nextLine();
|
System.err.println(x.getName() + " did not output correctly.");
|
||||||
if (line.startsWith("*** ")) {
|
}
|
||||||
System.out.println(line);
|
} else {
|
||||||
break;
|
failures++;
|
||||||
}
|
System.err.println(x.getName() + " failed to be processed!");
|
||||||
}
|
}
|
||||||
scan.close();
|
} else {
|
||||||
|
if (returnCode == 4)
|
||||||
return num;
|
System.out.println(x.getName() + " failed successfully!");
|
||||||
}
|
else {
|
||||||
|
System.err.println(x.getName() + " did not fail properly!");
|
||||||
|
failures++;
|
||||||
public static void processStream(InputStream stream) {
|
}
|
||||||
Scanner scan = new Scanner(stream);
|
}
|
||||||
while (scan.hasNextLine()) {
|
}
|
||||||
String line = scan.nextLine();
|
System.out.println(failures + " failures in all.");
|
||||||
if (line.startsWith("*** "))
|
}
|
||||||
System.out.println(line);
|
|
||||||
if (line.startsWith("ERROR")) {
|
private static int runTest(File x) throws IOException, InterruptedException {
|
||||||
System.out.println(line);
|
ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath())
|
||||||
//while(scan.hasNext())
|
.directory(new File(System.getProperty("java.class.path")));
|
||||||
//System.out.println(scan.next());
|
pb.redirectErrorStream(true);
|
||||||
}
|
Process p = pb.start();
|
||||||
}
|
|
||||||
scan.close();
|
processStream(p.getInputStream());
|
||||||
}
|
p.waitFor();
|
||||||
|
int exitValue = p.exitValue();
|
||||||
|
return exitValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int executeTest(File x) throws IOException, InterruptedException {
|
||||||
|
ProcessBuilder pb = new ProcessBuilder("java", "mJAM.Interpreter", x.getPath().replace(".java", ".mJAM"))
|
||||||
|
.directory(new File(System.getProperty("java.class.path")));
|
||||||
|
Process process = pb.start();
|
||||||
|
|
||||||
|
Scanner scan = new Scanner(process.getInputStream());
|
||||||
|
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();
|
||||||
|
if (line.startsWith("*** "))
|
||||||
|
System.out.println(line);
|
||||||
|
if (line.startsWith("ERROR")) {
|
||||||
|
System.out.println(line);
|
||||||
|
// while(scan.hasNext())
|
||||||
|
// System.out.println(scan.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scan.close();
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue