diff --git a/Triangle.AbstractMachine.Disassembler/src/main/java/Triangle/AbstractMachine/Disassembler.java b/Triangle.AbstractMachine.Disassembler/src/main/java/Triangle/AbstractMachine/Disassembler.java index 8bda415..aa71b4c 100644 --- a/Triangle.AbstractMachine.Disassembler/src/main/java/Triangle/AbstractMachine/Disassembler.java +++ b/Triangle.AbstractMachine.Disassembler/src/main/java/Triangle/AbstractMachine/Disassembler.java @@ -20,8 +20,8 @@ import java.io.FileNotFoundException; import java.io.IOException; /** - * Disassembles the TAM code in the given file, and displays the - * instructions on standard output. + * Disassembles the TAM code in the given file, and displays the instructions on + * standard output. * * For example: * @@ -38,361 +38,361 @@ import java.io.IOException; public class Disassembler { - static String objectName; - - static int CT; - - /** - * Writes the r-field of an instruction in the form "lregr", where - * l 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 rightbracket the character to print after the register. - */ - private static void writeR(char leftbracket, int r, char rightbracket) { - - System.out.print(leftbracket); - switch (r) { - case Machine.CBr: - System.out.print("CB"); - break; - case Machine.CTr: - System.out.print("CT"); - break; - case Machine.PBr: - System.out.print("PB"); - break; - case Machine.PTr: - System.out.print("PT"); - break; - case Machine.SBr: - System.out.print("SB"); - break; - case Machine.STr: - System.out.print("ST"); - break; - case Machine.HBr: - System.out.print("HB"); - break; - case Machine.HTr: - System.out.print("HT"); - break; - case Machine.LBr: - System.out.print("LB"); - break; - case Machine.L1r: - System.out.print("L1"); - break; - case Machine.L2r: - System.out.print("L2"); - break; - case Machine.L3r: - System.out.print("L3"); - break; - case Machine.L4r: - System.out.print("L4"); - break; - case Machine.L5r: - System.out.print("L5"); - break; - case Machine.L6r: - System.out.print("L6"); - break; - case Machine.CPr: - System.out.print("CP"); - break; - } - System.out.print(rightbracket); - } - - /** - * Writes a void n-field of an instruction. - */ - private static void blankN() { - System.out.print(" "); - } - - // Writes the n-field of an instruction. - /** - * Writes the n-field of an instruction in the form "(n)". - * - * @param n the integer to write. - */ - private static void writeN(int n) { - System.out.print("(" + n + ") "); - if (n < 10) - System.out.print(" "); - else if (n < 100) - System.out.print(" "); - } - - /** - * Writes the d-field of an instruction. - * - * @param d the integer to write. - */ - private static void writeD(int d) { - System.out.print(d); - } - - /** - * Writes the name of primitive routine with relative address d. - * - * @param d the displacment of the primitive routine. - */ - private static void writePrimitive(int d) { - switch (d) { - case Machine.idDisplacement: - System.out.print("id "); - break; - case Machine.notDisplacement: - System.out.print("not "); - break; - case Machine.andDisplacement: - System.out.print("and "); - break; - case Machine.orDisplacement: - System.out.print("or "); - break; - case Machine.succDisplacement: - System.out.print("succ "); - break; - case Machine.predDisplacement: - System.out.print("pred "); - break; - case Machine.negDisplacement: - System.out.print("neg "); - break; - case Machine.addDisplacement: - System.out.print("add "); - break; - case Machine.subDisplacement: - System.out.print("sub "); - break; - case Machine.multDisplacement: - System.out.print("mult "); - break; - case Machine.divDisplacement: - System.out.print("div "); - break; - case Machine.modDisplacement: - System.out.print("mod "); - break; - case Machine.ltDisplacement: - System.out.print("lt "); - break; - case Machine.leDisplacement: - System.out.print("le "); - break; - case Machine.geDisplacement: - System.out.print("ge "); - break; - case Machine.gtDisplacement: - System.out.print("gt "); - break; - case Machine.eqDisplacement: - System.out.print("eq "); - break; - case Machine.neDisplacement: - System.out.print("ne "); - break; - case Machine.eolDisplacement: - System.out.print("eol "); - break; - case Machine.eofDisplacement: - System.out.print("eof "); - break; - case Machine.getDisplacement: - System.out.print("get "); - break; - case Machine.putDisplacement: - System.out.print("put "); - break; - case Machine.geteolDisplacement: - System.out.print("geteol "); - break; - case Machine.puteolDisplacement: - System.out.print("puteol "); - break; - case Machine.getintDisplacement: - System.out.print("getint "); - break; - case Machine.putintDisplacement: - System.out.print("putint "); - break; - case Machine.newDisplacement: - System.out.print("new "); - break; - case Machine.disposeDisplacement: - System.out.print("dispose "); - break; - } - } - - /** - * Writes the given instruction in assembly-code format. - * - * @param instr the instruction to display. - */ - private static void writeInstruction(Instruction instr) { - - switch (instr.op) { - case Machine.LOADop: - System.out.print("LOAD "); - writeN(instr.n); - writeD(instr.d); - writeR('[', instr.r, ']'); - break; - - case Machine.LOADAop: - System.out.print("LOADA "); - blankN(); - writeD(instr.d); - writeR('[', instr.r, ']'); - break; - - case Machine.LOADIop: - System.out.print("LOADI "); - writeN(instr.n); - break; - - case Machine.LOADLop: - System.out.print("LOADL "); - blankN(); - writeD(instr.d); - break; - - case Machine.STOREop: - System.out.print("STORE "); - writeN(instr.n); - writeD(instr.d); - writeR('[', instr.r, ']'); - break; - - case Machine.STOREIop: - System.out.print("STOREI"); - writeN(instr.n); - break; - - case Machine.CALLop: - System.out.print("CALL "); - if (instr.r == Machine.PBr) { - blankN(); - writePrimitive(instr.d); - } else { - writeR('(', instr.n, ')'); - System.out.print(" "); - writeD(instr.d); - writeR('[', instr.r, ']'); - } - break; - - case Machine.CALLIop: - System.out.print("CALLI "); - break; - - case Machine.RETURNop: - System.out.print("RETURN"); - writeN(instr.n); - writeD(instr.d); - break; - - case Machine.PUSHop: - System.out.print("PUSH "); - blankN(); - writeD(instr.d); - break; - - case Machine.POPop: - System.out.print("POP "); - writeN(instr.n); - writeD(instr.d); - break; - - case Machine.JUMPop: - System.out.print("JUMP "); - blankN(); - writeD(instr.d); - writeR('[', instr.r, ']'); - break; - - case Machine.JUMPIop: - System.out.print("JUMPI "); - break; - - case Machine.JUMPIFop: - System.out.print("JUMPIF"); - writeN(instr.n); - writeD(instr.d); - writeR('[', instr.r, ']'); - break; - - case Machine.HALTop: - System.out.print("HALT "); - } - } - - /** - * Writes all instructions of the program in code store. - */ - private static void disassembleProgram() { - for (int addr = Machine.CB; addr < CT; addr++) { - System.out.print(addr + ": "); - writeInstruction(Machine.code[addr]); - System.out.println(); - } - } - - // LOADING - - /** - * Loads the TAM object program into code store from the named file. - * - * @param objectName the name of the file containing the program. - */ - static void loadObjectProgram(String objectName) { - - FileInputStream objectFile = null; - DataInputStream objectStream = null; - - int addr; - boolean finished = false; - - try { - objectFile = new FileInputStream(objectName); - objectStream = new DataInputStream(objectFile); - - addr = Machine.CB; - while (!finished) { - Machine.code[addr] = Instruction.read(objectStream); - if (Machine.code[addr] == null) - finished = true; - else - addr = addr + 1; - } - CT = addr; - objectFile.close(); - } catch (FileNotFoundException s) { - CT = Machine.CB; - System.err.println("Error opening object file: " + s); - } catch (IOException s) { - CT = Machine.CB; - System.err.println("Error reading object file: " + s); - } - } - - // DISASSEMBLE - - public static void main(String[] args) { - System.out.println("********** TAM Disassembler (Sun Version 2.1) **********"); - - if (args.length == 1) - objectName = args[0]; - else - objectName = "obj.tam"; - - loadObjectProgram(objectName); - disassembleProgram(); - } + static String objectName; + + static int CT; + + /** + * Writes the r-field of an instruction in the form "lregr", where l 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 rightbracket the character to print after the register. + */ + private static void writeR(char leftbracket, int r, char rightbracket) { + + System.out.print(leftbracket); + switch (r) { + case Machine.CBr: + System.out.print("CB"); + break; + case Machine.CTr: + System.out.print("CT"); + break; + case Machine.PBr: + System.out.print("PB"); + break; + case Machine.PTr: + System.out.print("PT"); + break; + case Machine.SBr: + System.out.print("SB"); + break; + case Machine.STr: + System.out.print("ST"); + break; + case Machine.HBr: + System.out.print("HB"); + break; + case Machine.HTr: + System.out.print("HT"); + break; + case Machine.LBr: + System.out.print("LB"); + break; + case Machine.L1r: + System.out.print("L1"); + break; + case Machine.L2r: + System.out.print("L2"); + break; + case Machine.L3r: + System.out.print("L3"); + break; + case Machine.L4r: + System.out.print("L4"); + break; + case Machine.L5r: + System.out.print("L5"); + break; + case Machine.L6r: + System.out.print("L6"); + break; + case Machine.CPr: + System.out.print("CP"); + break; + } + System.out.print(rightbracket); + } + + /** + * Writes a void n-field of an instruction. + */ + private static void blankN() { + System.out.print(" "); + } + + // Writes the n-field of an instruction. + /** + * Writes the n-field of an instruction in the form "(n)". + * + * @param n the integer to write. + */ + private static void writeN(int n) { + System.out.print("(" + n + ") "); + if (n < 10) + System.out.print(" "); + else if (n < 100) + System.out.print(" "); + } + + /** + * Writes the d-field of an instruction. + * + * @param d the integer to write. + */ + private static void writeD(int d) { + System.out.print(d); + } + + /** + * Writes the name of primitive routine with relative address d. + * + * @param d the displacment of the primitive routine. + */ + private static void writePrimitive(int d) { + switch (d) { + case Machine.idDisplacement: + System.out.print("id "); + break; + case Machine.notDisplacement: + System.out.print("not "); + break; + case Machine.andDisplacement: + System.out.print("and "); + break; + case Machine.orDisplacement: + System.out.print("or "); + break; + case Machine.succDisplacement: + System.out.print("succ "); + break; + case Machine.predDisplacement: + System.out.print("pred "); + break; + case Machine.negDisplacement: + System.out.print("neg "); + break; + case Machine.addDisplacement: + System.out.print("add "); + break; + case Machine.subDisplacement: + System.out.print("sub "); + break; + case Machine.multDisplacement: + System.out.print("mult "); + break; + case Machine.divDisplacement: + System.out.print("div "); + break; + case Machine.modDisplacement: + System.out.print("mod "); + break; + case Machine.ltDisplacement: + System.out.print("lt "); + break; + case Machine.leDisplacement: + System.out.print("le "); + break; + case Machine.geDisplacement: + System.out.print("ge "); + break; + case Machine.gtDisplacement: + System.out.print("gt "); + break; + case Machine.eqDisplacement: + System.out.print("eq "); + break; + case Machine.neDisplacement: + System.out.print("ne "); + break; + case Machine.eolDisplacement: + System.out.print("eol "); + break; + case Machine.eofDisplacement: + System.out.print("eof "); + break; + case Machine.getDisplacement: + System.out.print("get "); + break; + case Machine.putDisplacement: + System.out.print("put "); + break; + case Machine.geteolDisplacement: + System.out.print("geteol "); + break; + case Machine.puteolDisplacement: + System.out.print("puteol "); + break; + case Machine.getintDisplacement: + System.out.print("getint "); + break; + case Machine.putintDisplacement: + System.out.print("putint "); + break; + case Machine.newDisplacement: + System.out.print("new "); + break; + case Machine.disposeDisplacement: + System.out.print("dispose "); + break; + } + } + + /** + * Writes the given instruction in assembly-code format. + * + * @param instr the instruction to display. + */ + private static void writeInstruction(Instruction instr) { + + switch (instr.op) { + case Machine.LOADop: + System.out.print("LOAD "); + writeN(instr.n); + writeD(instr.d); + writeR('[', instr.r, ']'); + break; + + case Machine.LOADAop: + System.out.print("LOADA "); + blankN(); + writeD(instr.d); + writeR('[', instr.r, ']'); + break; + + case Machine.LOADIop: + System.out.print("LOADI "); + writeN(instr.n); + break; + + case Machine.LOADLop: + System.out.print("LOADL "); + blankN(); + writeD(instr.d); + break; + + case Machine.STOREop: + System.out.print("STORE "); + writeN(instr.n); + writeD(instr.d); + writeR('[', instr.r, ']'); + break; + + case Machine.STOREIop: + System.out.print("STOREI"); + writeN(instr.n); + break; + + case Machine.CALLop: + System.out.print("CALL "); + if (instr.r == Machine.PBr) { + blankN(); + writePrimitive(instr.d); + } else { + writeR('(', instr.n, ')'); + System.out.print(" "); + writeD(instr.d); + writeR('[', instr.r, ']'); + } + break; + + case Machine.CALLIop: + System.out.print("CALLI "); + break; + + case Machine.RETURNop: + System.out.print("RETURN"); + writeN(instr.n); + writeD(instr.d); + break; + + case Machine.PUSHop: + System.out.print("PUSH "); + blankN(); + writeD(instr.d); + break; + + case Machine.POPop: + System.out.print("POP "); + writeN(instr.n); + writeD(instr.d); + break; + + case Machine.JUMPop: + System.out.print("JUMP "); + blankN(); + writeD(instr.d); + writeR('[', instr.r, ']'); + break; + + case Machine.JUMPIop: + System.out.print("JUMPI "); + break; + + case Machine.JUMPIFop: + System.out.print("JUMPIF"); + writeN(instr.n); + writeD(instr.d); + writeR('[', instr.r, ']'); + break; + + case Machine.HALTop: + System.out.print("HALT "); + } + } + + /** + * Writes all instructions of the program in code store. + */ + private static void disassembleProgram() { + for (int addr = Machine.CB; addr < CT; addr++) { + System.out.print(addr + ": "); + writeInstruction(Machine.code[addr]); + System.out.println(); + } + } + + // LOADING + + /** + * Loads the TAM object program into code store from the named file. + * + * @param objectName the name of the file containing the program. + */ + static void loadObjectProgram(String objectName) { + + FileInputStream objectFile = null; + DataInputStream objectStream = null; + + int addr; + boolean finished = false; + + try { + objectFile = new FileInputStream(objectName); + objectStream = new DataInputStream(objectFile); + + addr = Machine.CB; + while (!finished) { + Machine.code[addr] = Instruction.read(objectStream); + if (Machine.code[addr] == null) + finished = true; + else + addr = addr + 1; + } + CT = addr; + objectFile.close(); + } catch (FileNotFoundException s) { + CT = Machine.CB; + System.err.println("Error opening object file: " + s); + } catch (IOException s) { + CT = Machine.CB; + System.err.println("Error reading object file: " + s); + } + } + + // DISASSEMBLE + + public static void main(String[] args) { + System.out.println("********** TAM Disassembler (Sun Version 2.1) **********"); + + if (args.length == 1) + objectName = args[0]; + else + objectName = "obj.tam"; + + loadObjectProgram(objectName); + disassembleProgram(); + } } diff --git a/Triangle.AbstractMachine.Interpreter/src/main/java/Triangle/AbstractMachine/Interpreter.java b/Triangle.AbstractMachine.Interpreter/src/main/java/Triangle/AbstractMachine/Interpreter.java index 92fb721..3c1b610 100644 --- a/Triangle.AbstractMachine.Interpreter/src/main/java/Triangle/AbstractMachine/Interpreter.java +++ b/Triangle.AbstractMachine.Interpreter/src/main/java/Triangle/AbstractMachine/Interpreter.java @@ -21,600 +21,596 @@ import java.io.IOException; public class Interpreter { - static String objectName; - - // DATA STORE - - static int[] data = new int[1024]; - - // DATA STORE REGISTERS AND OTHER REGISTERS - - final static int CB = 0, - SB = 0, - HB = 1024; // = upper bound of data array + 1 - - static int CT, CP, ST, HT, LB, status; - - // status values - final static int running = 0, halted = 1, failedDataStoreFull = 2, failedInvalidCodeAddress = 3, - failedInvalidInstruction = 4, failedOverflow = 5, failedZeroDivide = 6, - failedIOError = 7; - - static long accumulator; - - static int content(int r) { - // Returns the current content of register r, - // even if r is one of the pseudo-registers L1..L6. - - switch (r) { - case Machine.CBr: - return CB; - case Machine.CTr: - return CT; - case Machine.PBr: - return Machine.PB; - case Machine.PTr: - return Machine.PT; - case Machine.SBr: - return SB; - case Machine.STr: - return ST; - case Machine.HBr: - return HB; - case Machine.HTr: - return HT; - case Machine.LBr: - return LB; - case Machine.L1r: - return data[LB]; - case Machine.L2r: - return data[data[LB]]; - case Machine.L3r: - return data[data[data[LB]]]; - case Machine.L4r: - return data[data[data[data[LB]]]]; - case Machine.L5r: - return data[data[data[data[data[LB]]]]]; - case Machine.L6r: - return data[data[data[data[data[data[LB]]]]]]; - case Machine.CPr: - return CP; - default: - return 0; - } - } - - // PROGRAM STATUS - - static void dump() { - // Writes a summary of the machine state. - int addr, staticLink, dynamicLink, - localRegNum; - - System.out.println(""); - System.out.println("State of data store and registers:"); - System.out.println(""); - if (HT == HB) - System.out.println(" |--------| (heap is empty)"); - else { - System.out.println(" HB-->"); - System.out.println(" |--------|"); - for (addr = HB - 1; addr >= HT; addr--) { - System.out.print(addr + ":"); - if (addr == HT) - System.out.print(" HT-->"); - else - System.out.print(" "); - System.out.println("|" + data[addr] + "|"); - } - System.out.println(" |--------|"); - } - System.out.println(" |////////|"); - System.out.println(" |////////|"); - if (ST == SB) - System.out.println(" |--------| (stack is empty)"); - else { - dynamicLink = LB; - staticLink = LB; - localRegNum = Machine.LBr; - System.out.println(" ST--> |////////|"); - System.out.println(" |--------|"); - for (addr = ST - 1; addr >= SB; addr--) { - System.out.print(addr + ":"); - if (addr == SB) - System.out.print(" SB-->"); - else if (addr == staticLink) { - switch (localRegNum) { - case Machine.LBr: - System.out.print(" LB-->"); - break; - case Machine.L1r: - System.out.print(" L1-->"); - break; - case Machine.L2r: - System.out.print(" L2-->"); - break; - case Machine.L3r: - System.out.print(" L3-->"); - break; - case Machine.L4r: - System.out.print(" L4-->"); - break; - case Machine.L5r: - System.out.print(" L5-->"); - break; - case Machine.L6r: - System.out.print(" L6-->"); - break; - } - staticLink = data[addr]; - localRegNum = localRegNum + 1; - } else - System.out.print(" "); - if ((addr == dynamicLink) && (dynamicLink != SB)) - System.out.print("|SL=" + data[addr] + "|"); - else if ((addr == dynamicLink + 1) && (dynamicLink != SB)) - System.out.print("|DL=" + data[addr] + "|"); - else if ((addr == dynamicLink + 2) && (dynamicLink != SB)) - System.out.print("|RA=" + data[addr] + "|"); - else - System.out.print("|" + data[addr] + "|"); - System.out.println(""); - if (addr == dynamicLink) { - System.out.println(" |--------|"); - dynamicLink = data[addr + 1]; - } - } - } - System.out.println(""); - } - - static void showStatus() { - // Writes an indication of whether and why the program has terminated. - System.out.println(""); - switch (status) { - case running: - System.out.println("Program is running."); - break; - case halted: - System.out.println("Program has halted normally."); - break; - case failedDataStoreFull: - System.out.println("Program has failed due to exhaustion of Data Store."); - break; - case failedInvalidCodeAddress: - System.out.println("Program has failed due to an invalid code address."); - break; - case failedInvalidInstruction: - System.out.println("Program has failed due to an invalid instruction."); - break; - case failedOverflow: - System.out.println("Program has failed due to overflow."); - break; - case failedZeroDivide: - System.out.println("Program has failed due to division by zero."); - break; - case failedIOError: - System.out.println("Program has failed due to an IO error."); - break; - } - if (status != halted) - dump(); - } - - // INTERPRETATION - - static void checkSpace(int spaceNeeded) { - // Signals failure if there is not enough space to expand the stack or - // heap by spaceNeeded. - - if (HT - ST < spaceNeeded) - status = failedDataStoreFull; - } - - static boolean isTrue(int datum) { - // Tests whether the given datum represents true. - return (datum == Machine.trueRep); - } - - static boolean equal(int size, int addr1, int addr2) { - // Tests whether two multi-word objects are equal, given their common - // size and their base addresses. - - boolean eq; - int index; - - eq = true; - index = 0; - while (eq && (index < size)) - if (data[addr1 + index] == data[addr2 + index]) - index = index + 1; - else - eq = false; - return eq; - } - - static int overflowChecked(long datum) { - // Signals failure if the datum is too large to fit into a single word, - // otherwise returns the datum as a single word. - - if ((-Machine.maxintRep <= datum) && (datum <= Machine.maxintRep)) - return (int) datum; - else { - status = failedOverflow; - return 0; - } - } - - static int toInt(boolean b) { - return b ? Machine.trueRep : Machine.falseRep; - } - - static int currentChar; - - static int readInt() throws java.io.IOException { - int temp = 0; - int sign = 1; - - do { - currentChar = System.in.read(); - } while (Character.isWhitespace((char) currentChar)); - - if ((currentChar == '-') || (currentChar == '+')) - do { - sign = (currentChar == '-') ? -1 : 1; - currentChar = System.in.read(); - } while ((currentChar == '-') || currentChar == '+'); - - if (Character.isDigit((char) currentChar)) - do { - temp = temp * 10 + (currentChar - '0'); - currentChar = System.in.read(); - } while (Character.isDigit((char) currentChar)); - - return sign * temp; - } - - static void callPrimitive(int primitiveDisplacement) { - // Invokes the given primitive routine. - - int addr, size; - char ch; - - switch (primitiveDisplacement) { - case Machine.idDisplacement: - break; // nothing to be done - case Machine.notDisplacement: - data[ST - 1] = toInt(!isTrue(data[ST - 1])); - break; - case Machine.andDisplacement: - ST = ST - 1; - data[ST - 1] = toInt(isTrue(data[ST - 1]) & isTrue(data[ST])); - break; - case Machine.orDisplacement: - ST = ST - 1; - data[ST - 1] = toInt(isTrue(data[ST - 1]) | isTrue(data[ST])); - break; - case Machine.succDisplacement: - data[ST - 1] = overflowChecked(data[ST - 1] + 1); - break; - case Machine.predDisplacement: - data[ST - 1] = overflowChecked(data[ST - 1] - 1); - break; - case Machine.negDisplacement: - data[ST - 1] = -data[ST - 1]; - break; - case Machine.addDisplacement: - ST = ST - 1; - accumulator = data[ST - 1]; - data[ST - 1] = overflowChecked(accumulator + data[ST]); - break; - case Machine.subDisplacement: - ST = ST - 1; - accumulator = data[ST - 1]; - data[ST - 1] = overflowChecked(accumulator - data[ST]); - break; - case Machine.multDisplacement: - ST = ST - 1; - accumulator = data[ST - 1]; - data[ST - 1] = overflowChecked(accumulator * data[ST]); - break; - case Machine.divDisplacement: - ST = ST - 1; - accumulator = data[ST - 1]; - if (data[ST] != 0) - data[ST - 1] = (int) (accumulator / data[ST]); - else - status = failedZeroDivide; - break; - case Machine.modDisplacement: - ST = ST - 1; - accumulator = data[ST - 1]; - if (data[ST] != 0) - data[ST - 1] = (int) (accumulator % data[ST]); - else - status = failedZeroDivide; - break; - case Machine.ltDisplacement: - ST = ST - 1; - data[ST - 1] = toInt(data[ST - 1] < data[ST]); - break; - case Machine.leDisplacement: - ST = ST - 1; - data[ST - 1] = toInt(data[ST - 1] <= data[ST]); - break; - case Machine.geDisplacement: - ST = ST - 1; - data[ST - 1] = toInt(data[ST - 1] >= data[ST]); - break; - case Machine.gtDisplacement: - ST = ST - 1; - data[ST - 1] = toInt(data[ST - 1] > data[ST]); - break; - case Machine.eqDisplacement: - size = data[ST - 1]; // size of each comparand - ST = ST - 2 * size; - data[ST - 1] = toInt(equal(size, ST - 1, ST - 1 + size)); - break; - case Machine.neDisplacement: - size = data[ST - 1]; // size of each comparand - ST = ST - 2 * size; - data[ST - 1] = toInt(!equal(size, ST - 1, ST - 1 + size)); - break; - case Machine.eolDisplacement: - data[ST] = toInt(currentChar == '\n'); - ST = ST + 1; - break; - case Machine.eofDisplacement: - data[ST] = toInt(currentChar == -1); - ST = ST + 1; - break; - case Machine.getDisplacement: - ST = ST - 1; - addr = data[ST]; - try { - currentChar = System.in.read(); - } catch (java.io.IOException s) { - status = failedIOError; - } - data[addr] = currentChar; - break; - case Machine.putDisplacement: - ST = ST - 1; - ch = (char) data[ST]; - System.out.print(ch); - break; - case Machine.geteolDisplacement: - try { - while ((currentChar = System.in.read()) != '\n') - ; - } catch (java.io.IOException s) { - status = failedIOError; - } - break; - case Machine.puteolDisplacement: - System.out.println(""); - break; - case Machine.getintDisplacement: - ST = ST - 1; - addr = data[ST]; - try { - accumulator = readInt(); - } catch (java.io.IOException s) { - status = failedIOError; - } - data[addr] = (int) accumulator; - break; - case Machine.putintDisplacement: - ST = ST - 1; - accumulator = data[ST]; - System.out.print(accumulator); - break; - case Machine.newDisplacement: - size = data[ST - 1]; - checkSpace(size); - HT = HT - size; - data[ST - 1] = HT; - break; - case Machine.disposeDisplacement: - ST = ST - 1; // no action taken at present - break; - } - } - - static void interpretProgram() { - // Runs the program in code store. - - Instruction currentInstr; - int op, r, n, d, addr, index; - - // Initialize registers ... - ST = SB; - HT = HB; - LB = SB; - CP = CB; - status = running; - do { - // Fetch instruction ... - currentInstr = Machine.code[CP]; - // Decode instruction ... - op = currentInstr.op; - r = currentInstr.r; - n = currentInstr.n; - d = currentInstr.d; - // Execute instruction ... - switch (op) { - case Machine.LOADop: - addr = d + content(r); - checkSpace(n); - for (index = 0; index < n; index++) - data[ST + index] = data[addr + index]; - ST = ST + n; - CP = CP + 1; - break; - case Machine.LOADAop: - addr = d + content(r); - checkSpace(1); - data[ST] = addr; - ST = ST + 1; - CP = CP + 1; - break; - case Machine.LOADIop: - ST = ST - 1; - addr = data[ST]; - checkSpace(n); - for (index = 0; index < n; index++) - data[ST + index] = data[addr + index]; - ST = ST + n; - CP = CP + 1; - break; - case Machine.LOADLop: - checkSpace(1); - data[ST] = d; - ST = ST + 1; - CP = CP + 1; - break; - case Machine.STOREop: - addr = d + content(r); - ST = ST - n; - for (index = 0; index < n; index++) - data[addr + index] = data[ST + index]; - CP = CP + 1; - break; - case Machine.STOREIop: - ST = ST - 1; - addr = data[ST]; - ST = ST - n; - for (index = 0; index < n; index++) - data[addr + index] = data[ST + index]; - CP = CP + 1; - break; - case Machine.CALLop: - addr = d + content(r); - if (addr >= Machine.PB) { - callPrimitive(addr - Machine.PB); - CP = CP + 1; - } else { - checkSpace(3); - if ((0 <= n) && (n <= 15)) - data[ST] = content(n); // static link - else - status = failedInvalidInstruction; - data[ST + 1] = LB; // dynamic link - data[ST + 2] = CP + 1; // return address - LB = ST; - ST = ST + 3; - CP = addr; - } - break; - case Machine.CALLIop: - ST = ST - 2; - addr = data[ST + 1]; - if (addr >= Machine.PB) { - callPrimitive(addr - Machine.PB); - CP = CP + 1; - } else { - // data[ST] = static link already - data[ST + 1] = LB; // dynamic link - data[ST + 2] = CP + 1; // return address - LB = ST; - ST = ST + 3; - CP = addr; - } - break; - case Machine.RETURNop: - addr = LB - d; - CP = data[LB + 2]; - LB = data[LB + 1]; - ST = ST - n; - for (index = 0; index < n; index++) - data[addr + index] = data[ST + index]; - ST = addr + n; - break; - case Machine.PUSHop: - checkSpace(d); - ST = ST + d; - CP = CP + 1; - break; - case Machine.POPop: - addr = ST - n - d; - ST = ST - n; - for (index = 0; index < n; index++) - data[addr + index] = data[ST + index]; - ST = addr + n; - CP = CP + 1; - break; - case Machine.JUMPop: - CP = d + content(r); - break; - case Machine.JUMPIop: - ST = ST - 1; - CP = data[ST]; - break; - case Machine.JUMPIFop: - ST = ST - 1; - if (data[ST] == n) - CP = d + content(r); - else - CP = CP + 1; - break; - case Machine.HALTop: - status = halted; - break; - } - if ((CP < CB) || (CP >= CT)) - status = failedInvalidCodeAddress; - } while (status == running); - } - - // LOADING - - static void loadObjectProgram(String objectName) { - // Loads the TAM object program into code store from the named file. - - FileInputStream objectFile = null; - DataInputStream objectStream = null; - - int addr; - boolean finished = false; - - try { - objectFile = new FileInputStream(objectName); - objectStream = new DataInputStream(objectFile); - - addr = Machine.CB; - while (!finished) { - Machine.code[addr] = Instruction.read(objectStream); - if (Machine.code[addr] == null) - finished = true; - else - addr = addr + 1; - } - CT = addr; - objectFile.close(); - } catch (FileNotFoundException s) { - CT = CB; - System.err.println("Error opening object file: " + s); - } catch (IOException s) { - CT = CB; - System.err.println("Error reading object file: " + s); - } - } - - // RUNNING - - public static void main(String[] args) { - System.out.println("********** TAM Interpreter (Java Version 2.1) **********"); - - if (args.length == 1) - objectName = args[0]; - else - objectName = "obj.tam"; - - loadObjectProgram(objectName); - if (CT != CB) { - interpretProgram(); - showStatus(); - } - } + static String objectName; + + // DATA STORE + + static int[] data = new int[1024]; + + // DATA STORE REGISTERS AND OTHER REGISTERS + + final static int CB = 0, SB = 0, HB = 1024; // = upper bound of data array + 1 + + static int CT, CP, ST, HT, LB, status; + + // status values + final static int running = 0, halted = 1, failedDataStoreFull = 2, failedInvalidCodeAddress = 3, + failedInvalidInstruction = 4, failedOverflow = 5, failedZeroDivide = 6, failedIOError = 7; + + static long accumulator; + + static int content(int r) { + // Returns the current content of register r, + // even if r is one of the pseudo-registers L1..L6. + + switch (r) { + case Machine.CBr: + return CB; + case Machine.CTr: + return CT; + case Machine.PBr: + return Machine.PB; + case Machine.PTr: + return Machine.PT; + case Machine.SBr: + return SB; + case Machine.STr: + return ST; + case Machine.HBr: + return HB; + case Machine.HTr: + return HT; + case Machine.LBr: + return LB; + case Machine.L1r: + return data[LB]; + case Machine.L2r: + return data[data[LB]]; + case Machine.L3r: + return data[data[data[LB]]]; + case Machine.L4r: + return data[data[data[data[LB]]]]; + case Machine.L5r: + return data[data[data[data[data[LB]]]]]; + case Machine.L6r: + return data[data[data[data[data[data[LB]]]]]]; + case Machine.CPr: + return CP; + default: + return 0; + } + } + + // PROGRAM STATUS + + static void dump() { + // Writes a summary of the machine state. + int addr, staticLink, dynamicLink, localRegNum; + + System.out.println(""); + System.out.println("State of data store and registers:"); + System.out.println(""); + if (HT == HB) + System.out.println(" |--------| (heap is empty)"); + else { + System.out.println(" HB-->"); + System.out.println(" |--------|"); + for (addr = HB - 1; addr >= HT; addr--) { + System.out.print(addr + ":"); + if (addr == HT) + System.out.print(" HT-->"); + else + System.out.print(" "); + System.out.println("|" + data[addr] + "|"); + } + System.out.println(" |--------|"); + } + System.out.println(" |////////|"); + System.out.println(" |////////|"); + if (ST == SB) + System.out.println(" |--------| (stack is empty)"); + else { + dynamicLink = LB; + staticLink = LB; + localRegNum = Machine.LBr; + System.out.println(" ST--> |////////|"); + System.out.println(" |--------|"); + for (addr = ST - 1; addr >= SB; addr--) { + System.out.print(addr + ":"); + if (addr == SB) + System.out.print(" SB-->"); + else if (addr == staticLink) { + switch (localRegNum) { + case Machine.LBr: + System.out.print(" LB-->"); + break; + case Machine.L1r: + System.out.print(" L1-->"); + break; + case Machine.L2r: + System.out.print(" L2-->"); + break; + case Machine.L3r: + System.out.print(" L3-->"); + break; + case Machine.L4r: + System.out.print(" L4-->"); + break; + case Machine.L5r: + System.out.print(" L5-->"); + break; + case Machine.L6r: + System.out.print(" L6-->"); + break; + } + staticLink = data[addr]; + localRegNum = localRegNum + 1; + } else + System.out.print(" "); + if ((addr == dynamicLink) && (dynamicLink != SB)) + System.out.print("|SL=" + data[addr] + "|"); + else if ((addr == dynamicLink + 1) && (dynamicLink != SB)) + System.out.print("|DL=" + data[addr] + "|"); + else if ((addr == dynamicLink + 2) && (dynamicLink != SB)) + System.out.print("|RA=" + data[addr] + "|"); + else + System.out.print("|" + data[addr] + "|"); + System.out.println(""); + if (addr == dynamicLink) { + System.out.println(" |--------|"); + dynamicLink = data[addr + 1]; + } + } + } + System.out.println(""); + } + + static void showStatus() { + // Writes an indication of whether and why the program has terminated. + System.out.println(""); + switch (status) { + case running: + System.out.println("Program is running."); + break; + case halted: + System.out.println("Program has halted normally."); + break; + case failedDataStoreFull: + System.out.println("Program has failed due to exhaustion of Data Store."); + break; + case failedInvalidCodeAddress: + System.out.println("Program has failed due to an invalid code address."); + break; + case failedInvalidInstruction: + System.out.println("Program has failed due to an invalid instruction."); + break; + case failedOverflow: + System.out.println("Program has failed due to overflow."); + break; + case failedZeroDivide: + System.out.println("Program has failed due to division by zero."); + break; + case failedIOError: + System.out.println("Program has failed due to an IO error."); + break; + } + if (status != halted) + dump(); + } + + // INTERPRETATION + + static void checkSpace(int spaceNeeded) { + // Signals failure if there is not enough space to expand the stack or + // heap by spaceNeeded. + + if (HT - ST < spaceNeeded) + status = failedDataStoreFull; + } + + static boolean isTrue(int datum) { + // Tests whether the given datum represents true. + return (datum == Machine.trueRep); + } + + static boolean equal(int size, int addr1, int addr2) { + // Tests whether two multi-word objects are equal, given their common + // size and their base addresses. + + boolean eq; + int index; + + eq = true; + index = 0; + while (eq && (index < size)) + if (data[addr1 + index] == data[addr2 + index]) + index = index + 1; + else + eq = false; + return eq; + } + + static int overflowChecked(long datum) { + // Signals failure if the datum is too large to fit into a single word, + // otherwise returns the datum as a single word. + + if ((-Machine.maxintRep <= datum) && (datum <= Machine.maxintRep)) + return (int) datum; + else { + status = failedOverflow; + return 0; + } + } + + static int toInt(boolean b) { + return b ? Machine.trueRep : Machine.falseRep; + } + + static int currentChar; + + static int readInt() throws java.io.IOException { + int temp = 0; + int sign = 1; + + do { + currentChar = System.in.read(); + } while (Character.isWhitespace((char) currentChar)); + + if ((currentChar == '-') || (currentChar == '+')) + do { + sign = (currentChar == '-') ? -1 : 1; + currentChar = System.in.read(); + } while ((currentChar == '-') || currentChar == '+'); + + if (Character.isDigit((char) currentChar)) + do { + temp = temp * 10 + (currentChar - '0'); + currentChar = System.in.read(); + } while (Character.isDigit((char) currentChar)); + + return sign * temp; + } + + static void callPrimitive(int primitiveDisplacement) { + // Invokes the given primitive routine. + + int addr, size; + char ch; + + switch (primitiveDisplacement) { + case Machine.idDisplacement: + break; // nothing to be done + case Machine.notDisplacement: + data[ST - 1] = toInt(!isTrue(data[ST - 1])); + break; + case Machine.andDisplacement: + ST = ST - 1; + data[ST - 1] = toInt(isTrue(data[ST - 1]) & isTrue(data[ST])); + break; + case Machine.orDisplacement: + ST = ST - 1; + data[ST - 1] = toInt(isTrue(data[ST - 1]) | isTrue(data[ST])); + break; + case Machine.succDisplacement: + data[ST - 1] = overflowChecked(data[ST - 1] + 1); + break; + case Machine.predDisplacement: + data[ST - 1] = overflowChecked(data[ST - 1] - 1); + break; + case Machine.negDisplacement: + data[ST - 1] = -data[ST - 1]; + break; + case Machine.addDisplacement: + ST = ST - 1; + accumulator = data[ST - 1]; + data[ST - 1] = overflowChecked(accumulator + data[ST]); + break; + case Machine.subDisplacement: + ST = ST - 1; + accumulator = data[ST - 1]; + data[ST - 1] = overflowChecked(accumulator - data[ST]); + break; + case Machine.multDisplacement: + ST = ST - 1; + accumulator = data[ST - 1]; + data[ST - 1] = overflowChecked(accumulator * data[ST]); + break; + case Machine.divDisplacement: + ST = ST - 1; + accumulator = data[ST - 1]; + if (data[ST] != 0) + data[ST - 1] = (int) (accumulator / data[ST]); + else + status = failedZeroDivide; + break; + case Machine.modDisplacement: + ST = ST - 1; + accumulator = data[ST - 1]; + if (data[ST] != 0) + data[ST - 1] = (int) (accumulator % data[ST]); + else + status = failedZeroDivide; + break; + case Machine.ltDisplacement: + ST = ST - 1; + data[ST - 1] = toInt(data[ST - 1] < data[ST]); + break; + case Machine.leDisplacement: + ST = ST - 1; + data[ST - 1] = toInt(data[ST - 1] <= data[ST]); + break; + case Machine.geDisplacement: + ST = ST - 1; + data[ST - 1] = toInt(data[ST - 1] >= data[ST]); + break; + case Machine.gtDisplacement: + ST = ST - 1; + data[ST - 1] = toInt(data[ST - 1] > data[ST]); + break; + case Machine.eqDisplacement: + size = data[ST - 1]; // size of each comparand + ST = ST - 2 * size; + data[ST - 1] = toInt(equal(size, ST - 1, ST - 1 + size)); + break; + case Machine.neDisplacement: + size = data[ST - 1]; // size of each comparand + ST = ST - 2 * size; + data[ST - 1] = toInt(!equal(size, ST - 1, ST - 1 + size)); + break; + case Machine.eolDisplacement: + data[ST] = toInt(currentChar == '\n'); + ST = ST + 1; + break; + case Machine.eofDisplacement: + data[ST] = toInt(currentChar == -1); + ST = ST + 1; + break; + case Machine.getDisplacement: + ST = ST - 1; + addr = data[ST]; + try { + currentChar = System.in.read(); + } catch (java.io.IOException s) { + status = failedIOError; + } + data[addr] = currentChar; + break; + case Machine.putDisplacement: + ST = ST - 1; + ch = (char) data[ST]; + System.out.print(ch); + break; + case Machine.geteolDisplacement: + try { + while ((currentChar = System.in.read()) != '\n') + ; + } catch (java.io.IOException s) { + status = failedIOError; + } + break; + case Machine.puteolDisplacement: + System.out.println(""); + break; + case Machine.getintDisplacement: + ST = ST - 1; + addr = data[ST]; + try { + accumulator = readInt(); + } catch (java.io.IOException s) { + status = failedIOError; + } + data[addr] = (int) accumulator; + break; + case Machine.putintDisplacement: + ST = ST - 1; + accumulator = data[ST]; + System.out.print(accumulator); + break; + case Machine.newDisplacement: + size = data[ST - 1]; + checkSpace(size); + HT = HT - size; + data[ST - 1] = HT; + break; + case Machine.disposeDisplacement: + ST = ST - 1; // no action taken at present + break; + } + } + + static void interpretProgram() { + // Runs the program in code store. + + Instruction currentInstr; + int op, r, n, d, addr, index; + + // Initialize registers ... + ST = SB; + HT = HB; + LB = SB; + CP = CB; + status = running; + do { + // Fetch instruction ... + currentInstr = Machine.code[CP]; + // Decode instruction ... + op = currentInstr.op; + r = currentInstr.r; + n = currentInstr.n; + d = currentInstr.d; + // Execute instruction ... + switch (op) { + case Machine.LOADop: + addr = d + content(r); + checkSpace(n); + for (index = 0; index < n; index++) + data[ST + index] = data[addr + index]; + ST = ST + n; + CP = CP + 1; + break; + case Machine.LOADAop: + addr = d + content(r); + checkSpace(1); + data[ST] = addr; + ST = ST + 1; + CP = CP + 1; + break; + case Machine.LOADIop: + ST = ST - 1; + addr = data[ST]; + checkSpace(n); + for (index = 0; index < n; index++) + data[ST + index] = data[addr + index]; + ST = ST + n; + CP = CP + 1; + break; + case Machine.LOADLop: + checkSpace(1); + data[ST] = d; + ST = ST + 1; + CP = CP + 1; + break; + case Machine.STOREop: + addr = d + content(r); + ST = ST - n; + for (index = 0; index < n; index++) + data[addr + index] = data[ST + index]; + CP = CP + 1; + break; + case Machine.STOREIop: + ST = ST - 1; + addr = data[ST]; + ST = ST - n; + for (index = 0; index < n; index++) + data[addr + index] = data[ST + index]; + CP = CP + 1; + break; + case Machine.CALLop: + addr = d + content(r); + if (addr >= Machine.PB) { + callPrimitive(addr - Machine.PB); + CP = CP + 1; + } else { + checkSpace(3); + if ((0 <= n) && (n <= 15)) + data[ST] = content(n); // static link + else + status = failedInvalidInstruction; + data[ST + 1] = LB; // dynamic link + data[ST + 2] = CP + 1; // return address + LB = ST; + ST = ST + 3; + CP = addr; + } + break; + case Machine.CALLIop: + ST = ST - 2; + addr = data[ST + 1]; + if (addr >= Machine.PB) { + callPrimitive(addr - Machine.PB); + CP = CP + 1; + } else { + // data[ST] = static link already + data[ST + 1] = LB; // dynamic link + data[ST + 2] = CP + 1; // return address + LB = ST; + ST = ST + 3; + CP = addr; + } + break; + case Machine.RETURNop: + addr = LB - d; + CP = data[LB + 2]; + LB = data[LB + 1]; + ST = ST - n; + for (index = 0; index < n; index++) + data[addr + index] = data[ST + index]; + ST = addr + n; + break; + case Machine.PUSHop: + checkSpace(d); + ST = ST + d; + CP = CP + 1; + break; + case Machine.POPop: + addr = ST - n - d; + ST = ST - n; + for (index = 0; index < n; index++) + data[addr + index] = data[ST + index]; + ST = addr + n; + CP = CP + 1; + break; + case Machine.JUMPop: + CP = d + content(r); + break; + case Machine.JUMPIop: + ST = ST - 1; + CP = data[ST]; + break; + case Machine.JUMPIFop: + ST = ST - 1; + if (data[ST] == n) + CP = d + content(r); + else + CP = CP + 1; + break; + case Machine.HALTop: + status = halted; + break; + } + if ((CP < CB) || (CP >= CT)) + status = failedInvalidCodeAddress; + } while (status == running); + } + + // LOADING + + static void loadObjectProgram(String objectName) { + // Loads the TAM object program into code store from the named file. + + FileInputStream objectFile = null; + DataInputStream objectStream = null; + + int addr; + boolean finished = false; + + try { + objectFile = new FileInputStream(objectName); + objectStream = new DataInputStream(objectFile); + + addr = Machine.CB; + while (!finished) { + Machine.code[addr] = Instruction.read(objectStream); + if (Machine.code[addr] == null) + finished = true; + else + addr = addr + 1; + } + CT = addr; + objectFile.close(); + } catch (FileNotFoundException s) { + CT = CB; + System.err.println("Error opening object file: " + s); + } catch (IOException s) { + CT = CB; + System.err.println("Error reading object file: " + s); + } + } + + // RUNNING + + public static void main(String[] args) { + System.out.println("********** TAM Interpreter (Java Version 2.1) **********"); + + if (args.length == 1) + objectName = args[0]; + else + objectName = "obj.tam"; + + loadObjectProgram(objectName); + if (CT != CB) { + interpretProgram(); + showStatus(); + } + } } diff --git a/Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Instruction.java b/Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Instruction.java index 785583a..bdfb7e4 100644 --- a/Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Instruction.java +++ b/Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Instruction.java @@ -21,44 +21,44 @@ import java.io.IOException; public class Instruction { - public Instruction() { - op = 0; - r = 0; - n = 0; - d = 0; - } + public Instruction() { + op = 0; + r = 0; + n = 0; + d = 0; + } - // Java has no type synonyms, so the following representations are - // assumed: - // - // type - // OpCode = 0..15; {4 bits unsigned} - // Length = 0..255; {8 bits unsigned} - // Operand = -32767..+32767; {16 bits signed} + // Java has no type synonyms, so the following representations are + // assumed: + // + // type + // OpCode = 0..15; {4 bits unsigned} + // Length = 0..255; {8 bits unsigned} + // Operand = -32767..+32767; {16 bits signed} - // Represents TAM instructions. - public int op; // OpCode - public int r; // RegisterNumber - public int n; // Length - public int d; // Operand + // Represents TAM instructions. + public int op; // OpCode + public int r; // RegisterNumber + public int n; // Length + public int d; // Operand - public void write(DataOutputStream output) throws IOException { - output.writeInt(op); - output.writeInt(r); - output.writeInt(n); - output.writeInt(d); - } + public void write(DataOutputStream output) throws IOException { + output.writeInt(op); + output.writeInt(r); + output.writeInt(n); + output.writeInt(d); + } - public static Instruction read(DataInputStream input) throws IOException { - Instruction inst = new Instruction(); - try { - inst.op = input.readInt(); - inst.r = input.readInt(); - inst.n = input.readInt(); - inst.d = input.readInt(); - return inst; - } catch (EOFException s) { - return null; - } - } + public static Instruction read(DataInputStream input) throws IOException { + Instruction inst = new Instruction(); + try { + inst.op = input.readInt(); + inst.r = input.readInt(); + inst.n = input.readInt(); + inst.d = input.readInt(); + return inst; + } catch (EOFException s) { + return null; + } + } } diff --git a/Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Machine.java b/Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Machine.java index 65e13a3..ef61e9e 100644 --- a/Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Machine.java +++ b/Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Machine.java @@ -16,110 +16,56 @@ package Triangle.AbstractMachine; public final class Machine { - public final static int maxRoutineLevel = 7; - - // WORDS AND ADDRESSES - - // Java has no type synonyms, so the following representations are - // assumed: - // - // type - // Word = -32767..+32767; {16 bits signed} - // DoubleWord = -2147483648..+2147483647; {32 bits signed} - // CodeAddress = 0..+32767; {15 bits unsigned} - // DataAddress = 0..+32767; {15 bits unsigned} - - // INSTRUCTIONS - - // Operation codes - public final static int LOADop = 0, - LOADAop = 1, - LOADIop = 2, - LOADLop = 3, - STOREop = 4, - STOREIop = 5, - CALLop = 6, - CALLIop = 7, - RETURNop = 8, - PUSHop = 10, - POPop = 11, - JUMPop = 12, - JUMPIop = 13, - JUMPIFop = 14, - HALTop = 15; - - // CODE STORE - - public static Instruction[] code = new Instruction[1024]; - - // CODE STORE REGISTERS - - public final static int CB = 0, - PB = 1024, // = upper bound of code array + 1 - PT = 1052; // = PB + 28 - - // REGISTER NUMBERS - - public final static int CBr = 0, - CTr = 1, - PBr = 2, - PTr = 3, - SBr = 4, - STr = 5, - HBr = 6, - HTr = 7, - LBr = 8, - L1r = LBr + 1, - L2r = LBr + 2, - L3r = LBr + 3, - L4r = LBr + 4, - L5r = LBr + 5, - L6r = LBr + 6, - CPr = 15; - - // DATA REPRESENTATION - - public final static int booleanSize = 1, - characterSize = 1, - integerSize = 1, - addressSize = 1, - closureSize = 2 * addressSize, - - linkDataSize = 3 * addressSize, - - falseRep = 0, - trueRep = 1, - maxintRep = 32767; - - // ADDRESSES OF PRIMITIVE ROUTINES - - public final static int idDisplacement = 1, - notDisplacement = 2, - andDisplacement = 3, - orDisplacement = 4, - succDisplacement = 5, - predDisplacement = 6, - negDisplacement = 7, - addDisplacement = 8, - subDisplacement = 9, - multDisplacement = 10, - divDisplacement = 11, - modDisplacement = 12, - ltDisplacement = 13, - leDisplacement = 14, - geDisplacement = 15, - gtDisplacement = 16, - eqDisplacement = 17, - neDisplacement = 18, - eolDisplacement = 19, - eofDisplacement = 20, - getDisplacement = 21, - putDisplacement = 22, - geteolDisplacement = 23, - puteolDisplacement = 24, - getintDisplacement = 25, - putintDisplacement = 26, - newDisplacement = 27, - disposeDisplacement = 28; + public final static int maxRoutineLevel = 7; + + // WORDS AND ADDRESSES + + // Java has no type synonyms, so the following representations are + // assumed: + // + // type + // Word = -32767..+32767; {16 bits signed} + // DoubleWord = -2147483648..+2147483647; {32 bits signed} + // CodeAddress = 0..+32767; {15 bits unsigned} + // DataAddress = 0..+32767; {15 bits unsigned} + + // INSTRUCTIONS + + // Operation codes + public final static int LOADop = 0, LOADAop = 1, LOADIop = 2, LOADLop = 3, STOREop = 4, STOREIop = 5, CALLop = 6, + CALLIop = 7, RETURNop = 8, PUSHop = 10, POPop = 11, JUMPop = 12, JUMPIop = 13, JUMPIFop = 14, HALTop = 15; + + // CODE STORE + + public static Instruction[] code = new Instruction[1024]; + + // CODE STORE REGISTERS + + public final static int CB = 0, PB = 1024, // = upper bound of code array + 1 + PT = 1052; // = PB + 28 + + // REGISTER NUMBERS + + public final static int CBr = 0, CTr = 1, PBr = 2, PTr = 3, SBr = 4, STr = 5, HBr = 6, HTr = 7, LBr = 8, + L1r = LBr + 1, L2r = LBr + 2, L3r = LBr + 3, L4r = LBr + 4, L5r = LBr + 5, L6r = LBr + 6, CPr = 15; + + // DATA REPRESENTATION + + public final static int booleanSize = 1, characterSize = 1, integerSize = 1, addressSize = 1, + closureSize = 2 * addressSize, + + linkDataSize = 3 * addressSize, + + falseRep = 0, trueRep = 1, maxintRep = 32767; + + // ADDRESSES OF PRIMITIVE ROUTINES + + public final static int idDisplacement = 1, notDisplacement = 2, andDisplacement = 3, orDisplacement = 4, + succDisplacement = 5, predDisplacement = 6, negDisplacement = 7, addDisplacement = 8, subDisplacement = 9, + multDisplacement = 10, divDisplacement = 11, modDisplacement = 12, ltDisplacement = 13, leDisplacement = 14, + geDisplacement = 15, gtDisplacement = 16, eqDisplacement = 17, neDisplacement = 18, eolDisplacement = 19, + eofDisplacement = 20, getDisplacement = 21, putDisplacement = 22, geteolDisplacement = 23, + puteolDisplacement = 24, getintDisplacement = 25, putintDisplacement = 26, newDisplacement = 27, + disposeDisplacement = 28; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AST.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AST.java index 6f3857c..179d568 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AST.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AST.java @@ -19,17 +19,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public abstract class AST { - public AST(SourcePosition thePosition) { - position = thePosition; - entity = null; - } + public AST(SourcePosition thePosition) { + position = thePosition; + entity = null; + } - public SourcePosition getPosition() { - return position; - } + public SourcePosition getPosition() { + return position; + } - public abstract Object visit(Visitor v, Object o); + public abstract Object visit(Visitor v, Object o); - public SourcePosition position; - public RuntimeEntity entity; + public SourcePosition position; + public RuntimeEntity entity; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ActualParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ActualParameter.java index 34cae48..5fed0fb 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ActualParameter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ActualParameter.java @@ -18,7 +18,7 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public abstract class ActualParameter extends AST { - public ActualParameter(SourcePosition thePosition) { - super(thePosition); - } + public ActualParameter(SourcePosition thePosition) { + super(thePosition); + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ActualParameterSequence.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ActualParameterSequence.java index d99a36d..0b40d39 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ActualParameterSequence.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ActualParameterSequence.java @@ -18,7 +18,7 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public abstract class ActualParameterSequence extends AST { - public ActualParameterSequence(SourcePosition thePosition) { - super(thePosition); - } + public ActualParameterSequence(SourcePosition thePosition) { + super(thePosition); + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AnyTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AnyTypeDenoter.java index db0df2b..13abea9 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AnyTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AnyTypeDenoter.java @@ -18,17 +18,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class AnyTypeDenoter extends TypeDenoter { - public AnyTypeDenoter(SourcePosition thePosition) { - super(thePosition); - } + public AnyTypeDenoter(SourcePosition thePosition) { + super(thePosition); + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitAnyTypeDenoter(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitAnyTypeDenoter(this, o); + } - @Override -public boolean equals(Object obj) { - return false; - } + @Override + public boolean equals(Object obj) { + return false; + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayAggregate.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayAggregate.java index 811a35a..8f9465f 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayAggregate.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayAggregate.java @@ -18,10 +18,10 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public abstract class ArrayAggregate extends AST { - public ArrayAggregate(SourcePosition thePosition) { - super(thePosition); - elemCount = 0; - } + public ArrayAggregate(SourcePosition thePosition) { + super(thePosition); + elemCount = 0; + } - public int elemCount; + public int elemCount; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayExpression.java index 88b1558..810fb67 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayExpression.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayExpression.java @@ -18,16 +18,15 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class ArrayExpression extends Expression { - public ArrayExpression(ArrayAggregate aaAST, - SourcePosition thePosition) { - super(thePosition); - AA = aaAST; - } + public ArrayExpression(ArrayAggregate aaAST, SourcePosition thePosition) { + super(thePosition); + AA = aaAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitArrayExpression(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitArrayExpression(this, o); + } - public ArrayAggregate AA; + public ArrayAggregate AA; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayTypeDenoter.java index 5f114a8..ecaa9fd 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayTypeDenoter.java @@ -18,29 +18,28 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class ArrayTypeDenoter extends TypeDenoter { - public ArrayTypeDenoter(IntegerLiteral ilAST, TypeDenoter tAST, - SourcePosition thePosition) { - super(thePosition); - IL = ilAST; - T = tAST; - } + public ArrayTypeDenoter(IntegerLiteral ilAST, TypeDenoter tAST, SourcePosition thePosition) { + super(thePosition); + IL = ilAST; + T = tAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitArrayTypeDenoter(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitArrayTypeDenoter(this, o); + } - @Override -public boolean equals(Object obj) { - if (obj != null && obj instanceof ErrorTypeDenoter) - return true; - else if (obj != null && obj instanceof ArrayTypeDenoter) - return this.IL.spelling.compareTo(((ArrayTypeDenoter) obj).IL.spelling) == 0 && - this.T.equals(((ArrayTypeDenoter) obj).T); - else - return false; - } + @Override + public boolean equals(Object obj) { + if (obj != null && obj instanceof ErrorTypeDenoter) + return true; + else if (obj != null && obj instanceof ArrayTypeDenoter) + return this.IL.spelling.compareTo(((ArrayTypeDenoter) obj).IL.spelling) == 0 + && this.T.equals(((ArrayTypeDenoter) obj).T); + else + return false; + } - public IntegerLiteral IL; - public TypeDenoter T; + public IntegerLiteral IL; + public TypeDenoter T; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AssignCommand.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AssignCommand.java index bbdb89d..6bfc924 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AssignCommand.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AssignCommand.java @@ -18,17 +18,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class AssignCommand extends Command { - public AssignCommand(Vname vAST, Expression eAST, SourcePosition thePosition) { - super(thePosition); - V = vAST; - E = eAST; - } + public AssignCommand(Vname vAST, Expression eAST, SourcePosition thePosition) { + super(thePosition); + V = vAST; + E = eAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitAssignCommand(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitAssignCommand(this, o); + } - public Vname V; - public Expression E; + public Vname V; + public Expression E; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BinaryExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BinaryExpression.java index c3a27d3..c5bd980 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BinaryExpression.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BinaryExpression.java @@ -18,19 +18,18 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class BinaryExpression extends Expression { - public BinaryExpression(Expression e1AST, Operator oAST, Expression e2AST, - SourcePosition thePosition) { - super(thePosition); - O = oAST; - E1 = e1AST; - E2 = e2AST; - } + public BinaryExpression(Expression e1AST, Operator oAST, Expression e2AST, SourcePosition thePosition) { + super(thePosition); + O = oAST; + E1 = e1AST; + E2 = e2AST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitBinaryExpression(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitBinaryExpression(this, o); + } - public Expression E1, E2; - public Operator O; + public Expression E1, E2; + public Operator O; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BinaryOperatorDeclaration.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BinaryOperatorDeclaration.java index 421b96f..30617bc 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BinaryOperatorDeclaration.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BinaryOperatorDeclaration.java @@ -18,21 +18,20 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class BinaryOperatorDeclaration extends Declaration { - public BinaryOperatorDeclaration(Operator oAST, TypeDenoter arg1AST, - TypeDenoter arg2AST, TypeDenoter resultAST, - SourcePosition thePosition) { - super(thePosition); - O = oAST; - ARG1 = arg1AST; - ARG2 = arg2AST; - RES = resultAST; - } + public BinaryOperatorDeclaration(Operator oAST, TypeDenoter arg1AST, TypeDenoter arg2AST, TypeDenoter resultAST, + SourcePosition thePosition) { + super(thePosition); + O = oAST; + ARG1 = arg1AST; + ARG2 = arg2AST; + RES = resultAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitBinaryOperatorDeclaration(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitBinaryOperatorDeclaration(this, o); + } - public Operator O; - public TypeDenoter ARG1, ARG2, RES; + public Operator O; + public TypeDenoter ARG1, ARG2, RES; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BoolTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BoolTypeDenoter.java index 8ab85b9..12bc07d 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BoolTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BoolTypeDenoter.java @@ -18,20 +18,20 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class BoolTypeDenoter extends TypeDenoter { - public BoolTypeDenoter(SourcePosition thePosition) { - super(thePosition); - } + public BoolTypeDenoter(SourcePosition thePosition) { + super(thePosition); + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitBoolTypeDenoter(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitBoolTypeDenoter(this, o); + } - @Override -public boolean equals(Object obj) { - if ((obj != null) && (obj instanceof ErrorTypeDenoter)) - return true; - else - return ((obj != null) && (obj instanceof BoolTypeDenoter)); - } + @Override + public boolean equals(Object obj) { + if ((obj != null) && (obj instanceof ErrorTypeDenoter)) + return true; + else + return ((obj != null) && (obj instanceof BoolTypeDenoter)); + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CallCommand.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CallCommand.java index 10a37f0..23c31bf 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CallCommand.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CallCommand.java @@ -18,18 +18,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class CallCommand extends Command { - public CallCommand(Identifier iAST, ActualParameterSequence apsAST, - SourcePosition thePosition) { - super(thePosition); - I = iAST; - APS = apsAST; - } + public CallCommand(Identifier iAST, ActualParameterSequence apsAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + APS = apsAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitCallCommand(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitCallCommand(this, o); + } - public Identifier I; - public ActualParameterSequence APS; + public Identifier I; + public ActualParameterSequence APS; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CallExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CallExpression.java index dcabc2e..a4c7a46 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CallExpression.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CallExpression.java @@ -18,18 +18,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class CallExpression extends Expression { - public CallExpression(Identifier iAST, ActualParameterSequence apsAST, - SourcePosition thePosition) { - super(thePosition); - I = iAST; - APS = apsAST; - } + public CallExpression(Identifier iAST, ActualParameterSequence apsAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + APS = apsAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitCallExpression(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitCallExpression(this, o); + } - public Identifier I; - public ActualParameterSequence APS; + public Identifier I; + public ActualParameterSequence APS; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharTypeDenoter.java index 7895dde..93d3672 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharTypeDenoter.java @@ -18,20 +18,20 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class CharTypeDenoter extends TypeDenoter { - public CharTypeDenoter(SourcePosition thePosition) { - super(thePosition); - } + public CharTypeDenoter(SourcePosition thePosition) { + super(thePosition); + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitCharTypeDenoter(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitCharTypeDenoter(this, o); + } - @Override -public boolean equals(Object obj) { - if (obj != null && obj instanceof ErrorTypeDenoter) - return true; - else - return (obj != null && obj instanceof CharTypeDenoter); - } + @Override + public boolean equals(Object obj) { + if (obj != null && obj instanceof ErrorTypeDenoter) + return true; + else + return (obj != null && obj instanceof CharTypeDenoter); + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharacterExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharacterExpression.java index 2718339..522333e 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharacterExpression.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharacterExpression.java @@ -18,15 +18,15 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class CharacterExpression extends Expression { - public CharacterExpression(CharacterLiteral clAST, SourcePosition thePosition) { - super(thePosition); - CL = clAST; - } + public CharacterExpression(CharacterLiteral clAST, SourcePosition thePosition) { + super(thePosition); + CL = clAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitCharacterExpression(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitCharacterExpression(this, o); + } - public CharacterLiteral CL; + public CharacterLiteral CL; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharacterLiteral.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharacterLiteral.java index 4ba6f0b..a8b5046 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharacterLiteral.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharacterLiteral.java @@ -18,13 +18,13 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class CharacterLiteral extends Terminal { - public CharacterLiteral(String theSpelling, SourcePosition thePosition) { - super(theSpelling, thePosition); - } + public CharacterLiteral(String theSpelling, SourcePosition thePosition) { + super(theSpelling, thePosition); + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitCharacterLiteral(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitCharacterLiteral(this, o); + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Command.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Command.java index 69acee0..240b7bc 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Command.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Command.java @@ -18,7 +18,7 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public abstract class Command extends AST { - public Command(SourcePosition thePosition) { - super(thePosition); - } + public Command(SourcePosition thePosition) { + super(thePosition); + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstActualParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstActualParameter.java index 90b0e4d..271fa66 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstActualParameter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstActualParameter.java @@ -18,15 +18,15 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class ConstActualParameter extends ActualParameter { - public ConstActualParameter(Expression eAST, SourcePosition thePosition) { - super(thePosition); - E = eAST; - } + public ConstActualParameter(Expression eAST, SourcePosition thePosition) { + super(thePosition); + E = eAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitConstActualParameter(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitConstActualParameter(this, o); + } - public Expression E; + public Expression E; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstDeclaration.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstDeclaration.java index 6251aa2..c4588d7 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstDeclaration.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstDeclaration.java @@ -18,18 +18,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class ConstDeclaration extends Declaration { - public ConstDeclaration(Identifier iAST, Expression eAST, - SourcePosition thePosition) { - super(thePosition); - I = iAST; - E = eAST; - } + public ConstDeclaration(Identifier iAST, Expression eAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + E = eAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitConstDeclaration(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitConstDeclaration(this, o); + } - public Identifier I; - public Expression E; + public Identifier I; + public Expression E; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstFormalParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstFormalParameter.java index 7add9b7..923d5e6 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstFormalParameter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstFormalParameter.java @@ -18,27 +18,26 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class ConstFormalParameter extends FormalParameter { - public ConstFormalParameter(Identifier iAST, TypeDenoter tAST, - SourcePosition thePosition) { - super(thePosition); - I = iAST; - T = tAST; - } + public ConstFormalParameter(Identifier iAST, TypeDenoter tAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + T = tAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitConstFormalParameter(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitConstFormalParameter(this, o); + } - public Identifier I; - public TypeDenoter T; + public Identifier I; + public TypeDenoter T; - @Override -public boolean equals(Object fpAST) { - if (fpAST instanceof ConstFormalParameter) { - ConstFormalParameter cfpAST = (ConstFormalParameter) fpAST; - return T.equals(cfpAST.T); - } else - return false; - } + @Override + public boolean equals(Object fpAST) { + if (fpAST instanceof ConstFormalParameter) { + ConstFormalParameter cfpAST = (ConstFormalParameter) fpAST; + return T.equals(cfpAST.T); + } else + return false; + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Declaration.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Declaration.java index 586293b..6ac0602 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Declaration.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Declaration.java @@ -18,10 +18,10 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public abstract class Declaration extends AST { - public Declaration(SourcePosition thePosition) { - super(thePosition); - duplicated = false; - } + public Declaration(SourcePosition thePosition) { + super(thePosition); + duplicated = false; + } - public boolean duplicated; + public boolean duplicated; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/DotVname.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/DotVname.java index 48bfc48..c53cfbb 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/DotVname.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/DotVname.java @@ -18,17 +18,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class DotVname extends Vname { - public DotVname(Vname vAST, Identifier iAST, SourcePosition thePosition) { - super(thePosition); - V = vAST; - I = iAST; - } + public DotVname(Vname vAST, Identifier iAST, SourcePosition thePosition) { + super(thePosition); + V = vAST; + I = iAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitDotVname(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitDotVname(this, o); + } - public Identifier I; - public Vname V; + public Identifier I; + public Vname V; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyActualParameterSequence.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyActualParameterSequence.java index 611aa37..efab13e 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyActualParameterSequence.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyActualParameterSequence.java @@ -18,12 +18,12 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class EmptyActualParameterSequence extends ActualParameterSequence { - public EmptyActualParameterSequence(SourcePosition thePosition) { - super(thePosition); - } + public EmptyActualParameterSequence(SourcePosition thePosition) { + super(thePosition); + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitEmptyActualParameterSequence(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitEmptyActualParameterSequence(this, o); + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyCommand.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyCommand.java index 9e395e3..d00efd9 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyCommand.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyCommand.java @@ -18,12 +18,12 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class EmptyCommand extends Command { - public EmptyCommand(SourcePosition thePosition) { - super(thePosition); - } + public EmptyCommand(SourcePosition thePosition) { + super(thePosition); + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitEmptyCommand(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitEmptyCommand(this, o); + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyExpression.java index 74fa7a2..a960a58 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyExpression.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyExpression.java @@ -18,12 +18,12 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class EmptyExpression extends Expression { - public EmptyExpression(SourcePosition thePosition) { - super(thePosition); - } + public EmptyExpression(SourcePosition thePosition) { + super(thePosition); + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitEmptyExpression(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitEmptyExpression(this, o); + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyFormalParameterSequence.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyFormalParameterSequence.java index b0a15e3..70dd07f 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyFormalParameterSequence.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyFormalParameterSequence.java @@ -18,17 +18,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class EmptyFormalParameterSequence extends FormalParameterSequence { - public EmptyFormalParameterSequence(SourcePosition thePosition) { - super(thePosition); - } + public EmptyFormalParameterSequence(SourcePosition thePosition) { + super(thePosition); + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitEmptyFormalParameterSequence(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitEmptyFormalParameterSequence(this, o); + } - @Override -public boolean equals(Object fpsAST) { - return (fpsAST instanceof EmptyFormalParameterSequence); - } + @Override + public boolean equals(Object fpsAST) { + return (fpsAST instanceof EmptyFormalParameterSequence); + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ErrorTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ErrorTypeDenoter.java index 66382e3..3cb0f6f 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ErrorTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ErrorTypeDenoter.java @@ -18,17 +18,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class ErrorTypeDenoter extends TypeDenoter { - public ErrorTypeDenoter(SourcePosition thePosition) { - super(thePosition); - } + public ErrorTypeDenoter(SourcePosition thePosition) { + super(thePosition); + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitErrorTypeDenoter(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitErrorTypeDenoter(this, o); + } - @Override -public boolean equals(Object obj) { - return true; - } + @Override + public boolean equals(Object obj) { + return true; + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Expression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Expression.java index 682d314..32dac66 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Expression.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Expression.java @@ -18,10 +18,10 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public abstract class Expression extends AST { - public Expression(SourcePosition thePosition) { - super(thePosition); - type = null; - } + public Expression(SourcePosition thePosition) { + super(thePosition); + type = null; + } - public TypeDenoter type; + public TypeDenoter type; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FieldTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FieldTypeDenoter.java index bebe36f..d229271 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FieldTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FieldTypeDenoter.java @@ -18,10 +18,10 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public abstract class FieldTypeDenoter extends TypeDenoter { - public FieldTypeDenoter(SourcePosition thePosition) { - super(thePosition); - } + public FieldTypeDenoter(SourcePosition thePosition) { + super(thePosition); + } - @Override -public abstract boolean equals(Object obj); + @Override + public abstract boolean equals(Object obj); } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FormalParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FormalParameter.java index ac600ee..2ca1b02 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FormalParameter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FormalParameter.java @@ -18,11 +18,11 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public abstract class FormalParameter extends Declaration { - public FormalParameter(SourcePosition thePosition) { - super(thePosition); - } + public FormalParameter(SourcePosition thePosition) { + super(thePosition); + } - @Override -public abstract boolean equals(Object fpAST); + @Override + public abstract boolean equals(Object fpAST); } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FormalParameterSequence.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FormalParameterSequence.java index 4bed80a..7e62f17 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FormalParameterSequence.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FormalParameterSequence.java @@ -18,10 +18,10 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public abstract class FormalParameterSequence extends AST { - public FormalParameterSequence(SourcePosition thePosition) { - super(thePosition); - } + public FormalParameterSequence(SourcePosition thePosition) { + super(thePosition); + } - @Override -public abstract boolean equals(Object fpsAST); + @Override + public abstract boolean equals(Object fpsAST); } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncActualParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncActualParameter.java index d0b42cf..8561892 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncActualParameter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncActualParameter.java @@ -18,15 +18,15 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class FuncActualParameter extends ActualParameter { - public FuncActualParameter(Identifier iAST, SourcePosition thePosition) { - super(thePosition); - I = iAST; - } + public FuncActualParameter(Identifier iAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitFuncActualParameter(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitFuncActualParameter(this, o); + } - public Identifier I; + public Identifier I; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncDeclaration.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncDeclaration.java index 570dd28..bff1c2b 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncDeclaration.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncDeclaration.java @@ -18,23 +18,22 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class FuncDeclaration extends Declaration { - public FuncDeclaration(Identifier iAST, FormalParameterSequence fpsAST, - TypeDenoter tAST, Expression eAST, - SourcePosition thePosition) { - super(thePosition); - I = iAST; - FPS = fpsAST; - T = tAST; - E = eAST; - } + public FuncDeclaration(Identifier iAST, FormalParameterSequence fpsAST, TypeDenoter tAST, Expression eAST, + SourcePosition thePosition) { + super(thePosition); + I = iAST; + FPS = fpsAST; + T = tAST; + E = eAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitFuncDeclaration(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitFuncDeclaration(this, o); + } - public Identifier I; - public FormalParameterSequence FPS; - public TypeDenoter T; - public Expression E; + public Identifier I; + public FormalParameterSequence FPS; + public TypeDenoter T; + public Expression E; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncFormalParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncFormalParameter.java index db08107..3cfbb7b 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncFormalParameter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncFormalParameter.java @@ -18,29 +18,29 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class FuncFormalParameter extends FormalParameter { - public FuncFormalParameter(Identifier iAST, FormalParameterSequence fpsAST, - TypeDenoter tAST, SourcePosition thePosition) { - super(thePosition); - I = iAST; - FPS = fpsAST; - T = tAST; - } + public FuncFormalParameter(Identifier iAST, FormalParameterSequence fpsAST, TypeDenoter tAST, + SourcePosition thePosition) { + super(thePosition); + I = iAST; + FPS = fpsAST; + T = tAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitFuncFormalParameter(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitFuncFormalParameter(this, o); + } - @Override -public boolean equals(Object fpAST) { - if (fpAST instanceof FuncFormalParameter) { - FuncFormalParameter ffpAST = (FuncFormalParameter) fpAST; - return FPS.equals(ffpAST.FPS) && T.equals(ffpAST.T); - } else - return false; - } + @Override + public boolean equals(Object fpAST) { + if (fpAST instanceof FuncFormalParameter) { + FuncFormalParameter ffpAST = (FuncFormalParameter) fpAST; + return FPS.equals(ffpAST.FPS) && T.equals(ffpAST.T); + } else + return false; + } - public Identifier I; - public FormalParameterSequence FPS; - public TypeDenoter T; + public Identifier I; + public FormalParameterSequence FPS; + public TypeDenoter T; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Identifier.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Identifier.java index 715b95a..3031dd0 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Identifier.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Identifier.java @@ -18,17 +18,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class Identifier extends Terminal { - public Identifier(String theSpelling, SourcePosition thePosition) { - super(theSpelling, thePosition); - type = null; - decl = null; - } + public Identifier(String theSpelling, SourcePosition thePosition) { + super(theSpelling, thePosition); + type = null; + decl = null; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitIdentifier(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitIdentifier(this, o); + } - public TypeDenoter type; - public AST decl; // Either a Declaration or a FieldTypeDenoter + public TypeDenoter type; + public AST decl; // Either a Declaration or a FieldTypeDenoter } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IfCommand.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IfCommand.java index b5e4537..02b4faf 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IfCommand.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IfCommand.java @@ -18,19 +18,18 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class IfCommand extends Command { - public IfCommand(Expression eAST, Command c1AST, Command c2AST, - SourcePosition thePosition) { - super(thePosition); - E = eAST; - C1 = c1AST; - C2 = c2AST; - } + public IfCommand(Expression eAST, Command c1AST, Command c2AST, SourcePosition thePosition) { + super(thePosition); + E = eAST; + C1 = c1AST; + C2 = c2AST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitIfCommand(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitIfCommand(this, o); + } - public Expression E; - public Command C1, C2; + public Expression E; + public Command C1, C2; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IfExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IfExpression.java index 37235dc..f66e852 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IfExpression.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IfExpression.java @@ -18,18 +18,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class IfExpression extends Expression { - public IfExpression(Expression e1AST, Expression e2AST, Expression e3AST, - SourcePosition thePosition) { - super(thePosition); - E1 = e1AST; - E2 = e2AST; - E3 = e3AST; - } + public IfExpression(Expression e1AST, Expression e2AST, Expression e3AST, SourcePosition thePosition) { + super(thePosition); + E1 = e1AST; + E2 = e2AST; + E3 = e3AST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitIfExpression(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitIfExpression(this, o); + } - public Expression E1, E2, E3; + public Expression E1, E2, E3; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntTypeDenoter.java index 33eb368..ae92ad8 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntTypeDenoter.java @@ -18,20 +18,20 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class IntTypeDenoter extends TypeDenoter { - public IntTypeDenoter(SourcePosition thePosition) { - super(thePosition); - } + public IntTypeDenoter(SourcePosition thePosition) { + super(thePosition); + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitIntTypeDenoter(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitIntTypeDenoter(this, o); + } - @Override -public boolean equals(Object obj) { - if (obj != null && obj instanceof ErrorTypeDenoter) - return true; - else - return (obj != null && obj instanceof IntTypeDenoter); - } + @Override + public boolean equals(Object obj) { + if (obj != null && obj instanceof ErrorTypeDenoter) + return true; + else + return (obj != null && obj instanceof IntTypeDenoter); + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntegerExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntegerExpression.java index 49006cf..986a6ba 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntegerExpression.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntegerExpression.java @@ -18,15 +18,15 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class IntegerExpression extends Expression { - public IntegerExpression(IntegerLiteral ilAST, SourcePosition thePosition) { - super(thePosition); - IL = ilAST; - } + public IntegerExpression(IntegerLiteral ilAST, SourcePosition thePosition) { + super(thePosition); + IL = ilAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitIntegerExpression(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitIntegerExpression(this, o); + } - public IntegerLiteral IL; + public IntegerLiteral IL; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntegerLiteral.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntegerLiteral.java index eea340b..037b3a6 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntegerLiteral.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntegerLiteral.java @@ -18,13 +18,13 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class IntegerLiteral extends Terminal { - public IntegerLiteral(String theSpelling, SourcePosition thePosition) { - super(theSpelling, thePosition); - } + public IntegerLiteral(String theSpelling, SourcePosition thePosition) { + super(theSpelling, thePosition); + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitIntegerLiteral(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitIntegerLiteral(this, o); + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/LetCommand.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/LetCommand.java index 049a0b4..bff4a43 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/LetCommand.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/LetCommand.java @@ -18,17 +18,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class LetCommand extends Command { - public LetCommand(Declaration dAST, Command cAST, SourcePosition thePosition) { - super(thePosition); - D = dAST; - C = cAST; - } + public LetCommand(Declaration dAST, Command cAST, SourcePosition thePosition) { + super(thePosition); + D = dAST; + C = cAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitLetCommand(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitLetCommand(this, o); + } - public Declaration D; - public Command C; + public Declaration D; + public Command C; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/LetExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/LetExpression.java index a928f4c..6090936 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/LetExpression.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/LetExpression.java @@ -18,17 +18,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class LetExpression extends Expression { - public LetExpression(Declaration dAST, Expression eAST, SourcePosition thePosition) { - super(thePosition); - D = dAST; - E = eAST; - } + public LetExpression(Declaration dAST, Expression eAST, SourcePosition thePosition) { + super(thePosition); + D = dAST; + E = eAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitLetExpression(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitLetExpression(this, o); + } - public Declaration D; - public Expression E; + public Declaration D; + public Expression E; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleActualParameterSequence.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleActualParameterSequence.java index 944fa42..a6bf9dc 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleActualParameterSequence.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleActualParameterSequence.java @@ -18,18 +18,18 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class MultipleActualParameterSequence extends ActualParameterSequence { - public MultipleActualParameterSequence(ActualParameter apAST, ActualParameterSequence apsAST, - SourcePosition thePosition) { - super(thePosition); - AP = apAST; - APS = apsAST; - } + public MultipleActualParameterSequence(ActualParameter apAST, ActualParameterSequence apsAST, + SourcePosition thePosition) { + super(thePosition); + AP = apAST; + APS = apsAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitMultipleActualParameterSequence(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitMultipleActualParameterSequence(this, o); + } - public ActualParameter AP; - public ActualParameterSequence APS; + public ActualParameter AP; + public ActualParameterSequence APS; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleArrayAggregate.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleArrayAggregate.java index 07e8533..1c2cb6a 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleArrayAggregate.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleArrayAggregate.java @@ -18,18 +18,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class MultipleArrayAggregate extends ArrayAggregate { - public MultipleArrayAggregate(Expression eAST, ArrayAggregate aaAST, - SourcePosition thePosition) { - super(thePosition); - E = eAST; - AA = aaAST; - } + public MultipleArrayAggregate(Expression eAST, ArrayAggregate aaAST, SourcePosition thePosition) { + super(thePosition); + E = eAST; + AA = aaAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitMultipleArrayAggregate(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitMultipleArrayAggregate(this, o); + } - public Expression E; - public ArrayAggregate AA; + public Expression E; + public ArrayAggregate AA; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFieldTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFieldTypeDenoter.java index 3c42f42..da4ce6a 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFieldTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFieldTypeDenoter.java @@ -18,31 +18,29 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class MultipleFieldTypeDenoter extends FieldTypeDenoter { - public MultipleFieldTypeDenoter(Identifier iAST, TypeDenoter tAST, FieldTypeDenoter ftAST, - SourcePosition thePosition) { - super(thePosition); - I = iAST; - T = tAST; - FT = ftAST; - } + public MultipleFieldTypeDenoter(Identifier iAST, TypeDenoter tAST, FieldTypeDenoter ftAST, + SourcePosition thePosition) { + super(thePosition); + I = iAST; + T = tAST; + FT = ftAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitMultipleFieldTypeDenoter(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitMultipleFieldTypeDenoter(this, o); + } - @Override -public boolean equals(Object obj) { - if (obj != null && obj instanceof MultipleFieldTypeDenoter) { - MultipleFieldTypeDenoter ft = (MultipleFieldTypeDenoter) obj; - return (this.I.spelling.compareTo(ft.I.spelling) == 0) && - this.T.equals(ft.T) && - this.FT.equals(ft.FT); - } else - return false; - } + @Override + public boolean equals(Object obj) { + if (obj != null && obj instanceof MultipleFieldTypeDenoter) { + MultipleFieldTypeDenoter ft = (MultipleFieldTypeDenoter) obj; + return (this.I.spelling.compareTo(ft.I.spelling) == 0) && this.T.equals(ft.T) && this.FT.equals(ft.FT); + } else + return false; + } - public Identifier I; - public TypeDenoter T; - public FieldTypeDenoter FT; + public Identifier I; + public TypeDenoter T; + public FieldTypeDenoter FT; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFormalParameterSequence.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFormalParameterSequence.java index 966651b..ae9497a 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFormalParameterSequence.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFormalParameterSequence.java @@ -18,27 +18,27 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class MultipleFormalParameterSequence extends FormalParameterSequence { - public MultipleFormalParameterSequence(FormalParameter fpAST, FormalParameterSequence fpsAST, - SourcePosition thePosition) { - super(thePosition); - FP = fpAST; - FPS = fpsAST; - } + public MultipleFormalParameterSequence(FormalParameter fpAST, FormalParameterSequence fpsAST, + SourcePosition thePosition) { + super(thePosition); + FP = fpAST; + FPS = fpsAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitMultipleFormalParameterSequence(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitMultipleFormalParameterSequence(this, o); + } - @Override -public boolean equals(Object fpsAST) { - if (fpsAST instanceof MultipleFormalParameterSequence) { - MultipleFormalParameterSequence mfpsAST = (MultipleFormalParameterSequence) fpsAST; - return FP.equals(mfpsAST.FP) && FPS.equals(mfpsAST.FPS); - } else - return false; - } + @Override + public boolean equals(Object fpsAST) { + if (fpsAST instanceof MultipleFormalParameterSequence) { + MultipleFormalParameterSequence mfpsAST = (MultipleFormalParameterSequence) fpsAST; + return FP.equals(mfpsAST.FP) && FPS.equals(mfpsAST.FPS); + } else + return false; + } - public FormalParameter FP; - public FormalParameterSequence FPS; + public FormalParameter FP; + public FormalParameterSequence FPS; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleRecordAggregate.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleRecordAggregate.java index 0134b95..1435a82 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleRecordAggregate.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleRecordAggregate.java @@ -18,20 +18,20 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class MultipleRecordAggregate extends RecordAggregate { - public MultipleRecordAggregate(Identifier iAST, Expression eAST, RecordAggregate raAST, - SourcePosition thePosition) { - super(thePosition); - I = iAST; - E = eAST; - RA = raAST; - } + public MultipleRecordAggregate(Identifier iAST, Expression eAST, RecordAggregate raAST, + SourcePosition thePosition) { + super(thePosition); + I = iAST; + E = eAST; + RA = raAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitMultipleRecordAggregate(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitMultipleRecordAggregate(this, o); + } - public Identifier I; - public Expression E; - public RecordAggregate RA; + public Identifier I; + public Expression E; + public RecordAggregate RA; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Operator.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Operator.java index f737a3a..e36e569 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Operator.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Operator.java @@ -18,15 +18,15 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class Operator extends Terminal { - public Operator(String theSpelling, SourcePosition thePosition) { - super(theSpelling, thePosition); - decl = null; - } + public Operator(String theSpelling, SourcePosition thePosition) { + super(theSpelling, thePosition); + decl = null; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitOperator(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitOperator(this, o); + } - public Declaration decl; + public Declaration decl; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcActualParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcActualParameter.java index 21a59ea..a56dc92 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcActualParameter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcActualParameter.java @@ -18,15 +18,15 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class ProcActualParameter extends ActualParameter { - public ProcActualParameter(Identifier iAST, SourcePosition thePosition) { - super(thePosition); - I = iAST; - } + public ProcActualParameter(Identifier iAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitProcActualParameter(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitProcActualParameter(this, o); + } - public Identifier I; + public Identifier I; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcDeclaration.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcDeclaration.java index d923810..7cf8d16 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcDeclaration.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcDeclaration.java @@ -18,20 +18,19 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class ProcDeclaration extends Declaration { - public ProcDeclaration(Identifier iAST, FormalParameterSequence fpsAST, - Command cAST, SourcePosition thePosition) { - super(thePosition); - I = iAST; - FPS = fpsAST; - C = cAST; - } + public ProcDeclaration(Identifier iAST, FormalParameterSequence fpsAST, Command cAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + FPS = fpsAST; + C = cAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitProcDeclaration(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitProcDeclaration(this, o); + } - public Identifier I; - public FormalParameterSequence FPS; - public Command C; + public Identifier I; + public FormalParameterSequence FPS; + public Command C; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcFormalParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcFormalParameter.java index b20a21d..327ce28 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcFormalParameter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcFormalParameter.java @@ -18,27 +18,26 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class ProcFormalParameter extends FormalParameter { - public ProcFormalParameter(Identifier iAST, FormalParameterSequence fpsAST, - SourcePosition thePosition) { - super(thePosition); - I = iAST; - FPS = fpsAST; - } + public ProcFormalParameter(Identifier iAST, FormalParameterSequence fpsAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + FPS = fpsAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitProcFormalParameter(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitProcFormalParameter(this, o); + } - public Identifier I; - public FormalParameterSequence FPS; + public Identifier I; + public FormalParameterSequence FPS; - @Override -public boolean equals(Object fpAST) { - if (fpAST instanceof ProcFormalParameter) { - ProcFormalParameter pfpAST = (ProcFormalParameter) fpAST; - return FPS.equals(pfpAST.FPS); - } else - return false; - } + @Override + public boolean equals(Object fpAST) { + if (fpAST instanceof ProcFormalParameter) { + ProcFormalParameter pfpAST = (ProcFormalParameter) fpAST; + return FPS.equals(pfpAST.FPS); + } else + return false; + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Program.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Program.java index 0a6a5bb..81425fa 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Program.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Program.java @@ -18,15 +18,15 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class Program extends AST { - public Program(Command cAST, SourcePosition thePosition) { - super(thePosition); - C = cAST; - } + public Program(Command cAST, SourcePosition thePosition) { + super(thePosition); + C = cAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitProgram(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitProgram(this, o); + } - public Command C; + public Command C; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordAggregate.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordAggregate.java index 9f2d923..79ea2d7 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordAggregate.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordAggregate.java @@ -18,10 +18,10 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public abstract class RecordAggregate extends AST { - public RecordAggregate(SourcePosition thePosition) { - super(thePosition); - type = null; - } + public RecordAggregate(SourcePosition thePosition) { + super(thePosition); + type = null; + } - public FieldTypeDenoter type; + public FieldTypeDenoter type; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordExpression.java index c762bc7..9a2d7cb 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordExpression.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordExpression.java @@ -18,15 +18,15 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class RecordExpression extends Expression { - public RecordExpression(RecordAggregate raAST, SourcePosition thePosition) { - super(thePosition); - RA = raAST; - } + public RecordExpression(RecordAggregate raAST, SourcePosition thePosition) { + super(thePosition); + RA = raAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitRecordExpression(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitRecordExpression(this, o); + } - public RecordAggregate RA; + public RecordAggregate RA; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordTypeDenoter.java index 6715b47..7e2b9ce 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordTypeDenoter.java @@ -18,25 +18,25 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class RecordTypeDenoter extends TypeDenoter { - public RecordTypeDenoter(FieldTypeDenoter ftAST, SourcePosition thePosition) { - super(thePosition); - FT = ftAST; - } + public RecordTypeDenoter(FieldTypeDenoter ftAST, SourcePosition thePosition) { + super(thePosition); + FT = ftAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitRecordTypeDenoter(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitRecordTypeDenoter(this, o); + } - @Override -public boolean equals(Object obj) { - if (obj != null && obj instanceof ErrorTypeDenoter) - return true; - else if (obj != null && obj instanceof RecordTypeDenoter) - return this.FT.equals(((RecordTypeDenoter) obj).FT); - else - return false; - } + @Override + public boolean equals(Object obj) { + if (obj != null && obj instanceof ErrorTypeDenoter) + return true; + else if (obj != null && obj instanceof RecordTypeDenoter) + return this.FT.equals(((RecordTypeDenoter) obj).FT); + else + return false; + } - public FieldTypeDenoter FT; + public FieldTypeDenoter FT; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialCommand.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialCommand.java index a679bb9..a31bd79 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialCommand.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialCommand.java @@ -18,16 +18,16 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class SequentialCommand extends Command { - public SequentialCommand(Command c1AST, Command c2AST, SourcePosition thePosition) { - super(thePosition); - C1 = c1AST; - C2 = c2AST; - } + public SequentialCommand(Command c1AST, Command c2AST, SourcePosition thePosition) { + super(thePosition); + C1 = c1AST; + C2 = c2AST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitSequentialCommand(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitSequentialCommand(this, o); + } - public Command C1, C2; + public Command C1, C2; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialDeclaration.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialDeclaration.java index 48db85b..ce650c9 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialDeclaration.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialDeclaration.java @@ -18,17 +18,16 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class SequentialDeclaration extends Declaration { - public SequentialDeclaration(Declaration d1AST, Declaration d2AST, - SourcePosition thePosition) { - super(thePosition); - D1 = d1AST; - D2 = d2AST; - } + public SequentialDeclaration(Declaration d1AST, Declaration d2AST, SourcePosition thePosition) { + super(thePosition); + D1 = d1AST; + D2 = d2AST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitSequentialDeclaration(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitSequentialDeclaration(this, o); + } - public Declaration D1, D2; + public Declaration D1, D2; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SimpleTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SimpleTypeDenoter.java index 6b5411b..51e83d2 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SimpleTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SimpleTypeDenoter.java @@ -18,20 +18,20 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class SimpleTypeDenoter extends TypeDenoter { - public SimpleTypeDenoter(Identifier iAST, SourcePosition thePosition) { - super(thePosition); - I = iAST; - } + public SimpleTypeDenoter(Identifier iAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitSimpleTypeDenoter(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitSimpleTypeDenoter(this, o); + } - @Override -public boolean equals(Object obj) { - return false; // should not happen - } + @Override + public boolean equals(Object obj) { + return false; // should not happen + } - public Identifier I; + public Identifier I; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SimpleVname.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SimpleVname.java index 2e4558c..a21f812 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SimpleVname.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SimpleVname.java @@ -18,15 +18,15 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class SimpleVname extends Vname { - public SimpleVname(Identifier iAST, SourcePosition thePosition) { - super(thePosition); - I = iAST; - } + public SimpleVname(Identifier iAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitSimpleVname(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitSimpleVname(this, o); + } - public Identifier I; + public Identifier I; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleActualParameterSequence.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleActualParameterSequence.java index 35e3150..bc068fa 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleActualParameterSequence.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleActualParameterSequence.java @@ -18,16 +18,15 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class SingleActualParameterSequence extends ActualParameterSequence { - public SingleActualParameterSequence(ActualParameter apAST, - SourcePosition thePosition) { - super(thePosition); - AP = apAST; - } + public SingleActualParameterSequence(ActualParameter apAST, SourcePosition thePosition) { + super(thePosition); + AP = apAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitSingleActualParameterSequence(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitSingleActualParameterSequence(this, o); + } - public ActualParameter AP; + public ActualParameter AP; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleArrayAggregate.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleArrayAggregate.java index 349daab..423ccde 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleArrayAggregate.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleArrayAggregate.java @@ -18,16 +18,15 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class SingleArrayAggregate extends ArrayAggregate { - public SingleArrayAggregate(Expression eAST, - SourcePosition thePosition) { - super(thePosition); - E = eAST; - } + public SingleArrayAggregate(Expression eAST, SourcePosition thePosition) { + super(thePosition); + E = eAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitSingleArrayAggregate(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitSingleArrayAggregate(this, o); + } - public Expression E; + public Expression E; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFieldTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFieldTypeDenoter.java index 7793102..25d19d1 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFieldTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFieldTypeDenoter.java @@ -18,28 +18,26 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class SingleFieldTypeDenoter extends FieldTypeDenoter { - public SingleFieldTypeDenoter(Identifier iAST, TypeDenoter tAST, - SourcePosition thePosition) { - super(thePosition); - I = iAST; - T = tAST; - } + public SingleFieldTypeDenoter(Identifier iAST, TypeDenoter tAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + T = tAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitSingleFieldTypeDenoter(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitSingleFieldTypeDenoter(this, o); + } - @Override -public boolean equals(Object obj) { - if (obj != null && obj instanceof SingleFieldTypeDenoter) { - SingleFieldTypeDenoter ft = (SingleFieldTypeDenoter) obj; - return (this.I.spelling.compareTo(ft.I.spelling) == 0) && - this.T.equals(ft.T); - } else - return false; - } + @Override + public boolean equals(Object obj) { + if (obj != null && obj instanceof SingleFieldTypeDenoter) { + SingleFieldTypeDenoter ft = (SingleFieldTypeDenoter) obj; + return (this.I.spelling.compareTo(ft.I.spelling) == 0) && this.T.equals(ft.T); + } else + return false; + } - public Identifier I; - public TypeDenoter T; + public Identifier I; + public TypeDenoter T; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFormalParameterSequence.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFormalParameterSequence.java index a6676fb..f06f9a4 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFormalParameterSequence.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFormalParameterSequence.java @@ -18,25 +18,24 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class SingleFormalParameterSequence extends FormalParameterSequence { - public SingleFormalParameterSequence(FormalParameter fpAST, - SourcePosition thePosition) { - super(thePosition); - FP = fpAST; - } + public SingleFormalParameterSequence(FormalParameter fpAST, SourcePosition thePosition) { + super(thePosition); + FP = fpAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitSingleFormalParameterSequence(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitSingleFormalParameterSequence(this, o); + } - @Override -public boolean equals(Object fpsAST) { - if (fpsAST instanceof SingleFormalParameterSequence) { - SingleFormalParameterSequence sfpsAST = (SingleFormalParameterSequence) fpsAST; - return FP.equals(sfpsAST.FP); - } else - return false; - } + @Override + public boolean equals(Object fpsAST) { + if (fpsAST instanceof SingleFormalParameterSequence) { + SingleFormalParameterSequence sfpsAST = (SingleFormalParameterSequence) fpsAST; + return FP.equals(sfpsAST.FP); + } else + return false; + } - public FormalParameter FP; + public FormalParameter FP; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleRecordAggregate.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleRecordAggregate.java index f03f3fc..d8d7ac0 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleRecordAggregate.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleRecordAggregate.java @@ -18,18 +18,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class SingleRecordAggregate extends RecordAggregate { - public SingleRecordAggregate(Identifier iAST, Expression eAST, - SourcePosition thePosition) { - super(thePosition); - I = iAST; - E = eAST; - } + public SingleRecordAggregate(Identifier iAST, Expression eAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + E = eAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitSingleRecordAggregate(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitSingleRecordAggregate(this, o); + } - public Identifier I; - public Expression E; + public Identifier I; + public Expression E; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SubscriptVname.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SubscriptVname.java index 84074e5..a03f7b9 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SubscriptVname.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SubscriptVname.java @@ -18,17 +18,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class SubscriptVname extends Vname { - public SubscriptVname(Vname vAST, Expression eAST, SourcePosition thePosition) { - super(thePosition); - V = vAST; - E = eAST; - } + public SubscriptVname(Vname vAST, Expression eAST, SourcePosition thePosition) { + super(thePosition); + V = vAST; + E = eAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitSubscriptVname(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitSubscriptVname(this, o); + } - public Expression E; - public Vname V; + public Expression E; + public Vname V; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Terminal.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Terminal.java index f14d753..dc67590 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Terminal.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Terminal.java @@ -18,10 +18,10 @@ import Triangle.SyntacticAnalyzer.SourcePosition; abstract public class Terminal extends AST { - public Terminal(String theSpelling, SourcePosition thePosition) { - super(thePosition); - spelling = theSpelling; - } + public Terminal(String theSpelling, SourcePosition thePosition) { + super(thePosition); + spelling = theSpelling; + } - public String spelling; + public String spelling; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/TypeDeclaration.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/TypeDeclaration.java index e168808..9870655 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/TypeDeclaration.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/TypeDeclaration.java @@ -18,18 +18,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class TypeDeclaration extends Declaration { - public TypeDeclaration(Identifier iAST, TypeDenoter tAST, - SourcePosition thePosition) { - super(thePosition); - I = iAST; - T = tAST; - } + public TypeDeclaration(Identifier iAST, TypeDenoter tAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + T = tAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitTypeDeclaration(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitTypeDeclaration(this, o); + } - public Identifier I; - public TypeDenoter T; + public Identifier I; + public TypeDenoter T; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/TypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/TypeDenoter.java index f7f2e0a..c4c09f4 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/TypeDenoter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/TypeDenoter.java @@ -18,11 +18,11 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public abstract class TypeDenoter extends AST { - public TypeDenoter(SourcePosition thePosition) { - super(thePosition); - } + public TypeDenoter(SourcePosition thePosition) { + super(thePosition); + } - @Override -public abstract boolean equals(Object obj); + @Override + public abstract boolean equals(Object obj); } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/UnaryExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/UnaryExpression.java index 717fb3e..27d15ab 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/UnaryExpression.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/UnaryExpression.java @@ -18,18 +18,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class UnaryExpression extends Expression { - public UnaryExpression(Operator oAST, Expression eAST, - SourcePosition thePosition) { - super(thePosition); - O = oAST; - E = eAST; - } + public UnaryExpression(Operator oAST, Expression eAST, SourcePosition thePosition) { + super(thePosition); + O = oAST; + E = eAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitUnaryExpression(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitUnaryExpression(this, o); + } - public Expression E; - public Operator O; + public Expression E; + public Operator O; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/UnaryOperatorDeclaration.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/UnaryOperatorDeclaration.java index 535b3ef..f8a0d3a 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/UnaryOperatorDeclaration.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/UnaryOperatorDeclaration.java @@ -18,19 +18,19 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class UnaryOperatorDeclaration extends Declaration { - public UnaryOperatorDeclaration(Operator oAST, TypeDenoter argAST, - TypeDenoter resultAST, SourcePosition thePosition) { - super(thePosition); - O = oAST; - ARG = argAST; - RES = resultAST; - } + public UnaryOperatorDeclaration(Operator oAST, TypeDenoter argAST, TypeDenoter resultAST, + SourcePosition thePosition) { + super(thePosition); + O = oAST; + ARG = argAST; + RES = resultAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitUnaryOperatorDeclaration(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitUnaryOperatorDeclaration(this, o); + } - public Operator O; - public TypeDenoter ARG, RES; + public Operator O; + public TypeDenoter ARG, RES; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarActualParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarActualParameter.java index c4398dc..48d86eb 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarActualParameter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarActualParameter.java @@ -18,15 +18,15 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class VarActualParameter extends ActualParameter { - public VarActualParameter(Vname vAST, SourcePosition thePosition) { - super(thePosition); - V = vAST; - } + public VarActualParameter(Vname vAST, SourcePosition thePosition) { + super(thePosition); + V = vAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitVarActualParameter(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitVarActualParameter(this, o); + } - public Vname V; + public Vname V; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarDeclaration.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarDeclaration.java index 8a933f8..227e867 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarDeclaration.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarDeclaration.java @@ -18,18 +18,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class VarDeclaration extends Declaration { - public VarDeclaration(Identifier iAST, TypeDenoter tAST, - SourcePosition thePosition) { - super(thePosition); - I = iAST; - T = tAST; - } + public VarDeclaration(Identifier iAST, TypeDenoter tAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + T = tAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitVarDeclaration(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitVarDeclaration(this, o); + } - public Identifier I; - public TypeDenoter T; + public Identifier I; + public TypeDenoter T; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarFormalParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarFormalParameter.java index 083ae3e..5366d59 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarFormalParameter.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarFormalParameter.java @@ -18,27 +18,26 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class VarFormalParameter extends FormalParameter { - public VarFormalParameter(Identifier iAST, TypeDenoter tAST, - SourcePosition thePosition) { - super(thePosition); - I = iAST; - T = tAST; - } + public VarFormalParameter(Identifier iAST, TypeDenoter tAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + T = tAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitVarFormalParameter(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitVarFormalParameter(this, o); + } - public Identifier I; - public TypeDenoter T; + public Identifier I; + public TypeDenoter T; - @Override -public boolean equals(Object fpAST) { - if (fpAST instanceof VarFormalParameter) { - VarFormalParameter vfpAST = (VarFormalParameter) fpAST; - return T.equals(vfpAST.T); - } else - return false; - } + @Override + public boolean equals(Object fpAST) { + if (fpAST instanceof VarFormalParameter) { + VarFormalParameter vfpAST = (VarFormalParameter) fpAST; + return T.equals(vfpAST.T); + } else + return false; + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Visitor.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Visitor.java index b1be8a1..53993fa 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Visitor.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Visitor.java @@ -16,139 +16,139 @@ package Triangle.AbstractSyntaxTrees; public interface Visitor { - // Commands - public abstract Object visitAssignCommand(AssignCommand ast, Object o); + // Commands + public abstract Object visitAssignCommand(AssignCommand ast, Object o); - public abstract Object visitCallCommand(CallCommand ast, Object o); + public abstract Object visitCallCommand(CallCommand ast, Object o); - public abstract Object visitEmptyCommand(EmptyCommand ast, Object o); + public abstract Object visitEmptyCommand(EmptyCommand ast, Object o); - public abstract Object visitIfCommand(IfCommand ast, Object o); + public abstract Object visitIfCommand(IfCommand ast, Object o); - public abstract Object visitLetCommand(LetCommand ast, Object o); + public abstract Object visitLetCommand(LetCommand ast, Object o); - public abstract Object visitSequentialCommand(SequentialCommand ast, Object o); + public abstract Object visitSequentialCommand(SequentialCommand ast, Object o); - public abstract Object visitWhileCommand(WhileCommand ast, Object o); + public abstract Object visitWhileCommand(WhileCommand ast, Object o); - // Expressions - public abstract Object visitArrayExpression(ArrayExpression ast, Object o); + // Expressions + public abstract Object visitArrayExpression(ArrayExpression ast, Object o); - public abstract Object visitBinaryExpression(BinaryExpression ast, Object o); + public abstract Object visitBinaryExpression(BinaryExpression ast, Object o); - public abstract Object visitCallExpression(CallExpression ast, Object o); + public abstract Object visitCallExpression(CallExpression ast, Object o); - public abstract Object visitCharacterExpression(CharacterExpression ast, Object o); + public abstract Object visitCharacterExpression(CharacterExpression ast, Object o); - public abstract Object visitEmptyExpression(EmptyExpression ast, Object o); + public abstract Object visitEmptyExpression(EmptyExpression ast, Object o); - public abstract Object visitIfExpression(IfExpression ast, Object o); + public abstract Object visitIfExpression(IfExpression ast, Object o); - public abstract Object visitIntegerExpression(IntegerExpression ast, Object o); + public abstract Object visitIntegerExpression(IntegerExpression ast, Object o); - public abstract Object visitLetExpression(LetExpression ast, Object o); + public abstract Object visitLetExpression(LetExpression ast, Object o); - public abstract Object visitRecordExpression(RecordExpression ast, Object o); + public abstract Object visitRecordExpression(RecordExpression ast, Object o); - public abstract Object visitUnaryExpression(UnaryExpression ast, Object o); + public abstract Object visitUnaryExpression(UnaryExpression ast, Object o); - public abstract Object visitVnameExpression(VnameExpression ast, Object o); + public abstract Object visitVnameExpression(VnameExpression ast, Object o); - // Declarations - public abstract Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Object o); + // Declarations + public abstract Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Object o); - public abstract Object visitConstDeclaration(ConstDeclaration ast, Object o); + public abstract Object visitConstDeclaration(ConstDeclaration ast, Object o); - public abstract Object visitFuncDeclaration(FuncDeclaration ast, Object o); + public abstract Object visitFuncDeclaration(FuncDeclaration ast, Object o); - public abstract Object visitProcDeclaration(ProcDeclaration ast, Object o); + public abstract Object visitProcDeclaration(ProcDeclaration ast, Object o); - public abstract Object visitSequentialDeclaration(SequentialDeclaration ast, Object o); + public abstract Object visitSequentialDeclaration(SequentialDeclaration ast, Object o); - public abstract Object visitTypeDeclaration(TypeDeclaration ast, Object o); + public abstract Object visitTypeDeclaration(TypeDeclaration ast, Object o); - public abstract Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Object o); + public abstract Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Object o); - public abstract Object visitVarDeclaration(VarDeclaration ast, Object o); + public abstract Object visitVarDeclaration(VarDeclaration ast, Object o); - // Array Aggregates - public abstract Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, Object o); + // Array Aggregates + public abstract Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, Object o); - public abstract Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object o); + public abstract Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object o); - // Record Aggregates - public abstract Object visitMultipleRecordAggregate(MultipleRecordAggregate ast, Object o); + // Record Aggregates + public abstract Object visitMultipleRecordAggregate(MultipleRecordAggregate ast, Object o); - public abstract Object visitSingleRecordAggregate(SingleRecordAggregate ast, Object o); + public abstract Object visitSingleRecordAggregate(SingleRecordAggregate ast, Object o); - // Formal Parameters - public abstract Object visitConstFormalParameter(ConstFormalParameter ast, Object o); + // Formal Parameters + public abstract Object visitConstFormalParameter(ConstFormalParameter ast, Object o); - public abstract Object visitFuncFormalParameter(FuncFormalParameter ast, Object o); + public abstract Object visitFuncFormalParameter(FuncFormalParameter ast, Object o); - public abstract Object visitProcFormalParameter(ProcFormalParameter ast, Object o); + public abstract Object visitProcFormalParameter(ProcFormalParameter ast, Object o); - public abstract Object visitVarFormalParameter(VarFormalParameter ast, Object o); + public abstract Object visitVarFormalParameter(VarFormalParameter ast, Object o); - public abstract Object visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Object o); + public abstract Object visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Object o); - public abstract Object visitMultipleFormalParameterSequence(MultipleFormalParameterSequence ast, Object o); + public abstract Object visitMultipleFormalParameterSequence(MultipleFormalParameterSequence ast, Object o); - public abstract Object visitSingleFormalParameterSequence(SingleFormalParameterSequence ast, Object o); + public abstract Object visitSingleFormalParameterSequence(SingleFormalParameterSequence ast, Object o); - // Actual Parameters - public abstract Object visitConstActualParameter(ConstActualParameter ast, Object o); + // Actual Parameters + public abstract Object visitConstActualParameter(ConstActualParameter ast, Object o); - public abstract Object visitFuncActualParameter(FuncActualParameter ast, Object o); + public abstract Object visitFuncActualParameter(FuncActualParameter ast, Object o); - public abstract Object visitProcActualParameter(ProcActualParameter ast, Object o); + public abstract Object visitProcActualParameter(ProcActualParameter ast, Object o); - public abstract Object visitVarActualParameter(VarActualParameter ast, Object o); + public abstract Object visitVarActualParameter(VarActualParameter ast, Object o); - public abstract Object visitEmptyActualParameterSequence(EmptyActualParameterSequence ast, Object o); + public abstract Object visitEmptyActualParameterSequence(EmptyActualParameterSequence ast, Object o); - public abstract Object visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, Object o); + public abstract Object visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, Object o); - public abstract Object visitSingleActualParameterSequence(SingleActualParameterSequence ast, Object o); + public abstract Object visitSingleActualParameterSequence(SingleActualParameterSequence ast, Object o); - // Type Denoters - public abstract Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object o); + // Type Denoters + public abstract Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object o); - public abstract Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object o); + public abstract Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object o); - public abstract Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object o); + public abstract Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object o); - public abstract Object visitCharTypeDenoter(CharTypeDenoter ast, Object o); + public abstract Object visitCharTypeDenoter(CharTypeDenoter ast, Object o); - public abstract Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object o); + public abstract Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object o); - public abstract Object visitSimpleTypeDenoter(SimpleTypeDenoter ast, Object o); + public abstract Object visitSimpleTypeDenoter(SimpleTypeDenoter ast, Object o); - public abstract Object visitIntTypeDenoter(IntTypeDenoter ast, Object o); + public abstract Object visitIntTypeDenoter(IntTypeDenoter ast, Object o); - public abstract Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object o); + public abstract Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object o); - public abstract Object visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, Object o); + public abstract Object visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, Object o); - public abstract Object visitSingleFieldTypeDenoter(SingleFieldTypeDenoter ast, Object o); + public abstract Object visitSingleFieldTypeDenoter(SingleFieldTypeDenoter ast, Object o); - // Literals, Identifiers and Operators - public abstract Object visitCharacterLiteral(CharacterLiteral ast, Object o); + // Literals, Identifiers and Operators + public abstract Object visitCharacterLiteral(CharacterLiteral ast, Object o); - public abstract Object visitIdentifier(Identifier ast, Object o); + public abstract Object visitIdentifier(Identifier ast, Object o); - public abstract Object visitIntegerLiteral(IntegerLiteral ast, Object o); + public abstract Object visitIntegerLiteral(IntegerLiteral ast, Object o); - public abstract Object visitOperator(Operator ast, Object o); + public abstract Object visitOperator(Operator ast, Object o); - // Value-or-variable names - public abstract Object visitDotVname(DotVname ast, Object o); + // Value-or-variable names + public abstract Object visitDotVname(DotVname ast, Object o); - public abstract Object visitSimpleVname(SimpleVname ast, Object o); + public abstract Object visitSimpleVname(SimpleVname ast, Object o); - public abstract Object visitSubscriptVname(SubscriptVname ast, Object o); + public abstract Object visitSubscriptVname(SubscriptVname ast, Object o); - // Programs - public abstract Object visitProgram(Program ast, Object o); + // Programs + public abstract Object visitProgram(Program ast, Object o); } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Vname.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Vname.java index 9c00d53..97feff4 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Vname.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Vname.java @@ -18,13 +18,13 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public abstract class Vname extends AST { - public Vname(SourcePosition thePosition) { - super(thePosition); - variable = false; - type = null; - } + public Vname(SourcePosition thePosition) { + super(thePosition); + variable = false; + type = null; + } - public boolean variable, indexed; - public int offset; - public TypeDenoter type; + public boolean variable, indexed; + public int offset; + public TypeDenoter type; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VnameExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VnameExpression.java index 9cbe87a..a92e6b0 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VnameExpression.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VnameExpression.java @@ -18,15 +18,15 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class VnameExpression extends Expression { - public VnameExpression(Vname vAST, SourcePosition thePosition) { - super(thePosition); - V = vAST; - } + public VnameExpression(Vname vAST, SourcePosition thePosition) { + super(thePosition); + V = vAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitVnameExpression(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitVnameExpression(this, o); + } - public Vname V; + public Vname V; } diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/WhileCommand.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/WhileCommand.java index 9dd2f35..6c37e9b 100644 --- a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/WhileCommand.java +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/WhileCommand.java @@ -18,17 +18,17 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class WhileCommand extends Command { - public WhileCommand(Expression eAST, Command cAST, SourcePosition thePosition) { - super(thePosition); - E = eAST; - C = cAST; - } + public WhileCommand(Expression eAST, Command cAST, SourcePosition thePosition) { + super(thePosition); + E = eAST; + C = cAST; + } - @Override -public Object visit(Visitor v, Object o) { - return v.visitWhileCommand(this, o); - } + @Override + public Object visit(Visitor v, Object o) { + return v.visitWhileCommand(this, o); + } - public Expression E; - public Command C; + public Expression E; + public Command C; } diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Encoder.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Encoder.java index 04a8d73..55aae1d 100644 --- a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Encoder.java +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Encoder.java @@ -92,954 +92,921 @@ import Triangle.AbstractSyntaxTrees.WhileCommand; public final class Encoder implements Visitor { - // Commands - @Override -public Object visitAssignCommand(AssignCommand ast, Object o) { - Frame frame = (Frame) o; - Integer valSize = (Integer) ast.E.visit(this, frame); - encodeStore(ast.V, new Frame(frame, valSize.intValue()), - valSize.intValue()); - return null; - } - - @Override -public Object visitCallCommand(CallCommand ast, Object o) { - Frame frame = (Frame) o; - Integer argsSize = (Integer) ast.APS.visit(this, frame); - ast.I.visit(this, new Frame(frame.level, argsSize)); - return null; - } - - @Override -public Object visitEmptyCommand(EmptyCommand ast, Object o) { - return null; - } - - @Override -public Object visitIfCommand(IfCommand ast, Object o) { - Frame frame = (Frame) o; - int jumpifAddr, jumpAddr; - - Integer valSize = (Integer) ast.E.visit(this, frame); - jumpifAddr = nextInstrAddr; - emit(Machine.JUMPIFop, Machine.falseRep, Machine.CBr, 0); - ast.C1.visit(this, frame); - jumpAddr = nextInstrAddr; - emit(Machine.JUMPop, 0, Machine.CBr, 0); - patch(jumpifAddr, nextInstrAddr); - ast.C2.visit(this, frame); - patch(jumpAddr, nextInstrAddr); - return null; - } - - @Override -public Object visitLetCommand(LetCommand ast, Object o) { - Frame frame = (Frame) o; - int extraSize = ((Integer) ast.D.visit(this, frame)).intValue(); - ast.C.visit(this, new Frame(frame, extraSize)); - if (extraSize > 0) - emit(Machine.POPop, 0, 0, extraSize); - return null; - } - - @Override -public Object visitSequentialCommand(SequentialCommand ast, Object o) { - ast.C1.visit(this, o); - ast.C2.visit(this, o); - return null; - } - - @Override -public Object visitWhileCommand(WhileCommand ast, Object o) { - Frame frame = (Frame) o; - int jumpAddr, loopAddr; - - jumpAddr = nextInstrAddr; - emit(Machine.JUMPop, 0, Machine.CBr, 0); - loopAddr = nextInstrAddr; - ast.C.visit(this, frame); - patch(jumpAddr, nextInstrAddr); - ast.E.visit(this, frame); - emit(Machine.JUMPIFop, Machine.trueRep, Machine.CBr, loopAddr); - return null; - } - - // Expressions - @Override -public Object visitArrayExpression(ArrayExpression ast, Object o) { - ast.type.visit(this, null); - return ast.AA.visit(this, o); - } - - @Override -public Object visitBinaryExpression(BinaryExpression ast, Object o) { - Frame frame = (Frame) o; - Integer valSize = (Integer) ast.type.visit(this, null); - int valSize1 = ((Integer) ast.E1.visit(this, frame)).intValue(); - Frame frame1 = new Frame(frame, valSize1); - int valSize2 = ((Integer) ast.E2.visit(this, frame1)).intValue(); - Frame frame2 = new Frame(frame.level, valSize1 + valSize2); - ast.O.visit(this, frame2); - return valSize; - } - - @Override -public Object visitCallExpression(CallExpression ast, Object o) { - Frame frame = (Frame) o; - Integer valSize = (Integer) ast.type.visit(this, null); - Integer argsSize = (Integer) ast.APS.visit(this, frame); - ast.I.visit(this, new Frame(frame.level, argsSize)); - return valSize; - } - - @Override -public Object visitCharacterExpression(CharacterExpression ast, - Object o) { - Frame frame = (Frame) o; - Integer valSize = (Integer) ast.type.visit(this, null); - emit(Machine.LOADLop, 0, 0, ast.CL.spelling.charAt(1)); - return valSize; - } - - @Override -public Object visitEmptyExpression(EmptyExpression ast, Object o) { - return Integer.valueOf(0); - } - - @Override -public Object visitIfExpression(IfExpression ast, Object o) { - Frame frame = (Frame) o; - Integer valSize; - int jumpifAddr, jumpAddr; - - ast.type.visit(this, null); - ast.E1.visit(this, frame); - jumpifAddr = nextInstrAddr; - emit(Machine.JUMPIFop, Machine.falseRep, Machine.CBr, 0); - valSize = (Integer) ast.E2.visit(this, frame); - jumpAddr = nextInstrAddr; - emit(Machine.JUMPop, 0, Machine.CBr, 0); - patch(jumpifAddr, nextInstrAddr); - valSize = (Integer) ast.E3.visit(this, frame); - patch(jumpAddr, nextInstrAddr); - return valSize; - } - - @Override -public Object visitIntegerExpression(IntegerExpression ast, Object o) { - Frame frame = (Frame) o; - Integer valSize = (Integer) ast.type.visit(this, null); - emit(Machine.LOADLop, 0, 0, Integer.parseInt(ast.IL.spelling)); - return valSize; - } - - @Override -public Object visitLetExpression(LetExpression ast, Object o) { - Frame frame = (Frame) o; - ast.type.visit(this, null); - int extraSize = ((Integer) ast.D.visit(this, frame)).intValue(); - Frame frame1 = new Frame(frame, extraSize); - Integer valSize = (Integer) ast.E.visit(this, frame1); - if (extraSize > 0) - emit(Machine.POPop, valSize.intValue(), 0, extraSize); - return valSize; - } - - @Override -public Object visitRecordExpression(RecordExpression ast, Object o) { - ast.type.visit(this, null); - return ast.RA.visit(this, o); - } - - @Override -public Object visitUnaryExpression(UnaryExpression ast, Object o) { - Frame frame = (Frame) o; - Integer valSize = (Integer) ast.type.visit(this, null); - ast.E.visit(this, frame); - ast.O.visit(this, new Frame(frame.level, valSize.intValue())); - return valSize; - } - - @Override -public Object visitVnameExpression(VnameExpression ast, Object o) { - Frame frame = (Frame) o; - Integer valSize = (Integer) ast.type.visit(this, null); - encodeFetch(ast.V, frame, valSize.intValue()); - return valSize; - } - - // Declarations - @Override -public Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, - Object o) { - return Integer.valueOf(0); - } - - @Override -public Object visitConstDeclaration(ConstDeclaration ast, Object o) { - Frame frame = (Frame) o; - int extraSize = 0; - - if (ast.E instanceof CharacterExpression) { - CharacterLiteral CL = ((CharacterExpression) ast.E).CL; - ast.entity = new KnownValue(Machine.characterSize, - characterValuation(CL.spelling)); - } else if (ast.E instanceof IntegerExpression) { - IntegerLiteral IL = ((IntegerExpression) ast.E).IL; - ast.entity = new KnownValue(Machine.integerSize, - Integer.parseInt(IL.spelling)); - } else { - int valSize = ((Integer) ast.E.visit(this, frame)).intValue(); - ast.entity = new UnknownValue(valSize, frame.level, frame.size); - extraSize = valSize; - } - writeTableDetails(ast); - return Integer.valueOf(extraSize); - } - - @Override -public Object visitFuncDeclaration(FuncDeclaration ast, Object o) { - Frame frame = (Frame) o; - int jumpAddr = nextInstrAddr; - int argsSize = 0, valSize = 0; - - emit(Machine.JUMPop, 0, Machine.CBr, 0); - ast.entity = new KnownRoutine(Machine.closureSize, frame.level, nextInstrAddr); - writeTableDetails(ast); - if (frame.level == Machine.maxRoutineLevel) - reporter.reportRestriction("can't nest routines more than 7 deep"); - else { - Frame frame1 = new Frame(frame.level + 1, 0); - argsSize = ((Integer) ast.FPS.visit(this, frame1)).intValue(); - Frame frame2 = new Frame(frame.level + 1, Machine.linkDataSize); - valSize = ((Integer) ast.E.visit(this, frame2)).intValue(); - } - emit(Machine.RETURNop, valSize, 0, argsSize); - patch(jumpAddr, nextInstrAddr); - return Integer.valueOf(0); - } - - @Override -public Object visitProcDeclaration(ProcDeclaration ast, Object o) { - Frame frame = (Frame) o; - int jumpAddr = nextInstrAddr; - int argsSize = 0; - - emit(Machine.JUMPop, 0, Machine.CBr, 0); - ast.entity = new KnownRoutine(Machine.closureSize, frame.level, - nextInstrAddr); - writeTableDetails(ast); - if (frame.level == Machine.maxRoutineLevel) - reporter.reportRestriction("can't nest routines so deeply"); - else { - Frame frame1 = new Frame(frame.level + 1, 0); - argsSize = ((Integer) ast.FPS.visit(this, frame1)).intValue(); - Frame frame2 = new Frame(frame.level + 1, Machine.linkDataSize); - ast.C.visit(this, frame2); - } - emit(Machine.RETURNop, 0, 0, argsSize); - patch(jumpAddr, nextInstrAddr); - return Integer.valueOf(0); - } - - @Override -public Object visitSequentialDeclaration(SequentialDeclaration ast, Object o) { - Frame frame = (Frame) o; - int extraSize1, extraSize2; - - extraSize1 = ((Integer) ast.D1.visit(this, frame)).intValue(); - Frame frame1 = new Frame(frame, extraSize1); - extraSize2 = ((Integer) ast.D2.visit(this, frame1)).intValue(); - return Integer.valueOf(extraSize1 + extraSize2); - } - - @Override -public Object visitTypeDeclaration(TypeDeclaration ast, Object o) { - // just to ensure the type's representation is decided - ast.T.visit(this, null); - return Integer.valueOf(0); - } - - @Override -public Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, - Object o) { - return Integer.valueOf(0); - } - - @Override -public Object visitVarDeclaration(VarDeclaration ast, Object o) { - Frame frame = (Frame) o; - int extraSize; - - extraSize = ((Integer) ast.T.visit(this, null)).intValue(); - emit(Machine.PUSHop, 0, 0, extraSize); - ast.entity = new KnownAddress(Machine.addressSize, frame.level, frame.size); - writeTableDetails(ast); - return Integer.valueOf(extraSize); - } - - // Array Aggregates - @Override -public Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, - Object o) { - Frame frame = (Frame) o; - int elemSize = ((Integer) ast.E.visit(this, frame)).intValue(); - Frame frame1 = new Frame(frame, elemSize); - int arraySize = ((Integer) ast.AA.visit(this, frame1)).intValue(); - return Integer.valueOf(elemSize + arraySize); - } - - @Override -public Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object o) { - return ast.E.visit(this, o); - } - - // Record Aggregates - @Override -public Object visitMultipleRecordAggregate(MultipleRecordAggregate ast, - Object o) { - Frame frame = (Frame) o; - int fieldSize = ((Integer) ast.E.visit(this, frame)).intValue(); - Frame frame1 = new Frame(frame, fieldSize); - int recordSize = ((Integer) ast.RA.visit(this, frame1)).intValue(); - return Integer.valueOf(fieldSize + recordSize); - } - - @Override -public Object visitSingleRecordAggregate(SingleRecordAggregate ast, - Object o) { - return ast.E.visit(this, o); - } - - // Formal Parameters - @Override -public Object visitConstFormalParameter(ConstFormalParameter ast, Object o) { - Frame frame = (Frame) o; - int valSize = ((Integer) ast.T.visit(this, null)).intValue(); - ast.entity = new UnknownValue(valSize, frame.level, -frame.size - valSize); - writeTableDetails(ast); - return Integer.valueOf(valSize); - } - - @Override -public Object visitFuncFormalParameter(FuncFormalParameter ast, Object o) { - Frame frame = (Frame) o; - int argsSize = Machine.closureSize; - ast.entity = new UnknownRoutine(Machine.closureSize, frame.level, - -frame.size - argsSize); - writeTableDetails(ast); - return Integer.valueOf(argsSize); - } - - @Override -public Object visitProcFormalParameter(ProcFormalParameter ast, Object o) { - Frame frame = (Frame) o; - int argsSize = Machine.closureSize; - ast.entity = new UnknownRoutine(Machine.closureSize, frame.level, - -frame.size - argsSize); - writeTableDetails(ast); - return Integer.valueOf(argsSize); - } - - @Override -public Object visitVarFormalParameter(VarFormalParameter ast, Object o) { - Frame frame = (Frame) o; - ast.T.visit(this, null); - ast.entity = new UnknownAddress(Machine.addressSize, frame.level, - -frame.size - Machine.addressSize); - writeTableDetails(ast); - return Integer.valueOf(Machine.addressSize); - } - - @Override -public Object visitEmptyFormalParameterSequence( - EmptyFormalParameterSequence ast, Object o) { - return Integer.valueOf(0); - } - - @Override -public Object visitMultipleFormalParameterSequence( - MultipleFormalParameterSequence ast, Object o) { - Frame frame = (Frame) o; - int argsSize1 = ((Integer) ast.FPS.visit(this, frame)).intValue(); - Frame frame1 = new Frame(frame, argsSize1); - int argsSize2 = ((Integer) ast.FP.visit(this, frame1)).intValue(); - return Integer.valueOf(argsSize1 + argsSize2); - } - - @Override -public Object visitSingleFormalParameterSequence( - SingleFormalParameterSequence ast, Object o) { - return ast.FP.visit(this, o); - } - - // Actual Parameters - @Override -public Object visitConstActualParameter(ConstActualParameter ast, Object o) { - return ast.E.visit(this, o); - } - - @Override -public Object visitFuncActualParameter(FuncActualParameter ast, Object o) { - Frame frame = (Frame) o; - if (ast.I.decl.entity instanceof KnownRoutine) { - ObjectAddress address = ((KnownRoutine) ast.I.decl.entity).address; - // static link, code address - emit(Machine.LOADAop, 0, displayRegister(frame.level, address.level), 0); - emit(Machine.LOADAop, 0, Machine.CBr, address.displacement); - } else if (ast.I.decl.entity instanceof UnknownRoutine) { - ObjectAddress address = ((UnknownRoutine) ast.I.decl.entity).address; - emit(Machine.LOADop, Machine.closureSize, displayRegister(frame.level, - address.level), address.displacement); - } else if (ast.I.decl.entity instanceof PrimitiveRoutine) { - int displacement = ((PrimitiveRoutine) ast.I.decl.entity).displacement; - // static link, code address - emit(Machine.LOADAop, 0, Machine.SBr, 0); - emit(Machine.LOADAop, 0, Machine.PBr, displacement); - } - return Integer.valueOf(Machine.closureSize); - } - - @Override -public Object visitProcActualParameter(ProcActualParameter ast, Object o) { - Frame frame = (Frame) o; - if (ast.I.decl.entity instanceof KnownRoutine) { - ObjectAddress address = ((KnownRoutine) ast.I.decl.entity).address; - // static link, code address - emit(Machine.LOADAop, 0, displayRegister(frame.level, address.level), 0); - emit(Machine.LOADAop, 0, Machine.CBr, address.displacement); - } else if (ast.I.decl.entity instanceof UnknownRoutine) { - ObjectAddress address = ((UnknownRoutine) ast.I.decl.entity).address; - emit(Machine.LOADop, Machine.closureSize, displayRegister(frame.level, - address.level), address.displacement); - } else if (ast.I.decl.entity instanceof PrimitiveRoutine) { - int displacement = ((PrimitiveRoutine) ast.I.decl.entity).displacement; - // static link, code address - emit(Machine.LOADAop, 0, Machine.SBr, 0); - emit(Machine.LOADAop, 0, Machine.PBr, displacement); - } - return Integer.valueOf(Machine.closureSize); - } - - @Override -public Object visitVarActualParameter(VarActualParameter ast, Object o) { - encodeFetchAddress(ast.V, (Frame) o); - return Integer.valueOf(Machine.addressSize); - } - - @Override -public Object visitEmptyActualParameterSequence( - EmptyActualParameterSequence ast, Object o) { - return Integer.valueOf(0); - } - - @Override -public Object visitMultipleActualParameterSequence( - MultipleActualParameterSequence ast, Object o) { - Frame frame = (Frame) o; - int argsSize1 = ((Integer) ast.AP.visit(this, frame)).intValue(); - Frame frame1 = new Frame(frame, argsSize1); - int argsSize2 = ((Integer) ast.APS.visit(this, frame1)).intValue(); - return Integer.valueOf(argsSize1 + argsSize2); - } - - @Override -public Object visitSingleActualParameterSequence( - SingleActualParameterSequence ast, Object o) { - return ast.AP.visit(this, o); - } - - // Type Denoters - @Override -public Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object o) { - return Integer.valueOf(0); - } - - @Override -public Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object o) { - int typeSize; - if (ast.entity == null) { - int elemSize = ((Integer) ast.T.visit(this, null)).intValue(); - typeSize = Integer.parseInt(ast.IL.spelling) * elemSize; - ast.entity = new TypeRepresentation(typeSize); - writeTableDetails(ast); - } else - typeSize = ast.entity.size; - return Integer.valueOf(typeSize); - } - - @Override -public Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object o) { - if (ast.entity == null) { - ast.entity = new TypeRepresentation(Machine.booleanSize); - writeTableDetails(ast); - } - return Integer.valueOf(Machine.booleanSize); - } - - @Override -public Object visitCharTypeDenoter(CharTypeDenoter ast, Object o) { - if (ast.entity == null) { - ast.entity = new TypeRepresentation(Machine.characterSize); - writeTableDetails(ast); - } - return Integer.valueOf(Machine.characterSize); - } - - @Override -public Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object o) { - return Integer.valueOf(0); - } - - @Override -public Object visitSimpleTypeDenoter(SimpleTypeDenoter ast, - Object o) { - return Integer.valueOf(0); - } - - @Override -public Object visitIntTypeDenoter(IntTypeDenoter ast, Object o) { - if (ast.entity == null) { - ast.entity = new TypeRepresentation(Machine.integerSize); - writeTableDetails(ast); - } - return Integer.valueOf(Machine.integerSize); - } - - @Override -public Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object o) { - int typeSize; - if (ast.entity == null) { - typeSize = ((Integer) ast.FT.visit(this, Integer.valueOf(0))).intValue(); - ast.entity = new TypeRepresentation(typeSize); - writeTableDetails(ast); - } else - typeSize = ast.entity.size; - return Integer.valueOf(typeSize); - } - - @Override -public Object visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, - Object o) { - int offset = ((Integer) o).intValue(); - int fieldSize; - - if (ast.entity == null) { - fieldSize = ((Integer) ast.T.visit(this, null)).intValue(); - ast.entity = new Field(fieldSize, offset); - writeTableDetails(ast); - } else - fieldSize = ast.entity.size; - - Integer offset1 = Integer.valueOf(offset + fieldSize); - int recSize = ((Integer) ast.FT.visit(this, offset1)).intValue(); - return Integer.valueOf(fieldSize + recSize); - } - - @Override -public Object visitSingleFieldTypeDenoter(SingleFieldTypeDenoter ast, - Object o) { - int offset = ((Integer) o).intValue(); - int fieldSize; - - if (ast.entity == null) { - fieldSize = ((Integer) ast.T.visit(this, null)).intValue(); - ast.entity = new Field(fieldSize, offset); - writeTableDetails(ast); - } else - fieldSize = ast.entity.size; - - return Integer.valueOf(fieldSize); - } - - // Literals, Identifiers and Operators - @Override -public Object visitCharacterLiteral(CharacterLiteral ast, Object o) { - return null; - } - - @Override -public Object visitIdentifier(Identifier ast, Object o) { - Frame frame = (Frame) o; - if (ast.decl.entity instanceof KnownRoutine) { - ObjectAddress address = ((KnownRoutine) ast.decl.entity).address; - emit(Machine.CALLop, displayRegister(frame.level, address.level), - Machine.CBr, address.displacement); - } else if (ast.decl.entity instanceof UnknownRoutine) { - ObjectAddress address = ((UnknownRoutine) ast.decl.entity).address; - emit(Machine.LOADop, Machine.closureSize, displayRegister(frame.level, - address.level), address.displacement); - emit(Machine.CALLIop, 0, 0, 0); - } else if (ast.decl.entity instanceof PrimitiveRoutine) { - int displacement = ((PrimitiveRoutine) ast.decl.entity).displacement; - if (displacement != Machine.idDisplacement) - emit(Machine.CALLop, Machine.SBr, Machine.PBr, displacement); - } else if (ast.decl.entity instanceof EqualityRoutine) { // "=" or "\=" - int displacement = ((EqualityRoutine) ast.decl.entity).displacement; - emit(Machine.LOADLop, 0, 0, frame.size / 2); - emit(Machine.CALLop, Machine.SBr, Machine.PBr, displacement); - } - return null; - } - - @Override -public Object visitIntegerLiteral(IntegerLiteral ast, Object o) { - return null; - } - - @Override -public Object visitOperator(Operator ast, Object o) { - Frame frame = (Frame) o; - if (ast.decl.entity instanceof KnownRoutine) { - ObjectAddress address = ((KnownRoutine) ast.decl.entity).address; - emit(Machine.CALLop, displayRegister(frame.level, address.level), - Machine.CBr, address.displacement); - } else if (ast.decl.entity instanceof UnknownRoutine) { - ObjectAddress address = ((UnknownRoutine) ast.decl.entity).address; - emit(Machine.LOADop, Machine.closureSize, displayRegister(frame.level, - address.level), address.displacement); - emit(Machine.CALLIop, 0, 0, 0); - } else if (ast.decl.entity instanceof PrimitiveRoutine) { - int displacement = ((PrimitiveRoutine) ast.decl.entity).displacement; - if (displacement != Machine.idDisplacement) - emit(Machine.CALLop, Machine.SBr, Machine.PBr, displacement); - } else if (ast.decl.entity instanceof EqualityRoutine) { // "=" or "\=" - int displacement = ((EqualityRoutine) ast.decl.entity).displacement; - emit(Machine.LOADLop, 0, 0, frame.size / 2); - emit(Machine.CALLop, Machine.SBr, Machine.PBr, displacement); - } - return null; - } - - // Value-or-variable names - @Override -public Object visitDotVname(DotVname ast, Object o) { - Frame frame = (Frame) o; - RuntimeEntity baseObject = (RuntimeEntity) ast.V.visit(this, frame); - ast.offset = ast.V.offset + ((Field) ast.I.decl.entity).fieldOffset; - // I.decl points to the appropriate record field - ast.indexed = ast.V.indexed; - return baseObject; - } - - @Override -public Object visitSimpleVname(SimpleVname ast, Object o) { - ast.offset = 0; - ast.indexed = false; - return ast.I.decl.entity; - } - - @Override -public Object visitSubscriptVname(SubscriptVname ast, Object o) { - Frame frame = (Frame) o; - RuntimeEntity baseObject; - int elemSize, indexSize; - - baseObject = (RuntimeEntity) ast.V.visit(this, frame); - ast.offset = ast.V.offset; - ast.indexed = ast.V.indexed; - elemSize = ((Integer) ast.type.visit(this, null)).intValue(); - if (ast.E instanceof IntegerExpression) { - IntegerLiteral IL = ((IntegerExpression) ast.E).IL; - ast.offset = ast.offset + Integer.parseInt(IL.spelling) * elemSize; - } else { - // v-name is indexed by a proper expression, not a literal - if (ast.indexed) - frame.size = frame.size + Machine.integerSize; - indexSize = ((Integer) ast.E.visit(this, frame)).intValue(); - if (elemSize != 1) { - emit(Machine.LOADLop, 0, 0, elemSize); - emit(Machine.CALLop, Machine.SBr, Machine.PBr, - Machine.multDisplacement); - } - if (ast.indexed) - emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); - else - ast.indexed = true; - } - return baseObject; - } - - // Programs - @Override -public Object visitProgram(Program ast, Object o) { - return ast.C.visit(this, o); - } - - public Encoder(ErrorReporter reporter) { - this.reporter = reporter; - nextInstrAddr = Machine.CB; - elaborateStdEnvironment(); - } - - private ErrorReporter reporter; - - // Generates code to run a program. - // showingTable is true iff entity description details - // are to be displayed. - public final void encodeRun(Program theAST, boolean showingTable) { - tableDetailsReqd = showingTable; - // startCodeGeneration(); - theAST.visit(this, new Frame(0, 0)); - emit(Machine.HALTop, 0, 0, 0); - } - - // Decides run-time representation of a standard constant. - private final void elaborateStdConst(Declaration constDeclaration, - int value) { - - if (constDeclaration instanceof ConstDeclaration) { - ConstDeclaration decl = (ConstDeclaration) constDeclaration; - int typeSize = ((Integer) decl.E.type.visit(this, null)).intValue(); - decl.entity = new KnownValue(typeSize, value); - writeTableDetails(constDeclaration); - } - } - - // Decides run-time representation of a standard routine. - private final void elaborateStdPrimRoutine(Declaration routineDeclaration, - int routineOffset) { - routineDeclaration.entity = new PrimitiveRoutine(Machine.closureSize, routineOffset); - writeTableDetails(routineDeclaration); - } - - private final void elaborateStdEqRoutine(Declaration routineDeclaration, - int routineOffset) { - routineDeclaration.entity = new EqualityRoutine(Machine.closureSize, routineOffset); - writeTableDetails(routineDeclaration); - } - - private final void elaborateStdRoutine(Declaration routineDeclaration, - int routineOffset) { - routineDeclaration.entity = new KnownRoutine(Machine.closureSize, 0, routineOffset); - writeTableDetails(routineDeclaration); - } - - private final void elaborateStdEnvironment() { - tableDetailsReqd = false; - elaborateStdConst(StdEnvironment.falseDecl, Machine.falseRep); - elaborateStdConst(StdEnvironment.trueDecl, Machine.trueRep); - elaborateStdPrimRoutine(StdEnvironment.notDecl, Machine.notDisplacement); - elaborateStdPrimRoutine(StdEnvironment.andDecl, Machine.andDisplacement); - elaborateStdPrimRoutine(StdEnvironment.orDecl, Machine.orDisplacement); - elaborateStdConst(StdEnvironment.maxintDecl, Machine.maxintRep); - elaborateStdPrimRoutine(StdEnvironment.addDecl, Machine.addDisplacement); - elaborateStdPrimRoutine(StdEnvironment.subtractDecl, Machine.subDisplacement); - elaborateStdPrimRoutine(StdEnvironment.multiplyDecl, Machine.multDisplacement); - elaborateStdPrimRoutine(StdEnvironment.divideDecl, Machine.divDisplacement); - elaborateStdPrimRoutine(StdEnvironment.moduloDecl, Machine.modDisplacement); - elaborateStdPrimRoutine(StdEnvironment.lessDecl, Machine.ltDisplacement); - elaborateStdPrimRoutine(StdEnvironment.notgreaterDecl, Machine.leDisplacement); - elaborateStdPrimRoutine(StdEnvironment.greaterDecl, Machine.gtDisplacement); - elaborateStdPrimRoutine(StdEnvironment.notlessDecl, Machine.geDisplacement); - elaborateStdPrimRoutine(StdEnvironment.chrDecl, Machine.idDisplacement); - elaborateStdPrimRoutine(StdEnvironment.ordDecl, Machine.idDisplacement); - elaborateStdPrimRoutine(StdEnvironment.eolDecl, Machine.eolDisplacement); - elaborateStdPrimRoutine(StdEnvironment.eofDecl, Machine.eofDisplacement); - elaborateStdPrimRoutine(StdEnvironment.getDecl, Machine.getDisplacement); - elaborateStdPrimRoutine(StdEnvironment.putDecl, Machine.putDisplacement); - elaborateStdPrimRoutine(StdEnvironment.getintDecl, Machine.getintDisplacement); - elaborateStdPrimRoutine(StdEnvironment.putintDecl, Machine.putintDisplacement); - elaborateStdPrimRoutine(StdEnvironment.geteolDecl, Machine.geteolDisplacement); - elaborateStdPrimRoutine(StdEnvironment.puteolDecl, Machine.puteolDisplacement); - elaborateStdEqRoutine(StdEnvironment.equalDecl, Machine.eqDisplacement); - elaborateStdEqRoutine(StdEnvironment.unequalDecl, Machine.neDisplacement); - } - - // Saves the object program in the named file. - - public void saveObjectProgram(String objectName) { - FileOutputStream objectFile = null; - DataOutputStream objectStream = null; - - int addr; - - try { - objectFile = new FileOutputStream(objectName); - objectStream = new DataOutputStream(objectFile); - - addr = Machine.CB; - for (addr = Machine.CB; addr < nextInstrAddr; addr++) - Machine.code[addr].write(objectStream); - objectFile.close(); - } catch (FileNotFoundException s) { - System.err.println("Error opening object file: " + s); - } catch (IOException s) { - System.err.println("Error writing object file: " + s); - } - } - - boolean tableDetailsReqd; - - public static void writeTableDetails(AST ast) { - } - - // OBJECT CODE - - // Implementation notes: - // Object code is generated directly into the TAM Code Store, starting at CB. - // The address of the next instruction is held in nextInstrAddr. - - private int nextInstrAddr; - - // Appends an instruction, with the given fields, to the object code. - private void emit(int op, int n, int r, int d) { - Instruction nextInstr = new Instruction(); - if (n > 255) { - reporter.reportRestriction("length of operand can't exceed 255 words"); - n = 255; // to allow code generation to continue - } - nextInstr.op = op; - nextInstr.n = n; - nextInstr.r = r; - nextInstr.d = d; - if (nextInstrAddr == Machine.PB) - reporter.reportRestriction("too many instructions for code segment"); - else { - Machine.code[nextInstrAddr] = nextInstr; - nextInstrAddr = nextInstrAddr + 1; - } - } - - // Patches the d-field of the instruction at address addr. - private void patch(int addr, int d) { - Machine.code[addr].d = d; - } - - // DATA REPRESENTATION - - public int characterValuation(String spelling) { - // Returns the machine representation of the given character literal. - return spelling.charAt(1); - // since the character literal is of the form 'x'} - } - - // REGISTERS - - // Returns the register number appropriate for object code at currentLevel - // to address a data object at objectLevel. - private int displayRegister(int currentLevel, int objectLevel) { - if (objectLevel == 0) - return Machine.SBr; - else if (currentLevel - objectLevel <= 6) - return Machine.LBr + currentLevel - objectLevel; // LBr|L1r|...|L6r - else { - reporter.reportRestriction("can't access data more than 6 levels out"); - return Machine.L6r; // to allow code generation to continue - } - } - - // Generates code to fetch the value of a named constant or variable - // and push it on to the stack. - // currentLevel is the routine level where the vname occurs. - // frameSize is the anticipated size of the local stack frame when - // the constant or variable is fetched at run-time. - // valSize is the size of the constant or variable's value. - - private void encodeStore(Vname V, Frame frame, int valSize) { - - RuntimeEntity baseObject = (RuntimeEntity) V.visit(this, frame); - // If indexed = true, code will have been generated to load an index value. - if (valSize > 255) { - reporter.reportRestriction("can't store values larger than 255 words"); - valSize = 255; // to allow code generation to continue - } - if (baseObject instanceof KnownAddress) { - ObjectAddress address = ((KnownAddress) baseObject).address; - if (V.indexed) { - emit(Machine.LOADAop, 0, displayRegister(frame.level, address.level), - address.displacement + V.offset); - emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); - emit(Machine.STOREIop, valSize, 0, 0); - } else { - emit(Machine.STOREop, valSize, displayRegister(frame.level, - address.level), address.displacement + V.offset); - } - } else if (baseObject instanceof UnknownAddress) { - ObjectAddress address = ((UnknownAddress) baseObject).address; - emit(Machine.LOADop, Machine.addressSize, displayRegister(frame.level, - address.level), address.displacement); - if (V.indexed) - emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); - if (V.offset != 0) { - emit(Machine.LOADLop, 0, 0, V.offset); - emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); - } - emit(Machine.STOREIop, valSize, 0, 0); - } - } - - // Generates code to fetch the value of a named constant or variable - // and push it on to the stack. - // currentLevel is the routine level where the vname occurs. - // frameSize is the anticipated size of the local stack frame when - // the constant or variable is fetched at run-time. - // valSize is the size of the constant or variable's value. - - private void encodeFetch(Vname V, Frame frame, int valSize) { - - RuntimeEntity baseObject = (RuntimeEntity) V.visit(this, frame); - // If indexed = true, code will have been generated to load an index value. - if (valSize > 255) { - reporter.reportRestriction("can't load values larger than 255 words"); - valSize = 255; // to allow code generation to continue - } - if (baseObject instanceof KnownValue) { - // presumably offset = 0 and indexed = false - int value = ((KnownValue) baseObject).value; - emit(Machine.LOADLop, 0, 0, value); - } else if ((baseObject instanceof UnknownValue) || - (baseObject instanceof KnownAddress)) { - ObjectAddress address = (baseObject instanceof UnknownValue) ? ((UnknownValue) baseObject).address - : ((KnownAddress) baseObject).address; - if (V.indexed) { - emit(Machine.LOADAop, 0, displayRegister(frame.level, address.level), - address.displacement + V.offset); - emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); - emit(Machine.LOADIop, valSize, 0, 0); - } else - emit(Machine.LOADop, valSize, displayRegister(frame.level, - address.level), address.displacement + V.offset); - } else if (baseObject instanceof UnknownAddress) { - ObjectAddress address = ((UnknownAddress) baseObject).address; - emit(Machine.LOADop, Machine.addressSize, displayRegister(frame.level, - address.level), address.displacement); - if (V.indexed) - emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); - if (V.offset != 0) { - emit(Machine.LOADLop, 0, 0, V.offset); - emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); - } - emit(Machine.LOADIop, valSize, 0, 0); - } - } - - // Generates code to compute and push the address of a named variable. - // vname is the program phrase that names this variable. - // currentLevel is the routine level where the vname occurs. - // frameSize is the anticipated size of the local stack frame when - // the variable is addressed at run-time. - - private void encodeFetchAddress(Vname V, Frame frame) { - - RuntimeEntity baseObject = (RuntimeEntity) V.visit(this, frame); - // If indexed = true, code will have been generated to load an index value. - if (baseObject instanceof KnownAddress) { - ObjectAddress address = ((KnownAddress) baseObject).address; - emit(Machine.LOADAop, 0, displayRegister(frame.level, address.level), - address.displacement + V.offset); - if (V.indexed) - emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); - } else if (baseObject instanceof UnknownAddress) { - ObjectAddress address = ((UnknownAddress) baseObject).address; - emit(Machine.LOADop, Machine.addressSize, displayRegister(frame.level, - address.level), address.displacement); - if (V.indexed) - emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); - if (V.offset != 0) { - emit(Machine.LOADLop, 0, 0, V.offset); - emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); - } - } - } + // Commands + @Override + public Object visitAssignCommand(AssignCommand ast, Object o) { + Frame frame = (Frame) o; + Integer valSize = (Integer) ast.E.visit(this, frame); + encodeStore(ast.V, new Frame(frame, valSize.intValue()), valSize.intValue()); + return null; + } + + @Override + public Object visitCallCommand(CallCommand ast, Object o) { + Frame frame = (Frame) o; + Integer argsSize = (Integer) ast.APS.visit(this, frame); + ast.I.visit(this, new Frame(frame.level, argsSize)); + return null; + } + + @Override + public Object visitEmptyCommand(EmptyCommand ast, Object o) { + return null; + } + + @Override + public Object visitIfCommand(IfCommand ast, Object o) { + Frame frame = (Frame) o; + int jumpifAddr, jumpAddr; + + Integer valSize = (Integer) ast.E.visit(this, frame); + jumpifAddr = nextInstrAddr; + emit(Machine.JUMPIFop, Machine.falseRep, Machine.CBr, 0); + ast.C1.visit(this, frame); + jumpAddr = nextInstrAddr; + emit(Machine.JUMPop, 0, Machine.CBr, 0); + patch(jumpifAddr, nextInstrAddr); + ast.C2.visit(this, frame); + patch(jumpAddr, nextInstrAddr); + return null; + } + + @Override + public Object visitLetCommand(LetCommand ast, Object o) { + Frame frame = (Frame) o; + int extraSize = ((Integer) ast.D.visit(this, frame)).intValue(); + ast.C.visit(this, new Frame(frame, extraSize)); + if (extraSize > 0) + emit(Machine.POPop, 0, 0, extraSize); + return null; + } + + @Override + public Object visitSequentialCommand(SequentialCommand ast, Object o) { + ast.C1.visit(this, o); + ast.C2.visit(this, o); + return null; + } + + @Override + public Object visitWhileCommand(WhileCommand ast, Object o) { + Frame frame = (Frame) o; + int jumpAddr, loopAddr; + + jumpAddr = nextInstrAddr; + emit(Machine.JUMPop, 0, Machine.CBr, 0); + loopAddr = nextInstrAddr; + ast.C.visit(this, frame); + patch(jumpAddr, nextInstrAddr); + ast.E.visit(this, frame); + emit(Machine.JUMPIFop, Machine.trueRep, Machine.CBr, loopAddr); + return null; + } + + // Expressions + @Override + public Object visitArrayExpression(ArrayExpression ast, Object o) { + ast.type.visit(this, null); + return ast.AA.visit(this, o); + } + + @Override + public Object visitBinaryExpression(BinaryExpression ast, Object o) { + Frame frame = (Frame) o; + Integer valSize = (Integer) ast.type.visit(this, null); + int valSize1 = ((Integer) ast.E1.visit(this, frame)).intValue(); + Frame frame1 = new Frame(frame, valSize1); + int valSize2 = ((Integer) ast.E2.visit(this, frame1)).intValue(); + Frame frame2 = new Frame(frame.level, valSize1 + valSize2); + ast.O.visit(this, frame2); + return valSize; + } + + @Override + public Object visitCallExpression(CallExpression ast, Object o) { + Frame frame = (Frame) o; + Integer valSize = (Integer) ast.type.visit(this, null); + Integer argsSize = (Integer) ast.APS.visit(this, frame); + ast.I.visit(this, new Frame(frame.level, argsSize)); + return valSize; + } + + @Override + public Object visitCharacterExpression(CharacterExpression ast, Object o) { + Frame frame = (Frame) o; + Integer valSize = (Integer) ast.type.visit(this, null); + emit(Machine.LOADLop, 0, 0, ast.CL.spelling.charAt(1)); + return valSize; + } + + @Override + public Object visitEmptyExpression(EmptyExpression ast, Object o) { + return Integer.valueOf(0); + } + + @Override + public Object visitIfExpression(IfExpression ast, Object o) { + Frame frame = (Frame) o; + Integer valSize; + int jumpifAddr, jumpAddr; + + ast.type.visit(this, null); + ast.E1.visit(this, frame); + jumpifAddr = nextInstrAddr; + emit(Machine.JUMPIFop, Machine.falseRep, Machine.CBr, 0); + valSize = (Integer) ast.E2.visit(this, frame); + jumpAddr = nextInstrAddr; + emit(Machine.JUMPop, 0, Machine.CBr, 0); + patch(jumpifAddr, nextInstrAddr); + valSize = (Integer) ast.E3.visit(this, frame); + patch(jumpAddr, nextInstrAddr); + return valSize; + } + + @Override + public Object visitIntegerExpression(IntegerExpression ast, Object o) { + Frame frame = (Frame) o; + Integer valSize = (Integer) ast.type.visit(this, null); + emit(Machine.LOADLop, 0, 0, Integer.parseInt(ast.IL.spelling)); + return valSize; + } + + @Override + public Object visitLetExpression(LetExpression ast, Object o) { + Frame frame = (Frame) o; + ast.type.visit(this, null); + int extraSize = ((Integer) ast.D.visit(this, frame)).intValue(); + Frame frame1 = new Frame(frame, extraSize); + Integer valSize = (Integer) ast.E.visit(this, frame1); + if (extraSize > 0) + emit(Machine.POPop, valSize.intValue(), 0, extraSize); + return valSize; + } + + @Override + public Object visitRecordExpression(RecordExpression ast, Object o) { + ast.type.visit(this, null); + return ast.RA.visit(this, o); + } + + @Override + public Object visitUnaryExpression(UnaryExpression ast, Object o) { + Frame frame = (Frame) o; + Integer valSize = (Integer) ast.type.visit(this, null); + ast.E.visit(this, frame); + ast.O.visit(this, new Frame(frame.level, valSize.intValue())); + return valSize; + } + + @Override + public Object visitVnameExpression(VnameExpression ast, Object o) { + Frame frame = (Frame) o; + Integer valSize = (Integer) ast.type.visit(this, null); + encodeFetch(ast.V, frame, valSize.intValue()); + return valSize; + } + + // Declarations + @Override + public Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Object o) { + return Integer.valueOf(0); + } + + @Override + public Object visitConstDeclaration(ConstDeclaration ast, Object o) { + Frame frame = (Frame) o; + int extraSize = 0; + + if (ast.E instanceof CharacterExpression) { + CharacterLiteral CL = ((CharacterExpression) ast.E).CL; + ast.entity = new KnownValue(Machine.characterSize, characterValuation(CL.spelling)); + } else if (ast.E instanceof IntegerExpression) { + IntegerLiteral IL = ((IntegerExpression) ast.E).IL; + ast.entity = new KnownValue(Machine.integerSize, Integer.parseInt(IL.spelling)); + } else { + int valSize = ((Integer) ast.E.visit(this, frame)).intValue(); + ast.entity = new UnknownValue(valSize, frame.level, frame.size); + extraSize = valSize; + } + writeTableDetails(ast); + return Integer.valueOf(extraSize); + } + + @Override + public Object visitFuncDeclaration(FuncDeclaration ast, Object o) { + Frame frame = (Frame) o; + int jumpAddr = nextInstrAddr; + int argsSize = 0, valSize = 0; + + emit(Machine.JUMPop, 0, Machine.CBr, 0); + ast.entity = new KnownRoutine(Machine.closureSize, frame.level, nextInstrAddr); + writeTableDetails(ast); + if (frame.level == Machine.maxRoutineLevel) + reporter.reportRestriction("can't nest routines more than 7 deep"); + else { + Frame frame1 = new Frame(frame.level + 1, 0); + argsSize = ((Integer) ast.FPS.visit(this, frame1)).intValue(); + Frame frame2 = new Frame(frame.level + 1, Machine.linkDataSize); + valSize = ((Integer) ast.E.visit(this, frame2)).intValue(); + } + emit(Machine.RETURNop, valSize, 0, argsSize); + patch(jumpAddr, nextInstrAddr); + return Integer.valueOf(0); + } + + @Override + public Object visitProcDeclaration(ProcDeclaration ast, Object o) { + Frame frame = (Frame) o; + int jumpAddr = nextInstrAddr; + int argsSize = 0; + + emit(Machine.JUMPop, 0, Machine.CBr, 0); + ast.entity = new KnownRoutine(Machine.closureSize, frame.level, nextInstrAddr); + writeTableDetails(ast); + if (frame.level == Machine.maxRoutineLevel) + reporter.reportRestriction("can't nest routines so deeply"); + else { + Frame frame1 = new Frame(frame.level + 1, 0); + argsSize = ((Integer) ast.FPS.visit(this, frame1)).intValue(); + Frame frame2 = new Frame(frame.level + 1, Machine.linkDataSize); + ast.C.visit(this, frame2); + } + emit(Machine.RETURNop, 0, 0, argsSize); + patch(jumpAddr, nextInstrAddr); + return Integer.valueOf(0); + } + + @Override + public Object visitSequentialDeclaration(SequentialDeclaration ast, Object o) { + Frame frame = (Frame) o; + int extraSize1, extraSize2; + + extraSize1 = ((Integer) ast.D1.visit(this, frame)).intValue(); + Frame frame1 = new Frame(frame, extraSize1); + extraSize2 = ((Integer) ast.D2.visit(this, frame1)).intValue(); + return Integer.valueOf(extraSize1 + extraSize2); + } + + @Override + public Object visitTypeDeclaration(TypeDeclaration ast, Object o) { + // just to ensure the type's representation is decided + ast.T.visit(this, null); + return Integer.valueOf(0); + } + + @Override + public Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Object o) { + return Integer.valueOf(0); + } + + @Override + public Object visitVarDeclaration(VarDeclaration ast, Object o) { + Frame frame = (Frame) o; + int extraSize; + + extraSize = ((Integer) ast.T.visit(this, null)).intValue(); + emit(Machine.PUSHop, 0, 0, extraSize); + ast.entity = new KnownAddress(Machine.addressSize, frame.level, frame.size); + writeTableDetails(ast); + return Integer.valueOf(extraSize); + } + + // Array Aggregates + @Override + public Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, Object o) { + Frame frame = (Frame) o; + int elemSize = ((Integer) ast.E.visit(this, frame)).intValue(); + Frame frame1 = new Frame(frame, elemSize); + int arraySize = ((Integer) ast.AA.visit(this, frame1)).intValue(); + return Integer.valueOf(elemSize + arraySize); + } + + @Override + public Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object o) { + return ast.E.visit(this, o); + } + + // Record Aggregates + @Override + public Object visitMultipleRecordAggregate(MultipleRecordAggregate ast, Object o) { + Frame frame = (Frame) o; + int fieldSize = ((Integer) ast.E.visit(this, frame)).intValue(); + Frame frame1 = new Frame(frame, fieldSize); + int recordSize = ((Integer) ast.RA.visit(this, frame1)).intValue(); + return Integer.valueOf(fieldSize + recordSize); + } + + @Override + public Object visitSingleRecordAggregate(SingleRecordAggregate ast, Object o) { + return ast.E.visit(this, o); + } + + // Formal Parameters + @Override + public Object visitConstFormalParameter(ConstFormalParameter ast, Object o) { + Frame frame = (Frame) o; + int valSize = ((Integer) ast.T.visit(this, null)).intValue(); + ast.entity = new UnknownValue(valSize, frame.level, -frame.size - valSize); + writeTableDetails(ast); + return Integer.valueOf(valSize); + } + + @Override + public Object visitFuncFormalParameter(FuncFormalParameter ast, Object o) { + Frame frame = (Frame) o; + int argsSize = Machine.closureSize; + ast.entity = new UnknownRoutine(Machine.closureSize, frame.level, -frame.size - argsSize); + writeTableDetails(ast); + return Integer.valueOf(argsSize); + } + + @Override + public Object visitProcFormalParameter(ProcFormalParameter ast, Object o) { + Frame frame = (Frame) o; + int argsSize = Machine.closureSize; + ast.entity = new UnknownRoutine(Machine.closureSize, frame.level, -frame.size - argsSize); + writeTableDetails(ast); + return Integer.valueOf(argsSize); + } + + @Override + public Object visitVarFormalParameter(VarFormalParameter ast, Object o) { + Frame frame = (Frame) o; + ast.T.visit(this, null); + ast.entity = new UnknownAddress(Machine.addressSize, frame.level, -frame.size - Machine.addressSize); + writeTableDetails(ast); + return Integer.valueOf(Machine.addressSize); + } + + @Override + public Object visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Object o) { + return Integer.valueOf(0); + } + + @Override + public Object visitMultipleFormalParameterSequence(MultipleFormalParameterSequence ast, Object o) { + Frame frame = (Frame) o; + int argsSize1 = ((Integer) ast.FPS.visit(this, frame)).intValue(); + Frame frame1 = new Frame(frame, argsSize1); + int argsSize2 = ((Integer) ast.FP.visit(this, frame1)).intValue(); + return Integer.valueOf(argsSize1 + argsSize2); + } + + @Override + public Object visitSingleFormalParameterSequence(SingleFormalParameterSequence ast, Object o) { + return ast.FP.visit(this, o); + } + + // Actual Parameters + @Override + public Object visitConstActualParameter(ConstActualParameter ast, Object o) { + return ast.E.visit(this, o); + } + + @Override + public Object visitFuncActualParameter(FuncActualParameter ast, Object o) { + Frame frame = (Frame) o; + if (ast.I.decl.entity instanceof KnownRoutine) { + ObjectAddress address = ((KnownRoutine) ast.I.decl.entity).address; + // static link, code address + emit(Machine.LOADAop, 0, displayRegister(frame.level, address.level), 0); + emit(Machine.LOADAop, 0, Machine.CBr, address.displacement); + } else if (ast.I.decl.entity instanceof UnknownRoutine) { + ObjectAddress address = ((UnknownRoutine) ast.I.decl.entity).address; + emit(Machine.LOADop, Machine.closureSize, displayRegister(frame.level, address.level), + address.displacement); + } else if (ast.I.decl.entity instanceof PrimitiveRoutine) { + int displacement = ((PrimitiveRoutine) ast.I.decl.entity).displacement; + // static link, code address + emit(Machine.LOADAop, 0, Machine.SBr, 0); + emit(Machine.LOADAop, 0, Machine.PBr, displacement); + } + return Integer.valueOf(Machine.closureSize); + } + + @Override + public Object visitProcActualParameter(ProcActualParameter ast, Object o) { + Frame frame = (Frame) o; + if (ast.I.decl.entity instanceof KnownRoutine) { + ObjectAddress address = ((KnownRoutine) ast.I.decl.entity).address; + // static link, code address + emit(Machine.LOADAop, 0, displayRegister(frame.level, address.level), 0); + emit(Machine.LOADAop, 0, Machine.CBr, address.displacement); + } else if (ast.I.decl.entity instanceof UnknownRoutine) { + ObjectAddress address = ((UnknownRoutine) ast.I.decl.entity).address; + emit(Machine.LOADop, Machine.closureSize, displayRegister(frame.level, address.level), + address.displacement); + } else if (ast.I.decl.entity instanceof PrimitiveRoutine) { + int displacement = ((PrimitiveRoutine) ast.I.decl.entity).displacement; + // static link, code address + emit(Machine.LOADAop, 0, Machine.SBr, 0); + emit(Machine.LOADAop, 0, Machine.PBr, displacement); + } + return Integer.valueOf(Machine.closureSize); + } + + @Override + public Object visitVarActualParameter(VarActualParameter ast, Object o) { + encodeFetchAddress(ast.V, (Frame) o); + return Integer.valueOf(Machine.addressSize); + } + + @Override + public Object visitEmptyActualParameterSequence(EmptyActualParameterSequence ast, Object o) { + return Integer.valueOf(0); + } + + @Override + public Object visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, Object o) { + Frame frame = (Frame) o; + int argsSize1 = ((Integer) ast.AP.visit(this, frame)).intValue(); + Frame frame1 = new Frame(frame, argsSize1); + int argsSize2 = ((Integer) ast.APS.visit(this, frame1)).intValue(); + return Integer.valueOf(argsSize1 + argsSize2); + } + + @Override + public Object visitSingleActualParameterSequence(SingleActualParameterSequence ast, Object o) { + return ast.AP.visit(this, o); + } + + // Type Denoters + @Override + public Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object o) { + return Integer.valueOf(0); + } + + @Override + public Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object o) { + int typeSize; + if (ast.entity == null) { + int elemSize = ((Integer) ast.T.visit(this, null)).intValue(); + typeSize = Integer.parseInt(ast.IL.spelling) * elemSize; + ast.entity = new TypeRepresentation(typeSize); + writeTableDetails(ast); + } else + typeSize = ast.entity.size; + return Integer.valueOf(typeSize); + } + + @Override + public Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object o) { + if (ast.entity == null) { + ast.entity = new TypeRepresentation(Machine.booleanSize); + writeTableDetails(ast); + } + return Integer.valueOf(Machine.booleanSize); + } + + @Override + public Object visitCharTypeDenoter(CharTypeDenoter ast, Object o) { + if (ast.entity == null) { + ast.entity = new TypeRepresentation(Machine.characterSize); + writeTableDetails(ast); + } + return Integer.valueOf(Machine.characterSize); + } + + @Override + public Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object o) { + return Integer.valueOf(0); + } + + @Override + public Object visitSimpleTypeDenoter(SimpleTypeDenoter ast, Object o) { + return Integer.valueOf(0); + } + + @Override + public Object visitIntTypeDenoter(IntTypeDenoter ast, Object o) { + if (ast.entity == null) { + ast.entity = new TypeRepresentation(Machine.integerSize); + writeTableDetails(ast); + } + return Integer.valueOf(Machine.integerSize); + } + + @Override + public Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object o) { + int typeSize; + if (ast.entity == null) { + typeSize = ((Integer) ast.FT.visit(this, Integer.valueOf(0))).intValue(); + ast.entity = new TypeRepresentation(typeSize); + writeTableDetails(ast); + } else + typeSize = ast.entity.size; + return Integer.valueOf(typeSize); + } + + @Override + public Object visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, Object o) { + int offset = ((Integer) o).intValue(); + int fieldSize; + + if (ast.entity == null) { + fieldSize = ((Integer) ast.T.visit(this, null)).intValue(); + ast.entity = new Field(fieldSize, offset); + writeTableDetails(ast); + } else + fieldSize = ast.entity.size; + + Integer offset1 = Integer.valueOf(offset + fieldSize); + int recSize = ((Integer) ast.FT.visit(this, offset1)).intValue(); + return Integer.valueOf(fieldSize + recSize); + } + + @Override + public Object visitSingleFieldTypeDenoter(SingleFieldTypeDenoter ast, Object o) { + int offset = ((Integer) o).intValue(); + int fieldSize; + + if (ast.entity == null) { + fieldSize = ((Integer) ast.T.visit(this, null)).intValue(); + ast.entity = new Field(fieldSize, offset); + writeTableDetails(ast); + } else + fieldSize = ast.entity.size; + + return Integer.valueOf(fieldSize); + } + + // Literals, Identifiers and Operators + @Override + public Object visitCharacterLiteral(CharacterLiteral ast, Object o) { + return null; + } + + @Override + public Object visitIdentifier(Identifier ast, Object o) { + Frame frame = (Frame) o; + if (ast.decl.entity instanceof KnownRoutine) { + ObjectAddress address = ((KnownRoutine) ast.decl.entity).address; + emit(Machine.CALLop, displayRegister(frame.level, address.level), Machine.CBr, address.displacement); + } else if (ast.decl.entity instanceof UnknownRoutine) { + ObjectAddress address = ((UnknownRoutine) ast.decl.entity).address; + emit(Machine.LOADop, Machine.closureSize, displayRegister(frame.level, address.level), + address.displacement); + emit(Machine.CALLIop, 0, 0, 0); + } else if (ast.decl.entity instanceof PrimitiveRoutine) { + int displacement = ((PrimitiveRoutine) ast.decl.entity).displacement; + if (displacement != Machine.idDisplacement) + emit(Machine.CALLop, Machine.SBr, Machine.PBr, displacement); + } else if (ast.decl.entity instanceof EqualityRoutine) { // "=" or "\=" + int displacement = ((EqualityRoutine) ast.decl.entity).displacement; + emit(Machine.LOADLop, 0, 0, frame.size / 2); + emit(Machine.CALLop, Machine.SBr, Machine.PBr, displacement); + } + return null; + } + + @Override + public Object visitIntegerLiteral(IntegerLiteral ast, Object o) { + return null; + } + + @Override + public Object visitOperator(Operator ast, Object o) { + Frame frame = (Frame) o; + if (ast.decl.entity instanceof KnownRoutine) { + ObjectAddress address = ((KnownRoutine) ast.decl.entity).address; + emit(Machine.CALLop, displayRegister(frame.level, address.level), Machine.CBr, address.displacement); + } else if (ast.decl.entity instanceof UnknownRoutine) { + ObjectAddress address = ((UnknownRoutine) ast.decl.entity).address; + emit(Machine.LOADop, Machine.closureSize, displayRegister(frame.level, address.level), + address.displacement); + emit(Machine.CALLIop, 0, 0, 0); + } else if (ast.decl.entity instanceof PrimitiveRoutine) { + int displacement = ((PrimitiveRoutine) ast.decl.entity).displacement; + if (displacement != Machine.idDisplacement) + emit(Machine.CALLop, Machine.SBr, Machine.PBr, displacement); + } else if (ast.decl.entity instanceof EqualityRoutine) { // "=" or "\=" + int displacement = ((EqualityRoutine) ast.decl.entity).displacement; + emit(Machine.LOADLop, 0, 0, frame.size / 2); + emit(Machine.CALLop, Machine.SBr, Machine.PBr, displacement); + } + return null; + } + + // Value-or-variable names + @Override + public Object visitDotVname(DotVname ast, Object o) { + Frame frame = (Frame) o; + RuntimeEntity baseObject = (RuntimeEntity) ast.V.visit(this, frame); + ast.offset = ast.V.offset + ((Field) ast.I.decl.entity).fieldOffset; + // I.decl points to the appropriate record field + ast.indexed = ast.V.indexed; + return baseObject; + } + + @Override + public Object visitSimpleVname(SimpleVname ast, Object o) { + ast.offset = 0; + ast.indexed = false; + return ast.I.decl.entity; + } + + @Override + public Object visitSubscriptVname(SubscriptVname ast, Object o) { + Frame frame = (Frame) o; + RuntimeEntity baseObject; + int elemSize, indexSize; + + baseObject = (RuntimeEntity) ast.V.visit(this, frame); + ast.offset = ast.V.offset; + ast.indexed = ast.V.indexed; + elemSize = ((Integer) ast.type.visit(this, null)).intValue(); + if (ast.E instanceof IntegerExpression) { + IntegerLiteral IL = ((IntegerExpression) ast.E).IL; + ast.offset = ast.offset + Integer.parseInt(IL.spelling) * elemSize; + } else { + // v-name is indexed by a proper expression, not a literal + if (ast.indexed) + frame.size = frame.size + Machine.integerSize; + indexSize = ((Integer) ast.E.visit(this, frame)).intValue(); + if (elemSize != 1) { + emit(Machine.LOADLop, 0, 0, elemSize); + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.multDisplacement); + } + if (ast.indexed) + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + else + ast.indexed = true; + } + return baseObject; + } + + // Programs + @Override + public Object visitProgram(Program ast, Object o) { + return ast.C.visit(this, o); + } + + public Encoder(ErrorReporter reporter) { + this.reporter = reporter; + nextInstrAddr = Machine.CB; + elaborateStdEnvironment(); + } + + private ErrorReporter reporter; + + // Generates code to run a program. + // showingTable is true iff entity description details + // are to be displayed. + public final void encodeRun(Program theAST, boolean showingTable) { + tableDetailsReqd = showingTable; + // startCodeGeneration(); + theAST.visit(this, new Frame(0, 0)); + emit(Machine.HALTop, 0, 0, 0); + } + + // Decides run-time representation of a standard constant. + private final void elaborateStdConst(Declaration constDeclaration, int value) { + + if (constDeclaration instanceof ConstDeclaration) { + ConstDeclaration decl = (ConstDeclaration) constDeclaration; + int typeSize = ((Integer) decl.E.type.visit(this, null)).intValue(); + decl.entity = new KnownValue(typeSize, value); + writeTableDetails(constDeclaration); + } + } + + // Decides run-time representation of a standard routine. + private final void elaborateStdPrimRoutine(Declaration routineDeclaration, int routineOffset) { + routineDeclaration.entity = new PrimitiveRoutine(Machine.closureSize, routineOffset); + writeTableDetails(routineDeclaration); + } + + private final void elaborateStdEqRoutine(Declaration routineDeclaration, int routineOffset) { + routineDeclaration.entity = new EqualityRoutine(Machine.closureSize, routineOffset); + writeTableDetails(routineDeclaration); + } + + private final void elaborateStdRoutine(Declaration routineDeclaration, int routineOffset) { + routineDeclaration.entity = new KnownRoutine(Machine.closureSize, 0, routineOffset); + writeTableDetails(routineDeclaration); + } + + private final void elaborateStdEnvironment() { + tableDetailsReqd = false; + elaborateStdConst(StdEnvironment.falseDecl, Machine.falseRep); + elaborateStdConst(StdEnvironment.trueDecl, Machine.trueRep); + elaborateStdPrimRoutine(StdEnvironment.notDecl, Machine.notDisplacement); + elaborateStdPrimRoutine(StdEnvironment.andDecl, Machine.andDisplacement); + elaborateStdPrimRoutine(StdEnvironment.orDecl, Machine.orDisplacement); + elaborateStdConst(StdEnvironment.maxintDecl, Machine.maxintRep); + elaborateStdPrimRoutine(StdEnvironment.addDecl, Machine.addDisplacement); + elaborateStdPrimRoutine(StdEnvironment.subtractDecl, Machine.subDisplacement); + elaborateStdPrimRoutine(StdEnvironment.multiplyDecl, Machine.multDisplacement); + elaborateStdPrimRoutine(StdEnvironment.divideDecl, Machine.divDisplacement); + elaborateStdPrimRoutine(StdEnvironment.moduloDecl, Machine.modDisplacement); + elaborateStdPrimRoutine(StdEnvironment.lessDecl, Machine.ltDisplacement); + elaborateStdPrimRoutine(StdEnvironment.notgreaterDecl, Machine.leDisplacement); + elaborateStdPrimRoutine(StdEnvironment.greaterDecl, Machine.gtDisplacement); + elaborateStdPrimRoutine(StdEnvironment.notlessDecl, Machine.geDisplacement); + elaborateStdPrimRoutine(StdEnvironment.chrDecl, Machine.idDisplacement); + elaborateStdPrimRoutine(StdEnvironment.ordDecl, Machine.idDisplacement); + elaborateStdPrimRoutine(StdEnvironment.eolDecl, Machine.eolDisplacement); + elaborateStdPrimRoutine(StdEnvironment.eofDecl, Machine.eofDisplacement); + elaborateStdPrimRoutine(StdEnvironment.getDecl, Machine.getDisplacement); + elaborateStdPrimRoutine(StdEnvironment.putDecl, Machine.putDisplacement); + elaborateStdPrimRoutine(StdEnvironment.getintDecl, Machine.getintDisplacement); + elaborateStdPrimRoutine(StdEnvironment.putintDecl, Machine.putintDisplacement); + elaborateStdPrimRoutine(StdEnvironment.geteolDecl, Machine.geteolDisplacement); + elaborateStdPrimRoutine(StdEnvironment.puteolDecl, Machine.puteolDisplacement); + elaborateStdEqRoutine(StdEnvironment.equalDecl, Machine.eqDisplacement); + elaborateStdEqRoutine(StdEnvironment.unequalDecl, Machine.neDisplacement); + } + + // Saves the object program in the named file. + + public void saveObjectProgram(String objectName) { + FileOutputStream objectFile = null; + DataOutputStream objectStream = null; + + int addr; + + try { + objectFile = new FileOutputStream(objectName); + objectStream = new DataOutputStream(objectFile); + + addr = Machine.CB; + for (addr = Machine.CB; addr < nextInstrAddr; addr++) + Machine.code[addr].write(objectStream); + objectFile.close(); + } catch (FileNotFoundException s) { + System.err.println("Error opening object file: " + s); + } catch (IOException s) { + System.err.println("Error writing object file: " + s); + } + } + + boolean tableDetailsReqd; + + public static void writeTableDetails(AST ast) { + } + + // OBJECT CODE + + // Implementation notes: + // Object code is generated directly into the TAM Code Store, starting at CB. + // The address of the next instruction is held in nextInstrAddr. + + private int nextInstrAddr; + + // Appends an instruction, with the given fields, to the object code. + private void emit(int op, int n, int r, int d) { + Instruction nextInstr = new Instruction(); + if (n > 255) { + reporter.reportRestriction("length of operand can't exceed 255 words"); + n = 255; // to allow code generation to continue + } + nextInstr.op = op; + nextInstr.n = n; + nextInstr.r = r; + nextInstr.d = d; + if (nextInstrAddr == Machine.PB) + reporter.reportRestriction("too many instructions for code segment"); + else { + Machine.code[nextInstrAddr] = nextInstr; + nextInstrAddr = nextInstrAddr + 1; + } + } + + // Patches the d-field of the instruction at address addr. + private void patch(int addr, int d) { + Machine.code[addr].d = d; + } + + // DATA REPRESENTATION + + public int characterValuation(String spelling) { + // Returns the machine representation of the given character literal. + return spelling.charAt(1); + // since the character literal is of the form 'x'} + } + + // REGISTERS + + // Returns the register number appropriate for object code at currentLevel + // to address a data object at objectLevel. + private int displayRegister(int currentLevel, int objectLevel) { + if (objectLevel == 0) + return Machine.SBr; + else if (currentLevel - objectLevel <= 6) + return Machine.LBr + currentLevel - objectLevel; // LBr|L1r|...|L6r + else { + reporter.reportRestriction("can't access data more than 6 levels out"); + return Machine.L6r; // to allow code generation to continue + } + } + + // Generates code to fetch the value of a named constant or variable + // and push it on to the stack. + // currentLevel is the routine level where the vname occurs. + // frameSize is the anticipated size of the local stack frame when + // the constant or variable is fetched at run-time. + // valSize is the size of the constant or variable's value. + + private void encodeStore(Vname V, Frame frame, int valSize) { + + RuntimeEntity baseObject = (RuntimeEntity) V.visit(this, frame); + // If indexed = true, code will have been generated to load an index value. + if (valSize > 255) { + reporter.reportRestriction("can't store values larger than 255 words"); + valSize = 255; // to allow code generation to continue + } + if (baseObject instanceof KnownAddress) { + ObjectAddress address = ((KnownAddress) baseObject).address; + if (V.indexed) { + emit(Machine.LOADAop, 0, displayRegister(frame.level, address.level), address.displacement + V.offset); + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + emit(Machine.STOREIop, valSize, 0, 0); + } else { + emit(Machine.STOREop, valSize, displayRegister(frame.level, address.level), + address.displacement + V.offset); + } + } else if (baseObject instanceof UnknownAddress) { + ObjectAddress address = ((UnknownAddress) baseObject).address; + emit(Machine.LOADop, Machine.addressSize, displayRegister(frame.level, address.level), + address.displacement); + if (V.indexed) + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + if (V.offset != 0) { + emit(Machine.LOADLop, 0, 0, V.offset); + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + } + emit(Machine.STOREIop, valSize, 0, 0); + } + } + + // Generates code to fetch the value of a named constant or variable + // and push it on to the stack. + // currentLevel is the routine level where the vname occurs. + // frameSize is the anticipated size of the local stack frame when + // the constant or variable is fetched at run-time. + // valSize is the size of the constant or variable's value. + + private void encodeFetch(Vname V, Frame frame, int valSize) { + + RuntimeEntity baseObject = (RuntimeEntity) V.visit(this, frame); + // If indexed = true, code will have been generated to load an index value. + if (valSize > 255) { + reporter.reportRestriction("can't load values larger than 255 words"); + valSize = 255; // to allow code generation to continue + } + if (baseObject instanceof KnownValue) { + // presumably offset = 0 and indexed = false + int value = ((KnownValue) baseObject).value; + emit(Machine.LOADLop, 0, 0, value); + } else if ((baseObject instanceof UnknownValue) || (baseObject instanceof KnownAddress)) { + ObjectAddress address = (baseObject instanceof UnknownValue) ? ((UnknownValue) baseObject).address + : ((KnownAddress) baseObject).address; + if (V.indexed) { + emit(Machine.LOADAop, 0, displayRegister(frame.level, address.level), address.displacement + V.offset); + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + emit(Machine.LOADIop, valSize, 0, 0); + } else + emit(Machine.LOADop, valSize, displayRegister(frame.level, address.level), + address.displacement + V.offset); + } else if (baseObject instanceof UnknownAddress) { + ObjectAddress address = ((UnknownAddress) baseObject).address; + emit(Machine.LOADop, Machine.addressSize, displayRegister(frame.level, address.level), + address.displacement); + if (V.indexed) + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + if (V.offset != 0) { + emit(Machine.LOADLop, 0, 0, V.offset); + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + } + emit(Machine.LOADIop, valSize, 0, 0); + } + } + + // Generates code to compute and push the address of a named variable. + // vname is the program phrase that names this variable. + // currentLevel is the routine level where the vname occurs. + // frameSize is the anticipated size of the local stack frame when + // the variable is addressed at run-time. + + private void encodeFetchAddress(Vname V, Frame frame) { + + RuntimeEntity baseObject = (RuntimeEntity) V.visit(this, frame); + // If indexed = true, code will have been generated to load an index value. + if (baseObject instanceof KnownAddress) { + ObjectAddress address = ((KnownAddress) baseObject).address; + emit(Machine.LOADAop, 0, displayRegister(frame.level, address.level), address.displacement + V.offset); + if (V.indexed) + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + } else if (baseObject instanceof UnknownAddress) { + ObjectAddress address = ((UnknownAddress) baseObject).address; + emit(Machine.LOADop, Machine.addressSize, displayRegister(frame.level, address.level), + address.displacement); + if (V.indexed) + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + if (V.offset != 0) { + emit(Machine.LOADLop, 0, 0, V.offset); + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + } + } + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/EqualityRoutine.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/EqualityRoutine.java index 2ae074b..564e3ab 100644 --- a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/EqualityRoutine.java +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/EqualityRoutine.java @@ -16,15 +16,15 @@ package Triangle.CodeGenerator; public class EqualityRoutine extends RuntimeEntity { - public EqualityRoutine() { - super(); - } + public EqualityRoutine() { + super(); + } - public EqualityRoutine(int size, int displacement) { - super(size); - this.displacement = displacement; - } + public EqualityRoutine(int size, int displacement) { + super(size); + this.displacement = displacement; + } - public int displacement; + public int displacement; } diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Field.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Field.java index 6697e61..7906945 100644 --- a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Field.java +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Field.java @@ -16,16 +16,16 @@ package Triangle.CodeGenerator; public class Field extends RuntimeEntity { - public Field() { - super(); - fieldOffset = 0; - } + public Field() { + super(); + fieldOffset = 0; + } - public Field(int size, int fieldOffset) { - super(size); - this.fieldOffset = fieldOffset; - } + public Field(int size, int fieldOffset) { + super(size); + this.fieldOffset = fieldOffset; + } - public int fieldOffset; + public int fieldOffset; } diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Frame.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Frame.java index 7b8066f..2d784d8 100644 --- a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Frame.java +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Frame.java @@ -16,31 +16,31 @@ package Triangle.CodeGenerator; public class Frame { - public Frame() { - this.level = 0; - this.size = 0; - } - - public Frame(int level, Integer size) { - this.level = level; - this.size = size.intValue(); - } - - public Frame(int level, int size) { - this.level = level; - this.size = size; - } - - public Frame(Frame frame, int sizeIncrement) { - this.level = frame.level; - this.size = frame.size + sizeIncrement; - } - - public Frame(Frame frame, Integer sizeIncrement) { - this.level = frame.level; - this.size = frame.size + sizeIncrement.intValue(); - } - - protected int level; - protected int size; + public Frame() { + this.level = 0; + this.size = 0; + } + + public Frame(int level, Integer size) { + this.level = level; + this.size = size.intValue(); + } + + public Frame(int level, int size) { + this.level = level; + this.size = size; + } + + public Frame(Frame frame, int sizeIncrement) { + this.level = frame.level; + this.size = frame.size + sizeIncrement; + } + + public Frame(Frame frame, Integer sizeIncrement) { + this.level = frame.level; + this.size = frame.size + sizeIncrement.intValue(); + } + + protected int level; + protected int size; } diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownAddress.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownAddress.java index f36a95b..3e84c59 100644 --- a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownAddress.java +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownAddress.java @@ -16,16 +16,16 @@ package Triangle.CodeGenerator; public class KnownAddress extends RuntimeEntity { - public KnownAddress() { - super(); - address = null; - } + public KnownAddress() { + super(); + address = null; + } - public KnownAddress(int size, int level, int displacement) { - super(size); - address = new ObjectAddress(level, displacement); - } + public KnownAddress(int size, int level, int displacement) { + super(size); + address = new ObjectAddress(level, displacement); + } - public ObjectAddress address; + public ObjectAddress address; } diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownRoutine.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownRoutine.java index 3e05661..4262c6b 100644 --- a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownRoutine.java +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownRoutine.java @@ -16,16 +16,16 @@ package Triangle.CodeGenerator; public class KnownRoutine extends RuntimeEntity { - public KnownRoutine() { - super(); - address = null; - } + public KnownRoutine() { + super(); + address = null; + } - public KnownRoutine(int size, int level, int displacement) { - super(size); - address = new ObjectAddress(level, displacement); - } + public KnownRoutine(int size, int level, int displacement) { + super(size); + address = new ObjectAddress(level, displacement); + } - public ObjectAddress address; + public ObjectAddress address; } diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownValue.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownValue.java index 24635f2..2144a6a 100644 --- a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownValue.java +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownValue.java @@ -16,16 +16,16 @@ package Triangle.CodeGenerator; public class KnownValue extends RuntimeEntity { - public KnownValue() { - super(); - value = 0; - } + public KnownValue() { + super(); + value = 0; + } - public KnownValue(int size, int value) { - super(size); - this.value = value; - } + public KnownValue(int size, int value) { + super(size); + this.value = value; + } - public int value; + public int value; } diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/ObjectAddress.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/ObjectAddress.java index db1156a..05df9fc 100644 --- a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/ObjectAddress.java +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/ObjectAddress.java @@ -16,11 +16,11 @@ package Triangle.CodeGenerator; public final class ObjectAddress { - public ObjectAddress(int level, int displacement) { - this.level = level; - this.displacement = displacement; - } + public ObjectAddress(int level, int displacement) { + this.level = level; + this.displacement = displacement; + } - public int level, displacement; + public int level, displacement; } diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/PrimitiveRoutine.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/PrimitiveRoutine.java index 37e6894..e857dd5 100644 --- a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/PrimitiveRoutine.java +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/PrimitiveRoutine.java @@ -16,16 +16,16 @@ package Triangle.CodeGenerator; public class PrimitiveRoutine extends RuntimeEntity { - public PrimitiveRoutine() { - super(); - displacement = 0; - } + public PrimitiveRoutine() { + super(); + displacement = 0; + } - public PrimitiveRoutine(int size, int displacement) { - super(size); - this.displacement = displacement; - } + public PrimitiveRoutine(int size, int displacement) { + super(size); + this.displacement = displacement; + } - public int displacement; + public int displacement; } diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/RuntimeEntity.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/RuntimeEntity.java index 40d4d21..69a1cf6 100644 --- a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/RuntimeEntity.java +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/RuntimeEntity.java @@ -18,16 +18,16 @@ package Triangle.CodeGenerator; public abstract class RuntimeEntity { - public final static int maxRoutineLevel = 7; + public final static int maxRoutineLevel = 7; - public RuntimeEntity() { - size = 0; - } + public RuntimeEntity() { + size = 0; + } - public RuntimeEntity(int size) { - this.size = size; - } + public RuntimeEntity(int size) { + this.size = size; + } - public int size; + public int size; } diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/TypeRepresentation.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/TypeRepresentation.java index a14a087..ebe50c0 100644 --- a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/TypeRepresentation.java +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/TypeRepresentation.java @@ -16,8 +16,8 @@ package Triangle.CodeGenerator; public class TypeRepresentation extends RuntimeEntity { - public TypeRepresentation(int size) { - super(size); - } + public TypeRepresentation(int size) { + super(size); + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownAddress.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownAddress.java index f1e7605..d3ff717 100644 --- a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownAddress.java +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownAddress.java @@ -16,16 +16,16 @@ package Triangle.CodeGenerator; public class UnknownAddress extends RuntimeEntity { - public UnknownAddress() { - super(); - address = null; - } + public UnknownAddress() { + super(); + address = null; + } - public UnknownAddress(int size, int level, int displacement) { - super(size); - address = new ObjectAddress(level, displacement); - } + public UnknownAddress(int size, int level, int displacement) { + super(size); + address = new ObjectAddress(level, displacement); + } - public ObjectAddress address; + public ObjectAddress address; } diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownRoutine.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownRoutine.java index 58df472..0b2d4ea 100644 --- a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownRoutine.java +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownRoutine.java @@ -16,16 +16,16 @@ package Triangle.CodeGenerator; public class UnknownRoutine extends RuntimeEntity { - public UnknownRoutine() { - super(); - address = null; - } + public UnknownRoutine() { + super(); + address = null; + } - public UnknownRoutine(int size, int level, int displacement) { - super(size); - address = new ObjectAddress(level, displacement); - } + public UnknownRoutine(int size, int level, int displacement) { + super(size); + address = new ObjectAddress(level, displacement); + } - public ObjectAddress address; + public ObjectAddress address; } diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownValue.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownValue.java index c5d3085..3918607 100644 --- a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownValue.java +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownValue.java @@ -16,16 +16,16 @@ package Triangle.CodeGenerator; public class UnknownValue extends RuntimeEntity { - public UnknownValue() { - super(); - address = null; - } + public UnknownValue() { + super(); + address = null; + } - public UnknownValue(int size, int level, int displacement) { - super(size); - address = new ObjectAddress(level, displacement); - } + public UnknownValue(int size, int level, int displacement) { + super(size); + address = new ObjectAddress(level, displacement); + } - public ObjectAddress address; + public ObjectAddress address; } diff --git a/Triangle.Compiler/src/main/java/Triangle/Compiler.java b/Triangle.Compiler/src/main/java/Triangle/Compiler.java index 6e4be43..0fc04b1 100644 --- a/Triangle.Compiler/src/main/java/Triangle/Compiler.java +++ b/Triangle.Compiler/src/main/java/Triangle/Compiler.java @@ -30,98 +30,94 @@ import Triangle.TreeDrawer.Drawer; */ public class Compiler { - /** The filename for the object program, normally obj.tam. */ - static String objectName = "obj.tam"; - - private static Scanner scanner; - private static Parser parser; - private static Checker checker; - private static Encoder encoder; - private static ErrorReporter reporter; - private static Drawer drawer; - - /** The AST representing the source program. */ - private static Program theAST; - - /** - * Compile the source program to TAM machine code. - * - * @param sourceName the name of the file containing the - * source program. - * @param objectName the name of the file containing the - * object program. - * @param showingAST true iff the AST is to be displayed after - * contextual analysis (not currently implemented). - * @param showingTable true iff the object description details are to - * be displayed during code generation (not - * currently implemented). - * @return true iff the source program is free of compile-time errors, - * otherwise false. - */ - static boolean compileProgram(String sourceName, String objectName, - boolean showingAST, boolean showingTable) { - - System.out.println("********** " + - "Triangle Compiler (Java Version 2.1)" + - " **********"); - - System.out.println("Syntactic Analysis ..."); - SourceFile source = new SourceFile(sourceName); - - if (source == null) { - System.out.println("Can't access source file " + sourceName); - System.exit(1); - } - - scanner = new Scanner(source); - reporter = new ErrorReporter(); - parser = new Parser(scanner, reporter); - checker = new Checker(reporter); - encoder = new Encoder(reporter); - drawer = new Drawer(); - - // scanner.enableDebugging(); - theAST = parser.parseProgram(); // 1st pass - if (reporter.numErrors == 0) { - // if (showingAST) { - // drawer.draw(theAST); - // } - System.out.println("Contextual Analysis ..."); - checker.check(theAST); // 2nd pass - if (showingAST) { - drawer.draw(theAST); - } - if (reporter.numErrors == 0) { - System.out.println("Code Generation ..."); - encoder.encodeRun(theAST, showingTable); // 3rd pass - } - } - - boolean successful = (reporter.numErrors == 0); - if (successful) { - encoder.saveObjectProgram(objectName); - System.out.println("Compilation was successful."); - } else { - System.out.println("Compilation was unsuccessful."); - } - return successful; - } - - /** - * Triangle compiler main program. - * - * @param args the only command-line argument to the program specifies - * the source filename. - */ - public static void main(String[] args) { - boolean compiledOK; - - if (args.length != 1) { - System.out.println("Usage: tc filename"); - System.exit(1); - } - - String sourceName = args[0]; - compiledOK = compileProgram(sourceName, objectName, false, false); - } + /** The filename for the object program, normally obj.tam. */ + static String objectName = "obj.tam"; + + private static Scanner scanner; + private static Parser parser; + private static Checker checker; + private static Encoder encoder; + private static ErrorReporter reporter; + private static Drawer drawer; + + /** The AST representing the source program. */ + private static Program theAST; + + /** + * Compile the source program to TAM machine code. + * + * @param sourceName the name of the file containing the source program. + * @param objectName the name of the file containing the object program. + * @param showingAST true iff the AST is to be displayed after contextual + * analysis (not currently implemented). + * @param showingTable true iff the object description details are to be + * displayed during code generation (not currently + * implemented). + * @return true iff the source program is free of compile-time errors, otherwise + * false. + */ + static boolean compileProgram(String sourceName, String objectName, boolean showingAST, boolean showingTable) { + + System.out.println("********** " + "Triangle Compiler (Java Version 2.1)" + " **********"); + + System.out.println("Syntactic Analysis ..."); + SourceFile source = SourceFile.ofPath(sourceName); + + if (source == null) { + System.out.println("Can't access source file " + sourceName); + System.exit(1); + } + + scanner = new Scanner(source); + reporter = new ErrorReporter(); + parser = new Parser(scanner, reporter); + checker = new Checker(reporter); + encoder = new Encoder(reporter); + drawer = new Drawer(); + + // scanner.enableDebugging(); + theAST = parser.parseProgram(); // 1st pass + if (reporter.numErrors == 0) { + // if (showingAST) { + // drawer.draw(theAST); + // } + System.out.println("Contextual Analysis ..."); + checker.check(theAST); // 2nd pass + if (showingAST) { + drawer.draw(theAST); + } + if (reporter.numErrors == 0) { + System.out.println("Code Generation ..."); + encoder.encodeRun(theAST, showingTable); // 3rd pass + } + } + + boolean successful = (reporter.numErrors == 0); + if (successful) { + encoder.saveObjectProgram(objectName); + System.out.println("Compilation was successful."); + } else { + System.out.println("Compilation was unsuccessful."); + } + return successful; + } + + /** + * Triangle compiler main program. + * + * @param args the only command-line argument to the program specifies the + * source filename. + */ + public static void main(String[] args) { + + if (args.length != 1) { + System.out.println("Usage: tc filename"); + System.exit(1); + } + + String sourceName = args[0]; + var compiledOK = compileProgram(sourceName, objectName, false, false); + + System.exit(compiledOK ? 0 : 1); + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/Checker.java b/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/Checker.java index 13a82bf..d64fac6 100644 --- a/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/Checker.java +++ b/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/Checker.java @@ -89,925 +89,886 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public final class Checker implements Visitor { - // Commands - - // Always returns null. Does not use the given object. - - @Override -public Object visitAssignCommand(AssignCommand ast, Object o) { - TypeDenoter vType = (TypeDenoter) ast.V.visit(this, null); - TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); - if (!ast.V.variable) - reporter.reportError("LHS of assignment is not a variable", "", ast.V.position); - if (!eType.equals(vType)) - reporter.reportError("assignment incompatibilty", "", ast.position); - return null; - } - - @Override -public Object visitCallCommand(CallCommand ast, Object o) { - - Declaration binding = (Declaration) ast.I.visit(this, null); - if (binding == null) - reportUndeclared(ast.I); - else if (binding instanceof ProcDeclaration) { - ast.APS.visit(this, ((ProcDeclaration) binding).FPS); - } else if (binding instanceof ProcFormalParameter) { - ast.APS.visit(this, ((ProcFormalParameter) binding).FPS); - } else - reporter.reportError("\"%\" is not a procedure identifier", - ast.I.spelling, ast.I.position); - return null; - } - - @Override -public Object visitEmptyCommand(EmptyCommand ast, Object o) { - return null; - } - - @Override -public Object visitIfCommand(IfCommand ast, Object o) { - TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); - if (!eType.equals(StdEnvironment.booleanType)) - reporter.reportError("Boolean expression expected here", "", ast.E.position); - ast.C1.visit(this, null); - ast.C2.visit(this, null); - return null; - } - - @Override -public Object visitLetCommand(LetCommand ast, Object o) { - idTable.openScope(); - ast.D.visit(this, null); - ast.C.visit(this, null); - idTable.closeScope(); - return null; - } - - @Override -public Object visitSequentialCommand(SequentialCommand ast, Object o) { - ast.C1.visit(this, null); - ast.C2.visit(this, null); - return null; - } - - @Override -public Object visitWhileCommand(WhileCommand ast, Object o) { - TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); - if (!eType.equals(StdEnvironment.booleanType)) - reporter.reportError("Boolean expression expected here", "", ast.E.position); - ast.C.visit(this, null); - return null; - } - - // Expressions - - // Returns the TypeDenoter denoting the type of the expression. Does - // not use the given object. - - @Override -public Object visitArrayExpression(ArrayExpression ast, Object o) { - TypeDenoter elemType = (TypeDenoter) ast.AA.visit(this, null); - IntegerLiteral il = new IntegerLiteral(Integer.valueOf(ast.AA.elemCount).toString(), - ast.position); - ast.type = new ArrayTypeDenoter(il, elemType, ast.position); - return ast.type; - } - - @Override -public Object visitBinaryExpression(BinaryExpression ast, Object o) { - - TypeDenoter e1Type = (TypeDenoter) ast.E1.visit(this, null); - TypeDenoter e2Type = (TypeDenoter) ast.E2.visit(this, null); - Declaration binding = (Declaration) ast.O.visit(this, null); - - if (binding == null) - reportUndeclared(ast.O); - else { - if (!(binding instanceof BinaryOperatorDeclaration)) - reporter.reportError("\"%\" is not a binary operator", - ast.O.spelling, ast.O.position); - BinaryOperatorDeclaration bbinding = (BinaryOperatorDeclaration) binding; - if (bbinding.ARG1 == StdEnvironment.anyType) { - // this operator must be "=" or "\=" - if (!e1Type.equals(e2Type)) - reporter.reportError("incompatible argument types for \"%\"", - ast.O.spelling, ast.position); - } else if (!e1Type.equals(bbinding.ARG1)) - reporter.reportError("wrong argument type for \"%\"", - ast.O.spelling, ast.E1.position); - else if (!e2Type.equals(bbinding.ARG2)) - reporter.reportError("wrong argument type for \"%\"", - ast.O.spelling, ast.E2.position); - ast.type = bbinding.RES; - } - return ast.type; - } - - @Override -public Object visitCallExpression(CallExpression ast, Object o) { - Declaration binding = (Declaration) ast.I.visit(this, null); - if (binding == null) { - reportUndeclared(ast.I); - ast.type = StdEnvironment.errorType; - } else if (binding instanceof FuncDeclaration) { - ast.APS.visit(this, ((FuncDeclaration) binding).FPS); - ast.type = ((FuncDeclaration) binding).T; - } else if (binding instanceof FuncFormalParameter) { - ast.APS.visit(this, ((FuncFormalParameter) binding).FPS); - ast.type = ((FuncFormalParameter) binding).T; - } else - reporter.reportError("\"%\" is not a function identifier", - ast.I.spelling, ast.I.position); - return ast.type; - } - - @Override -public Object visitCharacterExpression(CharacterExpression ast, Object o) { - ast.type = StdEnvironment.charType; - return ast.type; - } - - @Override -public Object visitEmptyExpression(EmptyExpression ast, Object o) { - ast.type = null; - return ast.type; - } - - @Override -public Object visitIfExpression(IfExpression ast, Object o) { - TypeDenoter e1Type = (TypeDenoter) ast.E1.visit(this, null); - if (!e1Type.equals(StdEnvironment.booleanType)) - reporter.reportError("Boolean expression expected here", "", - ast.E1.position); - TypeDenoter e2Type = (TypeDenoter) ast.E2.visit(this, null); - TypeDenoter e3Type = (TypeDenoter) ast.E3.visit(this, null); - if (!e2Type.equals(e3Type)) - reporter.reportError("incompatible limbs in if-expression", "", ast.position); - ast.type = e2Type; - return ast.type; - } - - @Override -public Object visitIntegerExpression(IntegerExpression ast, Object o) { - ast.type = StdEnvironment.integerType; - return ast.type; - } - - @Override -public Object visitLetExpression(LetExpression ast, Object o) { - idTable.openScope(); - ast.D.visit(this, null); - ast.type = (TypeDenoter) ast.E.visit(this, null); - idTable.closeScope(); - return ast.type; - } - - @Override -public Object visitRecordExpression(RecordExpression ast, Object o) { - FieldTypeDenoter rType = (FieldTypeDenoter) ast.RA.visit(this, null); - ast.type = new RecordTypeDenoter(rType, ast.position); - return ast.type; - } - - @Override -public Object visitUnaryExpression(UnaryExpression ast, Object o) { - - TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); - Declaration binding = (Declaration) ast.O.visit(this, null); - if (binding == null) { - reportUndeclared(ast.O); - ast.type = StdEnvironment.errorType; - } else if (!(binding instanceof UnaryOperatorDeclaration)) - reporter.reportError("\"%\" is not a unary operator", - ast.O.spelling, ast.O.position); - else { - UnaryOperatorDeclaration ubinding = (UnaryOperatorDeclaration) binding; - if (!eType.equals(ubinding.ARG)) - reporter.reportError("wrong argument type for \"%\"", - ast.O.spelling, ast.O.position); - ast.type = ubinding.RES; - } - return ast.type; - } - - @Override -public Object visitVnameExpression(VnameExpression ast, Object o) { - ast.type = (TypeDenoter) ast.V.visit(this, null); - return ast.type; - } - - // Declarations - - // Always returns null. Does not use the given object. - @Override -public Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Object o) { - return null; - } - - @Override -public Object visitConstDeclaration(ConstDeclaration ast, Object o) { - TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); - idTable.enter(ast.I.spelling, ast); - if (ast.duplicated) - reporter.reportError("identifier \"%\" already declared", - ast.I.spelling, ast.position); - return null; - } - - @Override -public Object visitFuncDeclaration(FuncDeclaration ast, Object o) { - ast.T = (TypeDenoter) ast.T.visit(this, null); - idTable.enter(ast.I.spelling, ast); // permits recursion - if (ast.duplicated) - reporter.reportError("identifier \"%\" already declared", - ast.I.spelling, ast.position); - idTable.openScope(); - ast.FPS.visit(this, null); - TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); - idTable.closeScope(); - if (!ast.T.equals(eType)) - reporter.reportError("body of function \"%\" has wrong type", - ast.I.spelling, ast.E.position); - return null; - } - - @Override -public Object visitProcDeclaration(ProcDeclaration ast, Object o) { - idTable.enter(ast.I.spelling, ast); // permits recursion - if (ast.duplicated) - reporter.reportError("identifier \"%\" already declared", - ast.I.spelling, ast.position); - idTable.openScope(); - ast.FPS.visit(this, null); - ast.C.visit(this, null); - idTable.closeScope(); - return null; - } - - @Override -public Object visitSequentialDeclaration(SequentialDeclaration ast, Object o) { - ast.D1.visit(this, null); - ast.D2.visit(this, null); - return null; - } - - @Override -public Object visitTypeDeclaration(TypeDeclaration ast, Object o) { - ast.T = (TypeDenoter) ast.T.visit(this, null); - idTable.enter(ast.I.spelling, ast); - if (ast.duplicated) - reporter.reportError("identifier \"%\" already declared", - ast.I.spelling, ast.position); - return null; - } - - @Override -public Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Object o) { - return null; - } - - @Override -public Object visitVarDeclaration(VarDeclaration ast, Object o) { - ast.T = (TypeDenoter) ast.T.visit(this, null); - idTable.enter(ast.I.spelling, ast); - if (ast.duplicated) - reporter.reportError("identifier \"%\" already declared", - ast.I.spelling, ast.position); - - return null; - } - - // Array Aggregates - - // Returns the TypeDenoter for the Array Aggregate. Does not use the - // given object. - - @Override -public Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, Object o) { - TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); - TypeDenoter elemType = (TypeDenoter) ast.AA.visit(this, null); - ast.elemCount = ast.AA.elemCount + 1; - if (!eType.equals(elemType)) - reporter.reportError("incompatible array-aggregate element", "", ast.E.position); - return elemType; - } - - @Override -public Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object o) { - TypeDenoter elemType = (TypeDenoter) ast.E.visit(this, null); - ast.elemCount = 1; - return elemType; - } - - // Record Aggregates - - // Returns the TypeDenoter for the Record Aggregate. Does not use the - // given object. - - @Override -public Object visitMultipleRecordAggregate(MultipleRecordAggregate ast, Object o) { - TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); - FieldTypeDenoter rType = (FieldTypeDenoter) ast.RA.visit(this, null); - TypeDenoter fType = checkFieldIdentifier(rType, ast.I); - if (fType != StdEnvironment.errorType) - reporter.reportError("duplicate field \"%\" in record", - ast.I.spelling, ast.I.position); - ast.type = new MultipleFieldTypeDenoter(ast.I, eType, rType, ast.position); - return ast.type; - } - - @Override -public Object visitSingleRecordAggregate(SingleRecordAggregate ast, Object o) { - TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); - ast.type = new SingleFieldTypeDenoter(ast.I, eType, ast.position); - return ast.type; - } - - // Formal Parameters - - // Always returns null. Does not use the given object. - - @Override -public Object visitConstFormalParameter(ConstFormalParameter ast, Object o) { - ast.T = (TypeDenoter) ast.T.visit(this, null); - idTable.enter(ast.I.spelling, ast); - if (ast.duplicated) - reporter.reportError("duplicated formal parameter \"%\"", - ast.I.spelling, ast.position); - return null; - } - - @Override -public Object visitFuncFormalParameter(FuncFormalParameter ast, Object o) { - idTable.openScope(); - ast.FPS.visit(this, null); - idTable.closeScope(); - ast.T = (TypeDenoter) ast.T.visit(this, null); - idTable.enter(ast.I.spelling, ast); - if (ast.duplicated) - reporter.reportError("duplicated formal parameter \"%\"", - ast.I.spelling, ast.position); - return null; - } - - @Override -public Object visitProcFormalParameter(ProcFormalParameter ast, Object o) { - idTable.openScope(); - ast.FPS.visit(this, null); - idTable.closeScope(); - idTable.enter(ast.I.spelling, ast); - if (ast.duplicated) - reporter.reportError("duplicated formal parameter \"%\"", - ast.I.spelling, ast.position); - return null; - } - - @Override -public Object visitVarFormalParameter(VarFormalParameter ast, Object o) { - ast.T = (TypeDenoter) ast.T.visit(this, null); - idTable.enter(ast.I.spelling, ast); - if (ast.duplicated) - reporter.reportError("duplicated formal parameter \"%\"", - ast.I.spelling, ast.position); - return null; - } - - @Override -public Object visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Object o) { - return null; - } - - @Override -public Object visitMultipleFormalParameterSequence(MultipleFormalParameterSequence ast, Object o) { - ast.FP.visit(this, null); - ast.FPS.visit(this, null); - return null; - } - - @Override -public Object visitSingleFormalParameterSequence(SingleFormalParameterSequence ast, Object o) { - ast.FP.visit(this, null); - return null; - } - - // Actual Parameters - - // Always returns null. Uses the given FormalParameter. - - @Override -public Object visitConstActualParameter(ConstActualParameter ast, Object o) { - FormalParameter fp = (FormalParameter) o; - TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); - - if (!(fp instanceof ConstFormalParameter)) - reporter.reportError("const actual parameter not expected here", "", - ast.position); - else if (!eType.equals(((ConstFormalParameter) fp).T)) - reporter.reportError("wrong type for const actual parameter", "", - ast.E.position); - return null; - } - - @Override -public Object visitFuncActualParameter(FuncActualParameter ast, Object o) { - FormalParameter fp = (FormalParameter) o; - - Declaration binding = (Declaration) ast.I.visit(this, null); - if (binding == null) - reportUndeclared(ast.I); - else if (!(binding instanceof FuncDeclaration || - binding instanceof FuncFormalParameter)) - reporter.reportError("\"%\" is not a function identifier", - ast.I.spelling, ast.I.position); - else if (!(fp instanceof FuncFormalParameter)) - reporter.reportError("func actual parameter not expected here", "", - ast.position); - else { - FormalParameterSequence FPS = null; - TypeDenoter T = null; - if (binding instanceof FuncDeclaration) { - FPS = ((FuncDeclaration) binding).FPS; - T = ((FuncDeclaration) binding).T; - } else { - FPS = ((FuncFormalParameter) binding).FPS; - T = ((FuncFormalParameter) binding).T; - } - if (!FPS.equals(((FuncFormalParameter) fp).FPS)) - reporter.reportError("wrong signature for function \"%\"", - ast.I.spelling, ast.I.position); - else if (!T.equals(((FuncFormalParameter) fp).T)) - reporter.reportError("wrong type for function \"%\"", - ast.I.spelling, ast.I.position); - } - return null; - } - - @Override -public Object visitProcActualParameter(ProcActualParameter ast, Object o) { - FormalParameter fp = (FormalParameter) o; - - Declaration binding = (Declaration) ast.I.visit(this, null); - if (binding == null) - reportUndeclared(ast.I); - else if (!(binding instanceof ProcDeclaration || - binding instanceof ProcFormalParameter)) - reporter.reportError("\"%\" is not a procedure identifier", - ast.I.spelling, ast.I.position); - else if (!(fp instanceof ProcFormalParameter)) - reporter.reportError("proc actual parameter not expected here", "", - ast.position); - else { - FormalParameterSequence FPS = null; - if (binding instanceof ProcDeclaration) - FPS = ((ProcDeclaration) binding).FPS; - else - FPS = ((ProcFormalParameter) binding).FPS; - if (!FPS.equals(((ProcFormalParameter) fp).FPS)) - reporter.reportError("wrong signature for procedure \"%\"", - ast.I.spelling, ast.I.position); - } - return null; - } - - @Override -public Object visitVarActualParameter(VarActualParameter ast, Object o) { - FormalParameter fp = (FormalParameter) o; - - TypeDenoter vType = (TypeDenoter) ast.V.visit(this, null); - if (!ast.V.variable) - reporter.reportError("actual parameter is not a variable", "", - ast.V.position); - else if (!(fp instanceof VarFormalParameter)) - reporter.reportError("var actual parameter not expected here", "", - ast.V.position); - else if (!vType.equals(((VarFormalParameter) fp).T)) - reporter.reportError("wrong type for var actual parameter", "", - ast.V.position); - return null; - } - - @Override -public Object visitEmptyActualParameterSequence(EmptyActualParameterSequence ast, Object o) { - FormalParameterSequence fps = (FormalParameterSequence) o; - if (!(fps instanceof EmptyFormalParameterSequence)) - reporter.reportError("too few actual parameters", "", ast.position); - return null; - } - - @Override -public Object visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, Object o) { - FormalParameterSequence fps = (FormalParameterSequence) o; - if (!(fps instanceof MultipleFormalParameterSequence)) - reporter.reportError("too many actual parameters", "", ast.position); - else { - ast.AP.visit(this, ((MultipleFormalParameterSequence) fps).FP); - ast.APS.visit(this, ((MultipleFormalParameterSequence) fps).FPS); - } - return null; - } - - @Override -public Object visitSingleActualParameterSequence(SingleActualParameterSequence ast, Object o) { - FormalParameterSequence fps = (FormalParameterSequence) o; - if (!(fps instanceof SingleFormalParameterSequence)) - reporter.reportError("incorrect number of actual parameters", "", ast.position); - else { - ast.AP.visit(this, ((SingleFormalParameterSequence) fps).FP); - } - return null; - } - - // Type Denoters - - // Returns the expanded version of the TypeDenoter. Does not - // use the given object. - - @Override -public Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object o) { - return StdEnvironment.anyType; - } - - @Override -public Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object o) { - ast.T = (TypeDenoter) ast.T.visit(this, null); - if ((Integer.valueOf(ast.IL.spelling).intValue()) == 0) - reporter.reportError("arrays must not be empty", "", ast.IL.position); - return ast; - } - - @Override -public Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object o) { - return StdEnvironment.booleanType; - } - - @Override -public Object visitCharTypeDenoter(CharTypeDenoter ast, Object o) { - return StdEnvironment.charType; - } - - @Override -public Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object o) { - return StdEnvironment.errorType; - } - - @Override -public Object visitSimpleTypeDenoter(SimpleTypeDenoter ast, Object o) { - Declaration binding = (Declaration) ast.I.visit(this, null); - if (binding == null) { - reportUndeclared(ast.I); - return StdEnvironment.errorType; - } else if (!(binding instanceof TypeDeclaration)) { - reporter.reportError("\"%\" is not a type identifier", - ast.I.spelling, ast.I.position); - return StdEnvironment.errorType; - } - return ((TypeDeclaration) binding).T; - } - - @Override -public Object visitIntTypeDenoter(IntTypeDenoter ast, Object o) { - return StdEnvironment.integerType; - } - - @Override -public Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object o) { - ast.FT = (FieldTypeDenoter) ast.FT.visit(this, null); - return ast; - } - - @Override -public Object visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, Object o) { - ast.T = (TypeDenoter) ast.T.visit(this, null); - ast.FT.visit(this, null); - return ast; - } - - @Override -public Object visitSingleFieldTypeDenoter(SingleFieldTypeDenoter ast, Object o) { - ast.T = (TypeDenoter) ast.T.visit(this, null); - return ast; - } - - // Literals, Identifiers and Operators - @Override -public Object visitCharacterLiteral(CharacterLiteral CL, Object o) { - return StdEnvironment.charType; - } - - @Override -public Object visitIdentifier(Identifier I, Object o) { - Declaration binding = idTable.retrieve(I.spelling); - if (binding != null) - I.decl = binding; - return binding; - } - - @Override -public Object visitIntegerLiteral(IntegerLiteral IL, Object o) { - return StdEnvironment.integerType; - } - - @Override -public Object visitOperator(Operator O, Object o) { - Declaration binding = idTable.retrieve(O.spelling); - if (binding != null) - O.decl = binding; - return binding; - } - - // Value-or-variable names - - // Determines the address of a named object (constant or variable). - // This consists of a base object, to which 0 or more field-selection - // or array-indexing operations may be applied (if it is a record or - // array). As much as possible of the address computation is done at - // compile-time. Code is generated only when necessary to evaluate - // index expressions at run-time. - // currentLevel is the routine level where the v-name occurs. - // frameSize is the anticipated size of the local stack frame when - // the object is addressed at run-time. - // It returns the description of the base object. - // offset is set to the total of any field offsets (plus any offsets - // due to index expressions that happen to be literals). - // indexed is set to true iff there are any index expressions (other - // than literals). In that case code is generated to compute the - // offset due to these indexing operations at run-time. - - // Returns the TypeDenoter of the Vname. Does not use the - // given object. - - @Override -public Object visitDotVname(DotVname ast, Object o) { - ast.type = null; - TypeDenoter vType = (TypeDenoter) ast.V.visit(this, null); - ast.variable = ast.V.variable; - if (!(vType instanceof RecordTypeDenoter)) - reporter.reportError("record expected here", "", ast.V.position); - else { - ast.type = checkFieldIdentifier(((RecordTypeDenoter) vType).FT, ast.I); - if (ast.type == StdEnvironment.errorType) - reporter.reportError("no field \"%\" in this record type", - ast.I.spelling, ast.I.position); - } - return ast.type; - } - - @Override -public Object visitSimpleVname(SimpleVname ast, Object o) { - ast.variable = false; - ast.type = StdEnvironment.errorType; - Declaration binding = (Declaration) ast.I.visit(this, null); - if (binding == null) - reportUndeclared(ast.I); - else if (binding instanceof ConstDeclaration) { - ast.type = ((ConstDeclaration) binding).E.type; - ast.variable = false; - } else if (binding instanceof VarDeclaration) { - ast.type = ((VarDeclaration) binding).T; - ast.variable = true; - } else if (binding instanceof ConstFormalParameter) { - ast.type = ((ConstFormalParameter) binding).T; - ast.variable = false; - } else if (binding instanceof VarFormalParameter) { - ast.type = ((VarFormalParameter) binding).T; - ast.variable = true; - } else - reporter.reportError("\"%\" is not a const or var identifier", - ast.I.spelling, ast.I.position); - return ast.type; - } - - @Override -public Object visitSubscriptVname(SubscriptVname ast, Object o) { - TypeDenoter vType = (TypeDenoter) ast.V.visit(this, null); - ast.variable = ast.V.variable; - TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); - if (vType != StdEnvironment.errorType) { - if (!(vType instanceof ArrayTypeDenoter)) - reporter.reportError("array expected here", "", ast.V.position); - else { - if (!eType.equals(StdEnvironment.integerType)) - reporter.reportError("Integer expression expected here", "", - ast.E.position); - ast.type = ((ArrayTypeDenoter) vType).T; - } - } - return ast.type; - } - - // Programs - - @Override -public Object visitProgram(Program ast, Object o) { - ast.C.visit(this, null); - return null; - } - - // Checks whether the source program, represented by its AST, satisfies the - // language's scope rules and type rules. - // Also decorates the AST as follows: - // (a) Each applied occurrence of an identifier or operator is linked to - // the corresponding declaration of that identifier or operator. - // (b) Each expression and value-or-variable-name is decorated by its type. - // (c) Each type identifier is replaced by the type it denotes. - // Types are represented by small ASTs. - - public void check(Program ast) { - ast.visit(this, null); - } - - ///////////////////////////////////////////////////////////////////////////// - - public Checker(ErrorReporter reporter) { - this.reporter = reporter; - this.idTable = new IdentificationTable(); - establishStdEnvironment(); - } - - private IdentificationTable idTable; - private static SourcePosition dummyPos = new SourcePosition(); - private ErrorReporter reporter; - - // Reports that the identifier or operator used at a leaf of the AST - // has not been declared. - - private void reportUndeclared(Terminal leaf) { - reporter.reportError("\"%\" is not declared", leaf.spelling, leaf.position); - } - - private static TypeDenoter checkFieldIdentifier(FieldTypeDenoter ast, Identifier I) { - if (ast instanceof MultipleFieldTypeDenoter) { - MultipleFieldTypeDenoter ft = (MultipleFieldTypeDenoter) ast; - if (ft.I.spelling.compareTo(I.spelling) == 0) { - I.decl = ast; - return ft.T; - } else { - return checkFieldIdentifier(ft.FT, I); - } - } else if (ast instanceof SingleFieldTypeDenoter) { - SingleFieldTypeDenoter ft = (SingleFieldTypeDenoter) ast; - if (ft.I.spelling.compareTo(I.spelling) == 0) { - I.decl = ast; - return ft.T; - } - } - return StdEnvironment.errorType; - } - - // Creates a small AST to represent the "declaration" of a standard - // type, and enters it in the identification table. - - private TypeDeclaration declareStdType(String id, TypeDenoter typedenoter) { - - TypeDeclaration binding; - - binding = new TypeDeclaration(new Identifier(id, dummyPos), typedenoter, dummyPos); - idTable.enter(id, binding); - return binding; - } - - // Creates a small AST to represent the "declaration" of a standard - // type, and enters it in the identification table. - - private ConstDeclaration declareStdConst(String id, TypeDenoter constType) { - - IntegerExpression constExpr; - ConstDeclaration binding; - - // constExpr used only as a placeholder for constType - constExpr = new IntegerExpression(null, dummyPos); - constExpr.type = constType; - binding = new ConstDeclaration(new Identifier(id, dummyPos), constExpr, dummyPos); - idTable.enter(id, binding); - return binding; - } - - // Creates a small AST to represent the "declaration" of a standard - // type, and enters it in the identification table. - - private ProcDeclaration declareStdProc(String id, FormalParameterSequence fps) { - - ProcDeclaration binding; - - binding = new ProcDeclaration(new Identifier(id, dummyPos), fps, - new EmptyCommand(dummyPos), dummyPos); - idTable.enter(id, binding); - return binding; - } - - // Creates a small AST to represent the "declaration" of a standard - // type, and enters it in the identification table. - - private FuncDeclaration declareStdFunc(String id, FormalParameterSequence fps, - TypeDenoter resultType) { - - FuncDeclaration binding; - - binding = new FuncDeclaration(new Identifier(id, dummyPos), fps, resultType, - new EmptyExpression(dummyPos), dummyPos); - idTable.enter(id, binding); - return binding; - } - - // Creates a small AST to represent the "declaration" of a - // unary operator, and enters it in the identification table. - // This "declaration" summarises the operator's type info. - - private UnaryOperatorDeclaration declareStdUnaryOp(String op, TypeDenoter argType, TypeDenoter resultType) { - - UnaryOperatorDeclaration binding; - - binding = new UnaryOperatorDeclaration(new Operator(op, dummyPos), - argType, resultType, dummyPos); - idTable.enter(op, binding); - return binding; - } - - // Creates a small AST to represent the "declaration" of a - // binary operator, and enters it in the identification table. - // This "declaration" summarises the operator's type info. - - private BinaryOperatorDeclaration declareStdBinaryOp(String op, TypeDenoter arg1Type, TypeDenoter arg2type, - TypeDenoter resultType) { - - BinaryOperatorDeclaration binding; - - binding = new BinaryOperatorDeclaration(new Operator(op, dummyPos), - arg1Type, arg2type, resultType, dummyPos); - idTable.enter(op, binding); - return binding; - } - - // Creates small ASTs to represent the standard types. - // Creates small ASTs to represent "declarations" of standard types, - // constants, procedures, functions, and operators. - // Enters these "declarations" in the identification table. - - private final static Identifier dummyI = new Identifier("", dummyPos); - - private void establishStdEnvironment() { - - // idTable.startIdentification(); - StdEnvironment.booleanType = new BoolTypeDenoter(dummyPos); - StdEnvironment.integerType = new IntTypeDenoter(dummyPos); - StdEnvironment.charType = new CharTypeDenoter(dummyPos); - StdEnvironment.anyType = new AnyTypeDenoter(dummyPos); - StdEnvironment.errorType = new ErrorTypeDenoter(dummyPos); - - StdEnvironment.booleanDecl = declareStdType("Boolean", StdEnvironment.booleanType); - StdEnvironment.falseDecl = declareStdConst("false", StdEnvironment.booleanType); - StdEnvironment.trueDecl = declareStdConst("true", StdEnvironment.booleanType); - StdEnvironment.notDecl = declareStdUnaryOp("\\", StdEnvironment.booleanType, StdEnvironment.booleanType); - StdEnvironment.andDecl = declareStdBinaryOp("/\\", StdEnvironment.booleanType, StdEnvironment.booleanType, - StdEnvironment.booleanType); - StdEnvironment.orDecl = declareStdBinaryOp("\\/", StdEnvironment.booleanType, StdEnvironment.booleanType, - StdEnvironment.booleanType); - - StdEnvironment.integerDecl = declareStdType("Integer", StdEnvironment.integerType); - StdEnvironment.maxintDecl = declareStdConst("maxint", StdEnvironment.integerType); - StdEnvironment.addDecl = declareStdBinaryOp("+", StdEnvironment.integerType, StdEnvironment.integerType, - StdEnvironment.integerType); - StdEnvironment.subtractDecl = declareStdBinaryOp("-", StdEnvironment.integerType, StdEnvironment.integerType, - StdEnvironment.integerType); - StdEnvironment.multiplyDecl = declareStdBinaryOp("*", StdEnvironment.integerType, StdEnvironment.integerType, - StdEnvironment.integerType); - StdEnvironment.divideDecl = declareStdBinaryOp("/", StdEnvironment.integerType, StdEnvironment.integerType, - StdEnvironment.integerType); - StdEnvironment.moduloDecl = declareStdBinaryOp("//", StdEnvironment.integerType, StdEnvironment.integerType, - StdEnvironment.integerType); - StdEnvironment.lessDecl = declareStdBinaryOp("<", StdEnvironment.integerType, StdEnvironment.integerType, - StdEnvironment.booleanType); - StdEnvironment.notgreaterDecl = declareStdBinaryOp("<=", StdEnvironment.integerType, StdEnvironment.integerType, - StdEnvironment.booleanType); - StdEnvironment.greaterDecl = declareStdBinaryOp(">", StdEnvironment.integerType, StdEnvironment.integerType, - StdEnvironment.booleanType); - StdEnvironment.notlessDecl = declareStdBinaryOp(">=", StdEnvironment.integerType, StdEnvironment.integerType, - StdEnvironment.booleanType); - - StdEnvironment.charDecl = declareStdType("Char", StdEnvironment.charType); - StdEnvironment.chrDecl = declareStdFunc("chr", new SingleFormalParameterSequence( - new ConstFormalParameter(dummyI, StdEnvironment.integerType, dummyPos), dummyPos), StdEnvironment.charType); - StdEnvironment.ordDecl = declareStdFunc("ord", new SingleFormalParameterSequence( - new ConstFormalParameter(dummyI, StdEnvironment.charType, dummyPos), dummyPos), StdEnvironment.integerType); - StdEnvironment.eofDecl = declareStdFunc("eof", new EmptyFormalParameterSequence(dummyPos), - StdEnvironment.booleanType); - StdEnvironment.eolDecl = declareStdFunc("eol", new EmptyFormalParameterSequence(dummyPos), - StdEnvironment.booleanType); - StdEnvironment.getDecl = declareStdProc("get", new SingleFormalParameterSequence( - new VarFormalParameter(dummyI, StdEnvironment.charType, dummyPos), dummyPos)); - StdEnvironment.putDecl = declareStdProc("put", new SingleFormalParameterSequence( - new ConstFormalParameter(dummyI, StdEnvironment.charType, dummyPos), dummyPos)); - StdEnvironment.getintDecl = declareStdProc("getint", new SingleFormalParameterSequence( - new VarFormalParameter(dummyI, StdEnvironment.integerType, dummyPos), dummyPos)); - StdEnvironment.putintDecl = declareStdProc("putint", new SingleFormalParameterSequence( - new ConstFormalParameter(dummyI, StdEnvironment.integerType, dummyPos), dummyPos)); - StdEnvironment.geteolDecl = declareStdProc("geteol", new EmptyFormalParameterSequence(dummyPos)); - StdEnvironment.puteolDecl = declareStdProc("puteol", new EmptyFormalParameterSequence(dummyPos)); - StdEnvironment.equalDecl = declareStdBinaryOp("=", StdEnvironment.anyType, StdEnvironment.anyType, - StdEnvironment.booleanType); - StdEnvironment.unequalDecl = declareStdBinaryOp("\\=", StdEnvironment.anyType, StdEnvironment.anyType, - StdEnvironment.booleanType); - - } + // Commands + + // Always returns null. Does not use the given object. + + @Override + public Object visitAssignCommand(AssignCommand ast, Object o) { + TypeDenoter vType = (TypeDenoter) ast.V.visit(this, null); + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + if (!ast.V.variable) + reporter.reportError("LHS of assignment is not a variable", "", ast.V.position); + if (!eType.equals(vType)) + reporter.reportError("assignment incompatibilty", "", ast.position); + return null; + } + + @Override + public Object visitCallCommand(CallCommand ast, Object o) { + + Declaration binding = (Declaration) ast.I.visit(this, null); + if (binding == null) + reportUndeclared(ast.I); + else if (binding instanceof ProcDeclaration) { + ast.APS.visit(this, ((ProcDeclaration) binding).FPS); + } else if (binding instanceof ProcFormalParameter) { + ast.APS.visit(this, ((ProcFormalParameter) binding).FPS); + } else + reporter.reportError("\"%\" is not a procedure identifier", ast.I.spelling, ast.I.position); + return null; + } + + @Override + public Object visitEmptyCommand(EmptyCommand ast, Object o) { + return null; + } + + @Override + public Object visitIfCommand(IfCommand ast, Object o) { + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + if (!eType.equals(StdEnvironment.booleanType)) + reporter.reportError("Boolean expression expected here", "", ast.E.position); + ast.C1.visit(this, null); + ast.C2.visit(this, null); + return null; + } + + @Override + public Object visitLetCommand(LetCommand ast, Object o) { + idTable.openScope(); + ast.D.visit(this, null); + ast.C.visit(this, null); + idTable.closeScope(); + return null; + } + + @Override + public Object visitSequentialCommand(SequentialCommand ast, Object o) { + ast.C1.visit(this, null); + ast.C2.visit(this, null); + return null; + } + + @Override + public Object visitWhileCommand(WhileCommand ast, Object o) { + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + if (!eType.equals(StdEnvironment.booleanType)) + reporter.reportError("Boolean expression expected here", "", ast.E.position); + ast.C.visit(this, null); + return null; + } + + // Expressions + + // Returns the TypeDenoter denoting the type of the expression. Does + // not use the given object. + + @Override + public Object visitArrayExpression(ArrayExpression ast, Object o) { + TypeDenoter elemType = (TypeDenoter) ast.AA.visit(this, null); + IntegerLiteral il = new IntegerLiteral(Integer.valueOf(ast.AA.elemCount).toString(), ast.position); + ast.type = new ArrayTypeDenoter(il, elemType, ast.position); + return ast.type; + } + + @Override + public Object visitBinaryExpression(BinaryExpression ast, Object o) { + + TypeDenoter e1Type = (TypeDenoter) ast.E1.visit(this, null); + TypeDenoter e2Type = (TypeDenoter) ast.E2.visit(this, null); + Declaration binding = (Declaration) ast.O.visit(this, null); + + if (binding == null) + reportUndeclared(ast.O); + else { + if (!(binding instanceof BinaryOperatorDeclaration)) + reporter.reportError("\"%\" is not a binary operator", ast.O.spelling, ast.O.position); + BinaryOperatorDeclaration bbinding = (BinaryOperatorDeclaration) binding; + if (bbinding.ARG1 == StdEnvironment.anyType) { + // this operator must be "=" or "\=" + if (!e1Type.equals(e2Type)) + reporter.reportError("incompatible argument types for \"%\"", ast.O.spelling, ast.position); + } else if (!e1Type.equals(bbinding.ARG1)) + reporter.reportError("wrong argument type for \"%\"", ast.O.spelling, ast.E1.position); + else if (!e2Type.equals(bbinding.ARG2)) + reporter.reportError("wrong argument type for \"%\"", ast.O.spelling, ast.E2.position); + ast.type = bbinding.RES; + } + return ast.type; + } + + @Override + public Object visitCallExpression(CallExpression ast, Object o) { + Declaration binding = (Declaration) ast.I.visit(this, null); + if (binding == null) { + reportUndeclared(ast.I); + ast.type = StdEnvironment.errorType; + } else if (binding instanceof FuncDeclaration) { + ast.APS.visit(this, ((FuncDeclaration) binding).FPS); + ast.type = ((FuncDeclaration) binding).T; + } else if (binding instanceof FuncFormalParameter) { + ast.APS.visit(this, ((FuncFormalParameter) binding).FPS); + ast.type = ((FuncFormalParameter) binding).T; + } else + reporter.reportError("\"%\" is not a function identifier", ast.I.spelling, ast.I.position); + return ast.type; + } + + @Override + public Object visitCharacterExpression(CharacterExpression ast, Object o) { + ast.type = StdEnvironment.charType; + return ast.type; + } + + @Override + public Object visitEmptyExpression(EmptyExpression ast, Object o) { + ast.type = null; + return ast.type; + } + + @Override + public Object visitIfExpression(IfExpression ast, Object o) { + TypeDenoter e1Type = (TypeDenoter) ast.E1.visit(this, null); + if (!e1Type.equals(StdEnvironment.booleanType)) + reporter.reportError("Boolean expression expected here", "", ast.E1.position); + TypeDenoter e2Type = (TypeDenoter) ast.E2.visit(this, null); + TypeDenoter e3Type = (TypeDenoter) ast.E3.visit(this, null); + if (!e2Type.equals(e3Type)) + reporter.reportError("incompatible limbs in if-expression", "", ast.position); + ast.type = e2Type; + return ast.type; + } + + @Override + public Object visitIntegerExpression(IntegerExpression ast, Object o) { + ast.type = StdEnvironment.integerType; + return ast.type; + } + + @Override + public Object visitLetExpression(LetExpression ast, Object o) { + idTable.openScope(); + ast.D.visit(this, null); + ast.type = (TypeDenoter) ast.E.visit(this, null); + idTable.closeScope(); + return ast.type; + } + + @Override + public Object visitRecordExpression(RecordExpression ast, Object o) { + FieldTypeDenoter rType = (FieldTypeDenoter) ast.RA.visit(this, null); + ast.type = new RecordTypeDenoter(rType, ast.position); + return ast.type; + } + + @Override + public Object visitUnaryExpression(UnaryExpression ast, Object o) { + + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + Declaration binding = (Declaration) ast.O.visit(this, null); + if (binding == null) { + reportUndeclared(ast.O); + ast.type = StdEnvironment.errorType; + } else if (!(binding instanceof UnaryOperatorDeclaration)) + reporter.reportError("\"%\" is not a unary operator", ast.O.spelling, ast.O.position); + else { + UnaryOperatorDeclaration ubinding = (UnaryOperatorDeclaration) binding; + if (!eType.equals(ubinding.ARG)) + reporter.reportError("wrong argument type for \"%\"", ast.O.spelling, ast.O.position); + ast.type = ubinding.RES; + } + return ast.type; + } + + @Override + public Object visitVnameExpression(VnameExpression ast, Object o) { + ast.type = (TypeDenoter) ast.V.visit(this, null); + return ast.type; + } + + // Declarations + + // Always returns null. Does not use the given object. + @Override + public Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Object o) { + return null; + } + + @Override + public Object visitConstDeclaration(ConstDeclaration ast, Object o) { + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + idTable.enter(ast.I.spelling, ast); + if (ast.duplicated) + reporter.reportError("identifier \"%\" already declared", ast.I.spelling, ast.position); + return null; + } + + @Override + public Object visitFuncDeclaration(FuncDeclaration ast, Object o) { + ast.T = (TypeDenoter) ast.T.visit(this, null); + idTable.enter(ast.I.spelling, ast); // permits recursion + if (ast.duplicated) + reporter.reportError("identifier \"%\" already declared", ast.I.spelling, ast.position); + idTable.openScope(); + ast.FPS.visit(this, null); + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + idTable.closeScope(); + if (!ast.T.equals(eType)) + reporter.reportError("body of function \"%\" has wrong type", ast.I.spelling, ast.E.position); + return null; + } + + @Override + public Object visitProcDeclaration(ProcDeclaration ast, Object o) { + idTable.enter(ast.I.spelling, ast); // permits recursion + if (ast.duplicated) + reporter.reportError("identifier \"%\" already declared", ast.I.spelling, ast.position); + idTable.openScope(); + ast.FPS.visit(this, null); + ast.C.visit(this, null); + idTable.closeScope(); + return null; + } + + @Override + public Object visitSequentialDeclaration(SequentialDeclaration ast, Object o) { + ast.D1.visit(this, null); + ast.D2.visit(this, null); + return null; + } + + @Override + public Object visitTypeDeclaration(TypeDeclaration ast, Object o) { + ast.T = (TypeDenoter) ast.T.visit(this, null); + idTable.enter(ast.I.spelling, ast); + if (ast.duplicated) + reporter.reportError("identifier \"%\" already declared", ast.I.spelling, ast.position); + return null; + } + + @Override + public Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Object o) { + return null; + } + + @Override + public Object visitVarDeclaration(VarDeclaration ast, Object o) { + ast.T = (TypeDenoter) ast.T.visit(this, null); + idTable.enter(ast.I.spelling, ast); + if (ast.duplicated) + reporter.reportError("identifier \"%\" already declared", ast.I.spelling, ast.position); + + return null; + } + + // Array Aggregates + + // Returns the TypeDenoter for the Array Aggregate. Does not use the + // given object. + + @Override + public Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, Object o) { + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + TypeDenoter elemType = (TypeDenoter) ast.AA.visit(this, null); + ast.elemCount = ast.AA.elemCount + 1; + if (!eType.equals(elemType)) + reporter.reportError("incompatible array-aggregate element", "", ast.E.position); + return elemType; + } + + @Override + public Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object o) { + TypeDenoter elemType = (TypeDenoter) ast.E.visit(this, null); + ast.elemCount = 1; + return elemType; + } + + // Record Aggregates + + // Returns the TypeDenoter for the Record Aggregate. Does not use the + // given object. + + @Override + public Object visitMultipleRecordAggregate(MultipleRecordAggregate ast, Object o) { + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + FieldTypeDenoter rType = (FieldTypeDenoter) ast.RA.visit(this, null); + TypeDenoter fType = checkFieldIdentifier(rType, ast.I); + if (fType != StdEnvironment.errorType) + reporter.reportError("duplicate field \"%\" in record", ast.I.spelling, ast.I.position); + ast.type = new MultipleFieldTypeDenoter(ast.I, eType, rType, ast.position); + return ast.type; + } + + @Override + public Object visitSingleRecordAggregate(SingleRecordAggregate ast, Object o) { + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + ast.type = new SingleFieldTypeDenoter(ast.I, eType, ast.position); + return ast.type; + } + + // Formal Parameters + + // Always returns null. Does not use the given object. + + @Override + public Object visitConstFormalParameter(ConstFormalParameter ast, Object o) { + ast.T = (TypeDenoter) ast.T.visit(this, null); + idTable.enter(ast.I.spelling, ast); + if (ast.duplicated) + reporter.reportError("duplicated formal parameter \"%\"", ast.I.spelling, ast.position); + return null; + } + + @Override + public Object visitFuncFormalParameter(FuncFormalParameter ast, Object o) { + idTable.openScope(); + ast.FPS.visit(this, null); + idTable.closeScope(); + ast.T = (TypeDenoter) ast.T.visit(this, null); + idTable.enter(ast.I.spelling, ast); + if (ast.duplicated) + reporter.reportError("duplicated formal parameter \"%\"", ast.I.spelling, ast.position); + return null; + } + + @Override + public Object visitProcFormalParameter(ProcFormalParameter ast, Object o) { + idTable.openScope(); + ast.FPS.visit(this, null); + idTable.closeScope(); + idTable.enter(ast.I.spelling, ast); + if (ast.duplicated) + reporter.reportError("duplicated formal parameter \"%\"", ast.I.spelling, ast.position); + return null; + } + + @Override + public Object visitVarFormalParameter(VarFormalParameter ast, Object o) { + ast.T = (TypeDenoter) ast.T.visit(this, null); + idTable.enter(ast.I.spelling, ast); + if (ast.duplicated) + reporter.reportError("duplicated formal parameter \"%\"", ast.I.spelling, ast.position); + return null; + } + + @Override + public Object visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Object o) { + return null; + } + + @Override + public Object visitMultipleFormalParameterSequence(MultipleFormalParameterSequence ast, Object o) { + ast.FP.visit(this, null); + ast.FPS.visit(this, null); + return null; + } + + @Override + public Object visitSingleFormalParameterSequence(SingleFormalParameterSequence ast, Object o) { + ast.FP.visit(this, null); + return null; + } + + // Actual Parameters + + // Always returns null. Uses the given FormalParameter. + + @Override + public Object visitConstActualParameter(ConstActualParameter ast, Object o) { + FormalParameter fp = (FormalParameter) o; + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + + if (!(fp instanceof ConstFormalParameter)) + reporter.reportError("const actual parameter not expected here", "", ast.position); + else if (!eType.equals(((ConstFormalParameter) fp).T)) + reporter.reportError("wrong type for const actual parameter", "", ast.E.position); + return null; + } + + @Override + public Object visitFuncActualParameter(FuncActualParameter ast, Object o) { + FormalParameter fp = (FormalParameter) o; + + Declaration binding = (Declaration) ast.I.visit(this, null); + if (binding == null) + reportUndeclared(ast.I); + else if (!(binding instanceof FuncDeclaration || binding instanceof FuncFormalParameter)) + reporter.reportError("\"%\" is not a function identifier", ast.I.spelling, ast.I.position); + else if (!(fp instanceof FuncFormalParameter)) + reporter.reportError("func actual parameter not expected here", "", ast.position); + else { + FormalParameterSequence FPS = null; + TypeDenoter T = null; + if (binding instanceof FuncDeclaration) { + FPS = ((FuncDeclaration) binding).FPS; + T = ((FuncDeclaration) binding).T; + } else { + FPS = ((FuncFormalParameter) binding).FPS; + T = ((FuncFormalParameter) binding).T; + } + if (!FPS.equals(((FuncFormalParameter) fp).FPS)) + reporter.reportError("wrong signature for function \"%\"", ast.I.spelling, ast.I.position); + else if (!T.equals(((FuncFormalParameter) fp).T)) + reporter.reportError("wrong type for function \"%\"", ast.I.spelling, ast.I.position); + } + return null; + } + + @Override + public Object visitProcActualParameter(ProcActualParameter ast, Object o) { + FormalParameter fp = (FormalParameter) o; + + Declaration binding = (Declaration) ast.I.visit(this, null); + if (binding == null) + reportUndeclared(ast.I); + else if (!(binding instanceof ProcDeclaration || binding instanceof ProcFormalParameter)) + reporter.reportError("\"%\" is not a procedure identifier", ast.I.spelling, ast.I.position); + else if (!(fp instanceof ProcFormalParameter)) + reporter.reportError("proc actual parameter not expected here", "", ast.position); + else { + FormalParameterSequence FPS = null; + if (binding instanceof ProcDeclaration) + FPS = ((ProcDeclaration) binding).FPS; + else + FPS = ((ProcFormalParameter) binding).FPS; + if (!FPS.equals(((ProcFormalParameter) fp).FPS)) + reporter.reportError("wrong signature for procedure \"%\"", ast.I.spelling, ast.I.position); + } + return null; + } + + @Override + public Object visitVarActualParameter(VarActualParameter ast, Object o) { + FormalParameter fp = (FormalParameter) o; + + TypeDenoter vType = (TypeDenoter) ast.V.visit(this, null); + if (!ast.V.variable) + reporter.reportError("actual parameter is not a variable", "", ast.V.position); + else if (!(fp instanceof VarFormalParameter)) + reporter.reportError("var actual parameter not expected here", "", ast.V.position); + else if (!vType.equals(((VarFormalParameter) fp).T)) + reporter.reportError("wrong type for var actual parameter", "", ast.V.position); + return null; + } + + @Override + public Object visitEmptyActualParameterSequence(EmptyActualParameterSequence ast, Object o) { + FormalParameterSequence fps = (FormalParameterSequence) o; + if (!(fps instanceof EmptyFormalParameterSequence)) + reporter.reportError("too few actual parameters", "", ast.position); + return null; + } + + @Override + public Object visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, Object o) { + FormalParameterSequence fps = (FormalParameterSequence) o; + if (!(fps instanceof MultipleFormalParameterSequence)) + reporter.reportError("too many actual parameters", "", ast.position); + else { + ast.AP.visit(this, ((MultipleFormalParameterSequence) fps).FP); + ast.APS.visit(this, ((MultipleFormalParameterSequence) fps).FPS); + } + return null; + } + + @Override + public Object visitSingleActualParameterSequence(SingleActualParameterSequence ast, Object o) { + FormalParameterSequence fps = (FormalParameterSequence) o; + if (!(fps instanceof SingleFormalParameterSequence)) + reporter.reportError("incorrect number of actual parameters", "", ast.position); + else { + ast.AP.visit(this, ((SingleFormalParameterSequence) fps).FP); + } + return null; + } + + // Type Denoters + + // Returns the expanded version of the TypeDenoter. Does not + // use the given object. + + @Override + public Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object o) { + return StdEnvironment.anyType; + } + + @Override + public Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object o) { + ast.T = (TypeDenoter) ast.T.visit(this, null); + if ((Integer.valueOf(ast.IL.spelling).intValue()) == 0) + reporter.reportError("arrays must not be empty", "", ast.IL.position); + return ast; + } + + @Override + public Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object o) { + return StdEnvironment.booleanType; + } + + @Override + public Object visitCharTypeDenoter(CharTypeDenoter ast, Object o) { + return StdEnvironment.charType; + } + + @Override + public Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object o) { + return StdEnvironment.errorType; + } + + @Override + public Object visitSimpleTypeDenoter(SimpleTypeDenoter ast, Object o) { + Declaration binding = (Declaration) ast.I.visit(this, null); + if (binding == null) { + reportUndeclared(ast.I); + return StdEnvironment.errorType; + } else if (!(binding instanceof TypeDeclaration)) { + reporter.reportError("\"%\" is not a type identifier", ast.I.spelling, ast.I.position); + return StdEnvironment.errorType; + } + return ((TypeDeclaration) binding).T; + } + + @Override + public Object visitIntTypeDenoter(IntTypeDenoter ast, Object o) { + return StdEnvironment.integerType; + } + + @Override + public Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object o) { + ast.FT = (FieldTypeDenoter) ast.FT.visit(this, null); + return ast; + } + + @Override + public Object visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, Object o) { + ast.T = (TypeDenoter) ast.T.visit(this, null); + ast.FT.visit(this, null); + return ast; + } + + @Override + public Object visitSingleFieldTypeDenoter(SingleFieldTypeDenoter ast, Object o) { + ast.T = (TypeDenoter) ast.T.visit(this, null); + return ast; + } + + // Literals, Identifiers and Operators + @Override + public Object visitCharacterLiteral(CharacterLiteral CL, Object o) { + return StdEnvironment.charType; + } + + @Override + public Object visitIdentifier(Identifier I, Object o) { + Declaration binding = idTable.retrieve(I.spelling); + if (binding != null) + I.decl = binding; + return binding; + } + + @Override + public Object visitIntegerLiteral(IntegerLiteral IL, Object o) { + return StdEnvironment.integerType; + } + + @Override + public Object visitOperator(Operator O, Object o) { + Declaration binding = idTable.retrieve(O.spelling); + if (binding != null) + O.decl = binding; + return binding; + } + + // Value-or-variable names + + // Determines the address of a named object (constant or variable). + // This consists of a base object, to which 0 or more field-selection + // or array-indexing operations may be applied (if it is a record or + // array). As much as possible of the address computation is done at + // compile-time. Code is generated only when necessary to evaluate + // index expressions at run-time. + // currentLevel is the routine level where the v-name occurs. + // frameSize is the anticipated size of the local stack frame when + // the object is addressed at run-time. + // It returns the description of the base object. + // offset is set to the total of any field offsets (plus any offsets + // due to index expressions that happen to be literals). + // indexed is set to true iff there are any index expressions (other + // than literals). In that case code is generated to compute the + // offset due to these indexing operations at run-time. + + // Returns the TypeDenoter of the Vname. Does not use the + // given object. + + @Override + public Object visitDotVname(DotVname ast, Object o) { + ast.type = null; + TypeDenoter vType = (TypeDenoter) ast.V.visit(this, null); + ast.variable = ast.V.variable; + if (!(vType instanceof RecordTypeDenoter)) + reporter.reportError("record expected here", "", ast.V.position); + else { + ast.type = checkFieldIdentifier(((RecordTypeDenoter) vType).FT, ast.I); + if (ast.type == StdEnvironment.errorType) + reporter.reportError("no field \"%\" in this record type", ast.I.spelling, ast.I.position); + } + return ast.type; + } + + @Override + public Object visitSimpleVname(SimpleVname ast, Object o) { + ast.variable = false; + ast.type = StdEnvironment.errorType; + Declaration binding = (Declaration) ast.I.visit(this, null); + if (binding == null) + reportUndeclared(ast.I); + else if (binding instanceof ConstDeclaration) { + ast.type = ((ConstDeclaration) binding).E.type; + ast.variable = false; + } else if (binding instanceof VarDeclaration) { + ast.type = ((VarDeclaration) binding).T; + ast.variable = true; + } else if (binding instanceof ConstFormalParameter) { + ast.type = ((ConstFormalParameter) binding).T; + ast.variable = false; + } else if (binding instanceof VarFormalParameter) { + ast.type = ((VarFormalParameter) binding).T; + ast.variable = true; + } else + reporter.reportError("\"%\" is not a const or var identifier", ast.I.spelling, ast.I.position); + return ast.type; + } + + @Override + public Object visitSubscriptVname(SubscriptVname ast, Object o) { + TypeDenoter vType = (TypeDenoter) ast.V.visit(this, null); + ast.variable = ast.V.variable; + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + if (vType != StdEnvironment.errorType) { + if (!(vType instanceof ArrayTypeDenoter)) + reporter.reportError("array expected here", "", ast.V.position); + else { + if (!eType.equals(StdEnvironment.integerType)) + reporter.reportError("Integer expression expected here", "", ast.E.position); + ast.type = ((ArrayTypeDenoter) vType).T; + } + } + return ast.type; + } + + // Programs + + @Override + public Object visitProgram(Program ast, Object o) { + ast.C.visit(this, null); + return null; + } + + // Checks whether the source program, represented by its AST, satisfies the + // language's scope rules and type rules. + // Also decorates the AST as follows: + // (a) Each applied occurrence of an identifier or operator is linked to + // the corresponding declaration of that identifier or operator. + // (b) Each expression and value-or-variable-name is decorated by its type. + // (c) Each type identifier is replaced by the type it denotes. + // Types are represented by small ASTs. + + public void check(Program ast) { + ast.visit(this, null); + } + + ///////////////////////////////////////////////////////////////////////////// + + public Checker(ErrorReporter reporter) { + this.reporter = reporter; + this.idTable = new IdentificationTable(); + establishStdEnvironment(); + } + + private IdentificationTable idTable; + private static SourcePosition dummyPos = new SourcePosition(); + private ErrorReporter reporter; + + // Reports that the identifier or operator used at a leaf of the AST + // has not been declared. + + private void reportUndeclared(Terminal leaf) { + reporter.reportError("\"%\" is not declared", leaf.spelling, leaf.position); + } + + private static TypeDenoter checkFieldIdentifier(FieldTypeDenoter ast, Identifier I) { + if (ast instanceof MultipleFieldTypeDenoter) { + MultipleFieldTypeDenoter ft = (MultipleFieldTypeDenoter) ast; + if (ft.I.spelling.compareTo(I.spelling) == 0) { + I.decl = ast; + return ft.T; + } else { + return checkFieldIdentifier(ft.FT, I); + } + } else if (ast instanceof SingleFieldTypeDenoter) { + SingleFieldTypeDenoter ft = (SingleFieldTypeDenoter) ast; + if (ft.I.spelling.compareTo(I.spelling) == 0) { + I.decl = ast; + return ft.T; + } + } + return StdEnvironment.errorType; + } + + // Creates a small AST to represent the "declaration" of a standard + // type, and enters it in the identification table. + + private TypeDeclaration declareStdType(String id, TypeDenoter typedenoter) { + + TypeDeclaration binding; + + binding = new TypeDeclaration(new Identifier(id, dummyPos), typedenoter, dummyPos); + idTable.enter(id, binding); + return binding; + } + + // Creates a small AST to represent the "declaration" of a standard + // type, and enters it in the identification table. + + private ConstDeclaration declareStdConst(String id, TypeDenoter constType) { + + IntegerExpression constExpr; + ConstDeclaration binding; + + // constExpr used only as a placeholder for constType + constExpr = new IntegerExpression(null, dummyPos); + constExpr.type = constType; + binding = new ConstDeclaration(new Identifier(id, dummyPos), constExpr, dummyPos); + idTable.enter(id, binding); + return binding; + } + + // Creates a small AST to represent the "declaration" of a standard + // type, and enters it in the identification table. + + private ProcDeclaration declareStdProc(String id, FormalParameterSequence fps) { + + ProcDeclaration binding; + + binding = new ProcDeclaration(new Identifier(id, dummyPos), fps, new EmptyCommand(dummyPos), dummyPos); + idTable.enter(id, binding); + return binding; + } + + // Creates a small AST to represent the "declaration" of a standard + // type, and enters it in the identification table. + + private FuncDeclaration declareStdFunc(String id, FormalParameterSequence fps, TypeDenoter resultType) { + + FuncDeclaration binding; + + binding = new FuncDeclaration(new Identifier(id, dummyPos), fps, resultType, new EmptyExpression(dummyPos), + dummyPos); + idTable.enter(id, binding); + return binding; + } + + // Creates a small AST to represent the "declaration" of a + // unary operator, and enters it in the identification table. + // This "declaration" summarises the operator's type info. + + private UnaryOperatorDeclaration declareStdUnaryOp(String op, TypeDenoter argType, TypeDenoter resultType) { + + UnaryOperatorDeclaration binding; + + binding = new UnaryOperatorDeclaration(new Operator(op, dummyPos), argType, resultType, dummyPos); + idTable.enter(op, binding); + return binding; + } + + // Creates a small AST to represent the "declaration" of a + // binary operator, and enters it in the identification table. + // This "declaration" summarises the operator's type info. + + private BinaryOperatorDeclaration declareStdBinaryOp(String op, TypeDenoter arg1Type, TypeDenoter arg2type, + TypeDenoter resultType) { + + BinaryOperatorDeclaration binding; + + binding = new BinaryOperatorDeclaration(new Operator(op, dummyPos), arg1Type, arg2type, resultType, dummyPos); + idTable.enter(op, binding); + return binding; + } + + // Creates small ASTs to represent the standard types. + // Creates small ASTs to represent "declarations" of standard types, + // constants, procedures, functions, and operators. + // Enters these "declarations" in the identification table. + + private final static Identifier dummyI = new Identifier("", dummyPos); + + private void establishStdEnvironment() { + + // idTable.startIdentification(); + StdEnvironment.booleanType = new BoolTypeDenoter(dummyPos); + StdEnvironment.integerType = new IntTypeDenoter(dummyPos); + StdEnvironment.charType = new CharTypeDenoter(dummyPos); + StdEnvironment.anyType = new AnyTypeDenoter(dummyPos); + StdEnvironment.errorType = new ErrorTypeDenoter(dummyPos); + + StdEnvironment.booleanDecl = declareStdType("Boolean", StdEnvironment.booleanType); + StdEnvironment.falseDecl = declareStdConst("false", StdEnvironment.booleanType); + StdEnvironment.trueDecl = declareStdConst("true", StdEnvironment.booleanType); + StdEnvironment.notDecl = declareStdUnaryOp("\\", StdEnvironment.booleanType, StdEnvironment.booleanType); + StdEnvironment.andDecl = declareStdBinaryOp("/\\", StdEnvironment.booleanType, StdEnvironment.booleanType, + StdEnvironment.booleanType); + StdEnvironment.orDecl = declareStdBinaryOp("\\/", StdEnvironment.booleanType, StdEnvironment.booleanType, + StdEnvironment.booleanType); + + StdEnvironment.integerDecl = declareStdType("Integer", StdEnvironment.integerType); + StdEnvironment.maxintDecl = declareStdConst("maxint", StdEnvironment.integerType); + StdEnvironment.addDecl = declareStdBinaryOp("+", StdEnvironment.integerType, StdEnvironment.integerType, + StdEnvironment.integerType); + StdEnvironment.subtractDecl = declareStdBinaryOp("-", StdEnvironment.integerType, StdEnvironment.integerType, + StdEnvironment.integerType); + StdEnvironment.multiplyDecl = declareStdBinaryOp("*", StdEnvironment.integerType, StdEnvironment.integerType, + StdEnvironment.integerType); + StdEnvironment.divideDecl = declareStdBinaryOp("/", StdEnvironment.integerType, StdEnvironment.integerType, + StdEnvironment.integerType); + StdEnvironment.moduloDecl = declareStdBinaryOp("//", StdEnvironment.integerType, StdEnvironment.integerType, + StdEnvironment.integerType); + StdEnvironment.lessDecl = declareStdBinaryOp("<", StdEnvironment.integerType, StdEnvironment.integerType, + StdEnvironment.booleanType); + StdEnvironment.notgreaterDecl = declareStdBinaryOp("<=", StdEnvironment.integerType, StdEnvironment.integerType, + StdEnvironment.booleanType); + StdEnvironment.greaterDecl = declareStdBinaryOp(">", StdEnvironment.integerType, StdEnvironment.integerType, + StdEnvironment.booleanType); + StdEnvironment.notlessDecl = declareStdBinaryOp(">=", StdEnvironment.integerType, StdEnvironment.integerType, + StdEnvironment.booleanType); + + StdEnvironment.charDecl = declareStdType("Char", StdEnvironment.charType); + StdEnvironment.chrDecl = declareStdFunc("chr", + new SingleFormalParameterSequence( + new ConstFormalParameter(dummyI, StdEnvironment.integerType, dummyPos), dummyPos), + StdEnvironment.charType); + StdEnvironment.ordDecl = declareStdFunc("ord", + new SingleFormalParameterSequence(new ConstFormalParameter(dummyI, StdEnvironment.charType, dummyPos), + dummyPos), + StdEnvironment.integerType); + StdEnvironment.eofDecl = declareStdFunc("eof", new EmptyFormalParameterSequence(dummyPos), + StdEnvironment.booleanType); + StdEnvironment.eolDecl = declareStdFunc("eol", new EmptyFormalParameterSequence(dummyPos), + StdEnvironment.booleanType); + StdEnvironment.getDecl = declareStdProc("get", new SingleFormalParameterSequence( + new VarFormalParameter(dummyI, StdEnvironment.charType, dummyPos), dummyPos)); + StdEnvironment.putDecl = declareStdProc("put", new SingleFormalParameterSequence( + new ConstFormalParameter(dummyI, StdEnvironment.charType, dummyPos), dummyPos)); + StdEnvironment.getintDecl = declareStdProc("getint", new SingleFormalParameterSequence( + new VarFormalParameter(dummyI, StdEnvironment.integerType, dummyPos), dummyPos)); + StdEnvironment.putintDecl = declareStdProc("putint", new SingleFormalParameterSequence( + new ConstFormalParameter(dummyI, StdEnvironment.integerType, dummyPos), dummyPos)); + StdEnvironment.geteolDecl = declareStdProc("geteol", new EmptyFormalParameterSequence(dummyPos)); + StdEnvironment.puteolDecl = declareStdProc("puteol", new EmptyFormalParameterSequence(dummyPos)); + StdEnvironment.equalDecl = declareStdBinaryOp("=", StdEnvironment.anyType, StdEnvironment.anyType, + StdEnvironment.booleanType); + StdEnvironment.unequalDecl = declareStdBinaryOp("\\=", StdEnvironment.anyType, StdEnvironment.anyType, + StdEnvironment.booleanType); + + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdEntry.java b/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdEntry.java index 465710d..fc71b09 100644 --- a/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdEntry.java +++ b/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdEntry.java @@ -18,16 +18,16 @@ import Triangle.AbstractSyntaxTrees.Declaration; public class IdEntry { - protected String id; - protected Declaration attr; - protected int level; - protected IdEntry previous; + protected String id; + protected Declaration attr; + protected int level; + protected IdEntry previous; - IdEntry(String id, Declaration attr, int level, IdEntry previous) { - this.id = id; - this.attr = attr; - this.level = level; - this.previous = previous; - } + IdEntry(String id, Declaration attr, int level, IdEntry previous) { + this.id = id; + this.attr = attr; + this.level = level; + this.previous = previous; + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdentificationTable.java b/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdentificationTable.java index a3276f0..52853e7 100644 --- a/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdentificationTable.java +++ b/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdentificationTable.java @@ -18,91 +18,91 @@ import Triangle.AbstractSyntaxTrees.Declaration; public final class IdentificationTable { - private int level; - private IdEntry latest; - - public IdentificationTable() { - level = 0; - latest = null; - } - - // Opens a new level in the identification table, 1 higher than the - // current topmost level. - - public void openScope() { - - level++; - } - - // Closes the topmost level in the identification table, discarding - // all entries belonging to that level. - - public void closeScope() { - - IdEntry entry, local; - - // Presumably, idTable.level > 0. - entry = this.latest; - while (entry.level == this.level) { - local = entry; - entry = local.previous; - } - this.level--; - this.latest = entry; - } - - // Makes a new entry in the identification table for the given identifier - // and attribute. The new entry belongs to the current level. - // duplicated is set to to true iff there is already an entry for the - // same identifier at the current level. - - public void enter(String id, Declaration attr) { - - IdEntry entry = this.latest; - boolean present = false, searching = true; - - // Check for duplicate entry ... - while (searching) { - if (entry == null || entry.level < this.level) - searching = false; - else if (entry.id.equals(id)) { - present = true; - searching = false; - } else - entry = entry.previous; - } - - attr.duplicated = present; - // Add new entry ... - entry = new IdEntry(id, attr, this.level, this.latest); - this.latest = entry; - } - - // Finds an entry for the given identifier in the identification table, - // if any. If there are several entries for that identifier, finds the - // entry at the highest level, in accordance with the scope rules. - // Returns null iff no entry is found. - // otherwise returns the attribute field of the entry found. - - public Declaration retrieve(String id) { - - IdEntry entry; - Declaration attr = null; - boolean present = false, searching = true; - - entry = this.latest; - while (searching) { - if (entry == null) - searching = false; - else if (entry.id.equals(id)) { - present = true; - searching = false; - attr = entry.attr; - } else - entry = entry.previous; - } - - return attr; - } + private int level; + private IdEntry latest; + + public IdentificationTable() { + level = 0; + latest = null; + } + + // Opens a new level in the identification table, 1 higher than the + // current topmost level. + + public void openScope() { + + level++; + } + + // Closes the topmost level in the identification table, discarding + // all entries belonging to that level. + + public void closeScope() { + + IdEntry entry, local; + + // Presumably, idTable.level > 0. + entry = this.latest; + while (entry.level == this.level) { + local = entry; + entry = local.previous; + } + this.level--; + this.latest = entry; + } + + // Makes a new entry in the identification table for the given identifier + // and attribute. The new entry belongs to the current level. + // duplicated is set to to true iff there is already an entry for the + // same identifier at the current level. + + public void enter(String id, Declaration attr) { + + IdEntry entry = this.latest; + boolean present = false, searching = true; + + // Check for duplicate entry ... + while (searching) { + if (entry == null || entry.level < this.level) + searching = false; + else if (entry.id.equals(id)) { + present = true; + searching = false; + } else + entry = entry.previous; + } + + attr.duplicated = present; + // Add new entry ... + entry = new IdEntry(id, attr, this.level, this.latest); + this.latest = entry; + } + + // Finds an entry for the given identifier in the identification table, + // if any. If there are several entries for that identifier, finds the + // entry at the highest level, in accordance with the scope rules. + // Returns null iff no entry is found. + // otherwise returns the attribute field of the entry found. + + public Declaration retrieve(String id) { + + IdEntry entry; + Declaration attr = null; + boolean present = false, searching = true; + + entry = this.latest; + while (searching) { + if (entry == null) + searching = false; + else if (entry.id.equals(id)) { + present = true; + searching = false; + attr = entry.attr; + } else + entry = entry.previous; + } + + return attr; + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/ErrorReporter.java b/Triangle.Compiler/src/main/java/Triangle/ErrorReporter.java index aadbfcb..99a4f9f 100644 --- a/Triangle.Compiler/src/main/java/Triangle/ErrorReporter.java +++ b/Triangle.Compiler/src/main/java/Triangle/ErrorReporter.java @@ -18,25 +18,25 @@ import Triangle.SyntacticAnalyzer.SourcePosition; public class ErrorReporter { - int numErrors; - - ErrorReporter() { - numErrors = 0; - } - - public void reportError(String message, String tokenName, SourcePosition pos) { - System.out.print("ERROR: "); - - for (int p = 0; p < message.length(); p++) - if (message.charAt(p) == '%') - System.out.print(tokenName); - else - System.out.print(message.charAt(p)); - System.out.println(" " + pos.start + ".." + pos.finish); - numErrors++; - } - - public void reportRestriction(String message) { - System.out.println("RESTRICTION: " + message); - } + int numErrors; + + ErrorReporter() { + numErrors = 0; + } + + public void reportError(String message, String tokenName, SourcePosition pos) { + System.out.print("ERROR: "); + + for (int p = 0; p < message.length(); p++) + if (message.charAt(p) == '%') + System.out.print(tokenName); + else + System.out.print(message.charAt(p)); + System.out.println(" " + pos.start + ".." + pos.finish); + numErrors++; + } + + public void reportRestriction(String message) { + System.out.println("RESTRICTION: " + message); + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/StdEnvironment.java b/Triangle.Compiler/src/main/java/Triangle/StdEnvironment.java index 1366d1e..c2e4182 100644 --- a/Triangle.Compiler/src/main/java/Triangle/StdEnvironment.java +++ b/Triangle.Compiler/src/main/java/Triangle/StdEnvironment.java @@ -24,24 +24,23 @@ import Triangle.AbstractSyntaxTrees.UnaryOperatorDeclaration; public final class StdEnvironment { - // These are small ASTs representing standard types. + // These are small ASTs representing standard types. - public static TypeDenoter booleanType, charType, integerType, anyType, errorType; + public static TypeDenoter booleanType, charType, integerType, anyType, errorType; - public static TypeDeclaration booleanDecl, charDecl, integerDecl; + public static TypeDeclaration booleanDecl, charDecl, integerDecl; - // These are small ASTs representing "declarations" of standard entities. + // These are small ASTs representing "declarations" of standard entities. - public static ConstDeclaration falseDecl, trueDecl, maxintDecl; + public static ConstDeclaration falseDecl, trueDecl, maxintDecl; - public static UnaryOperatorDeclaration notDecl; + public static UnaryOperatorDeclaration notDecl; - public static BinaryOperatorDeclaration andDecl, orDecl, - addDecl, subtractDecl, multiplyDecl, divideDecl, moduloDecl, - equalDecl, unequalDecl, lessDecl, notlessDecl, greaterDecl, notgreaterDecl; + public static BinaryOperatorDeclaration andDecl, orDecl, addDecl, subtractDecl, multiplyDecl, divideDecl, + moduloDecl, equalDecl, unequalDecl, lessDecl, notlessDecl, greaterDecl, notgreaterDecl; - public static ProcDeclaration getDecl, putDecl, getintDecl, putintDecl, geteolDecl, puteolDecl; + public static ProcDeclaration getDecl, putDecl, getintDecl, putintDecl, geteolDecl, puteolDecl; - public static FuncDeclaration chrDecl, ordDecl, eolDecl, eofDecl; + public static FuncDeclaration chrDecl, ordDecl, eolDecl, eofDecl; } diff --git a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Parser.java b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Parser.java index ded9e7e..ba82d1c 100644 --- a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Parser.java +++ b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Parser.java @@ -84,850 +84,837 @@ import Triangle.AbstractSyntaxTrees.WhileCommand; public class Parser { - private Scanner lexicalAnalyser; - private ErrorReporter errorReporter; - private Token currentToken; - private SourcePosition previousTokenPosition; - - public Parser(Scanner lexer, ErrorReporter reporter) { - lexicalAnalyser = lexer; - errorReporter = reporter; - previousTokenPosition = new SourcePosition(); - } - - // accept checks whether the current token matches tokenExpected. - // If so, fetches the next token. - // If not, reports a syntactic error. - - void accept(int tokenExpected) throws SyntaxError { - if (currentToken.kind == tokenExpected) { - previousTokenPosition = currentToken.position; - currentToken = lexicalAnalyser.scan(); - } else { - syntacticError("\"%\" expected here", Token.spell(tokenExpected)); - } - } - - void acceptIt() { - previousTokenPosition = currentToken.position; - currentToken = lexicalAnalyser.scan(); - } - - // start records the position of the start of a phrase. - // This is defined to be the position of the first - // character of the first token of the phrase. - - void start(SourcePosition position) { - position.start = currentToken.position.start; - } - - // finish records the position of the end of a phrase. - // This is defined to be the position of the last - // character of the last token of the phrase. - - void finish(SourcePosition position) { - position.finish = previousTokenPosition.finish; - } - - void syntacticError(String messageTemplate, String tokenQuoted) throws SyntaxError { - SourcePosition pos = currentToken.position; - errorReporter.reportError(messageTemplate, tokenQuoted, pos); - throw (new SyntaxError()); - } - - /////////////////////////////////////////////////////////////////////////////// - // - // PROGRAMS - // - /////////////////////////////////////////////////////////////////////////////// - - public Program parseProgram() { - - Program programAST = null; - - previousTokenPosition.start = 0; - previousTokenPosition.finish = 0; - currentToken = lexicalAnalyser.scan(); - - try { - Command cAST = parseCommand(); - programAST = new Program(cAST, previousTokenPosition); - if (currentToken.kind != Token.EOT) { - syntacticError("\"%\" not expected after end of program", - currentToken.spelling); - } - } catch (SyntaxError s) { - return null; - } - return programAST; - } - - /////////////////////////////////////////////////////////////////////////////// - // - // LITERALS - // - /////////////////////////////////////////////////////////////////////////////// - - // parseIntegerLiteral parses an integer-literal, and constructs - // a leaf AST to represent it. - - IntegerLiteral parseIntegerLiteral() throws SyntaxError { - IntegerLiteral IL = null; - - if (currentToken.kind == Token.INTLITERAL) { - previousTokenPosition = currentToken.position; - String spelling = currentToken.spelling; - IL = new IntegerLiteral(spelling, previousTokenPosition); - currentToken = lexicalAnalyser.scan(); - } else { - IL = null; - syntacticError("integer literal expected here", ""); - } - return IL; - } - - // parseCharacterLiteral parses a character-literal, and constructs a leaf - // AST to represent it. - - CharacterLiteral parseCharacterLiteral() throws SyntaxError { - CharacterLiteral CL = null; - - if (currentToken.kind == Token.CHARLITERAL) { - previousTokenPosition = currentToken.position; - String spelling = currentToken.spelling; - CL = new CharacterLiteral(spelling, previousTokenPosition); - currentToken = lexicalAnalyser.scan(); - } else { - CL = null; - syntacticError("character literal expected here", ""); - } - return CL; - } - - // parseIdentifier parses an identifier, and constructs a leaf AST to - // represent it. - - Identifier parseIdentifier() throws SyntaxError { - Identifier I = null; - - if (currentToken.kind == Token.IDENTIFIER) { - previousTokenPosition = currentToken.position; - String spelling = currentToken.spelling; - I = new Identifier(spelling, previousTokenPosition); - currentToken = lexicalAnalyser.scan(); - } else { - I = null; - syntacticError("identifier expected here", ""); - } - return I; - } - - // parseOperator parses an operator, and constructs a leaf AST to - // represent it. - - Operator parseOperator() throws SyntaxError { - Operator O = null; - - if (currentToken.kind == Token.OPERATOR) { - previousTokenPosition = currentToken.position; - String spelling = currentToken.spelling; - O = new Operator(spelling, previousTokenPosition); - currentToken = lexicalAnalyser.scan(); - } else { - O = null; - syntacticError("operator expected here", ""); - } - return O; - } - - /////////////////////////////////////////////////////////////////////////////// - // - // COMMANDS - // - /////////////////////////////////////////////////////////////////////////////// - - // parseCommand parses the command, and constructs an AST - // to represent its phrase structure. - - Command parseCommand() throws SyntaxError { - Command commandAST = null; // in case there's a syntactic error - - SourcePosition commandPos = new SourcePosition(); - - start(commandPos); - commandAST = parseSingleCommand(); - while (currentToken.kind == Token.SEMICOLON) { - acceptIt(); - Command c2AST = parseSingleCommand(); - finish(commandPos); - commandAST = new SequentialCommand(commandAST, c2AST, commandPos); - } - return commandAST; - } - - Command parseSingleCommand() throws SyntaxError { - Command commandAST = null; // in case there's a syntactic error - - SourcePosition commandPos = new SourcePosition(); - start(commandPos); - - switch (currentToken.kind) { - - case Token.IDENTIFIER: { - Identifier iAST = parseIdentifier(); - if (currentToken.kind == Token.LPAREN) { - acceptIt(); - ActualParameterSequence apsAST = parseActualParameterSequence(); - accept(Token.RPAREN); - finish(commandPos); - commandAST = new CallCommand(iAST, apsAST, commandPos); - - } else { - - Vname vAST = parseRestOfVname(iAST); - accept(Token.BECOMES); - Expression eAST = parseExpression(); - finish(commandPos); - commandAST = new AssignCommand(vAST, eAST, commandPos); - } - } - break; - - case Token.BEGIN: - acceptIt(); - commandAST = parseCommand(); - accept(Token.END); - break; - - case Token.LET: { - acceptIt(); - Declaration dAST = parseDeclaration(); - accept(Token.IN); - Command cAST = parseSingleCommand(); - finish(commandPos); - commandAST = new LetCommand(dAST, cAST, commandPos); - } - break; - - case Token.IF: { - acceptIt(); - Expression eAST = parseExpression(); - accept(Token.THEN); - Command c1AST = parseSingleCommand(); - accept(Token.ELSE); - Command c2AST = parseSingleCommand(); - finish(commandPos); - commandAST = new IfCommand(eAST, c1AST, c2AST, commandPos); - } - break; - - case Token.WHILE: { - acceptIt(); - Expression eAST = parseExpression(); - accept(Token.DO); - Command cAST = parseSingleCommand(); - finish(commandPos); - commandAST = new WhileCommand(eAST, cAST, commandPos); - } - break; - - case Token.SEMICOLON: - case Token.END: - case Token.ELSE: - case Token.IN: - case Token.EOT: - - finish(commandPos); - commandAST = new EmptyCommand(commandPos); - break; - - default: - syntacticError("\"%\" cannot start a command", - currentToken.spelling); - break; - - } - - return commandAST; - } - - /////////////////////////////////////////////////////////////////////////////// - // - // EXPRESSIONS - // - /////////////////////////////////////////////////////////////////////////////// - - Expression parseExpression() throws SyntaxError { - Expression expressionAST = null; // in case there's a syntactic error - - SourcePosition expressionPos = new SourcePosition(); - - start(expressionPos); - - switch (currentToken.kind) { - - case Token.LET: { - acceptIt(); - Declaration dAST = parseDeclaration(); - accept(Token.IN); - Expression eAST = parseExpression(); - finish(expressionPos); - expressionAST = new LetExpression(dAST, eAST, expressionPos); - } - break; - - case Token.IF: { - acceptIt(); - Expression e1AST = parseExpression(); - accept(Token.THEN); - Expression e2AST = parseExpression(); - accept(Token.ELSE); - Expression e3AST = parseExpression(); - finish(expressionPos); - expressionAST = new IfExpression(e1AST, e2AST, e3AST, expressionPos); - } - break; - - default: - expressionAST = parseSecondaryExpression(); - break; - } - return expressionAST; - } - - Expression parseSecondaryExpression() throws SyntaxError { - Expression expressionAST = null; // in case there's a syntactic error - - SourcePosition expressionPos = new SourcePosition(); - start(expressionPos); - - expressionAST = parsePrimaryExpression(); - while (currentToken.kind == Token.OPERATOR) { - Operator opAST = parseOperator(); - Expression e2AST = parsePrimaryExpression(); - expressionAST = new BinaryExpression(expressionAST, opAST, e2AST, - expressionPos); - } - return expressionAST; - } - - Expression parsePrimaryExpression() throws SyntaxError { - Expression expressionAST = null; // in case there's a syntactic error - - SourcePosition expressionPos = new SourcePosition(); - start(expressionPos); - - switch (currentToken.kind) { - - case Token.INTLITERAL: { - IntegerLiteral ilAST = parseIntegerLiteral(); - finish(expressionPos); - expressionAST = new IntegerExpression(ilAST, expressionPos); - } - break; - - case Token.CHARLITERAL: { - CharacterLiteral clAST = parseCharacterLiteral(); - finish(expressionPos); - expressionAST = new CharacterExpression(clAST, expressionPos); - } - break; - - case Token.LBRACKET: { - acceptIt(); - ArrayAggregate aaAST = parseArrayAggregate(); - accept(Token.RBRACKET); - finish(expressionPos); - expressionAST = new ArrayExpression(aaAST, expressionPos); - } - break; - - case Token.LCURLY: { - acceptIt(); - RecordAggregate raAST = parseRecordAggregate(); - accept(Token.RCURLY); - finish(expressionPos); - expressionAST = new RecordExpression(raAST, expressionPos); - } - break; - - case Token.IDENTIFIER: { - Identifier iAST = parseIdentifier(); - if (currentToken.kind == Token.LPAREN) { - acceptIt(); - ActualParameterSequence apsAST = parseActualParameterSequence(); - accept(Token.RPAREN); - finish(expressionPos); - expressionAST = new CallExpression(iAST, apsAST, expressionPos); - - } else { - Vname vAST = parseRestOfVname(iAST); - finish(expressionPos); - expressionAST = new VnameExpression(vAST, expressionPos); - } - } - break; - - case Token.OPERATOR: { - Operator opAST = parseOperator(); - Expression eAST = parsePrimaryExpression(); - finish(expressionPos); - expressionAST = new UnaryExpression(opAST, eAST, expressionPos); - } - break; - - case Token.LPAREN: - acceptIt(); - expressionAST = parseExpression(); - accept(Token.RPAREN); - break; - - default: - syntacticError("\"%\" cannot start an expression", - currentToken.spelling); - break; - - } - return expressionAST; - } - - RecordAggregate parseRecordAggregate() throws SyntaxError { - RecordAggregate aggregateAST = null; // in case there's a syntactic error - - SourcePosition aggregatePos = new SourcePosition(); - start(aggregatePos); - - Identifier iAST = parseIdentifier(); - accept(Token.IS); - Expression eAST = parseExpression(); - - if (currentToken.kind == Token.COMMA) { - acceptIt(); - RecordAggregate aAST = parseRecordAggregate(); - finish(aggregatePos); - aggregateAST = new MultipleRecordAggregate(iAST, eAST, aAST, aggregatePos); - } else { - finish(aggregatePos); - aggregateAST = new SingleRecordAggregate(iAST, eAST, aggregatePos); - } - return aggregateAST; - } - - ArrayAggregate parseArrayAggregate() throws SyntaxError { - ArrayAggregate aggregateAST = null; // in case there's a syntactic error - - SourcePosition aggregatePos = new SourcePosition(); - start(aggregatePos); - - Expression eAST = parseExpression(); - if (currentToken.kind == Token.COMMA) { - acceptIt(); - ArrayAggregate aAST = parseArrayAggregate(); - finish(aggregatePos); - aggregateAST = new MultipleArrayAggregate(eAST, aAST, aggregatePos); - } else { - finish(aggregatePos); - aggregateAST = new SingleArrayAggregate(eAST, aggregatePos); - } - return aggregateAST; - } - - /////////////////////////////////////////////////////////////////////////////// - // - // VALUE-OR-VARIABLE NAMES - // - /////////////////////////////////////////////////////////////////////////////// - - Vname parseVname() throws SyntaxError { - Vname vnameAST = null; // in case there's a syntactic error - Identifier iAST = parseIdentifier(); - vnameAST = parseRestOfVname(iAST); - return vnameAST; - } - - Vname parseRestOfVname(Identifier identifierAST) throws SyntaxError { - SourcePosition vnamePos = new SourcePosition(); - vnamePos = identifierAST.position; - Vname vAST = new SimpleVname(identifierAST, vnamePos); - - while (currentToken.kind == Token.DOT || - currentToken.kind == Token.LBRACKET) { - - if (currentToken.kind == Token.DOT) { - acceptIt(); - Identifier iAST = parseIdentifier(); - vAST = new DotVname(vAST, iAST, vnamePos); - } else { - acceptIt(); - Expression eAST = parseExpression(); - accept(Token.RBRACKET); - finish(vnamePos); - vAST = new SubscriptVname(vAST, eAST, vnamePos); - } - } - return vAST; - } - - /////////////////////////////////////////////////////////////////////////////// - // - // DECLARATIONS - // - /////////////////////////////////////////////////////////////////////////////// - - Declaration parseDeclaration() throws SyntaxError { - Declaration declarationAST = null; // in case there's a syntactic error - - SourcePosition declarationPos = new SourcePosition(); - start(declarationPos); - declarationAST = parseSingleDeclaration(); - while (currentToken.kind == Token.SEMICOLON) { - acceptIt(); - Declaration d2AST = parseSingleDeclaration(); - finish(declarationPos); - declarationAST = new SequentialDeclaration(declarationAST, d2AST, - declarationPos); - } - return declarationAST; - } - - Declaration parseSingleDeclaration() throws SyntaxError { - Declaration declarationAST = null; // in case there's a syntactic error - - SourcePosition declarationPos = new SourcePosition(); - start(declarationPos); - - switch (currentToken.kind) { - - case Token.CONST: { - acceptIt(); - Identifier iAST = parseIdentifier(); - accept(Token.IS); - Expression eAST = parseExpression(); - finish(declarationPos); - declarationAST = new ConstDeclaration(iAST, eAST, declarationPos); - } - break; - - case Token.VAR: { - acceptIt(); - Identifier iAST = parseIdentifier(); - accept(Token.COLON); - TypeDenoter tAST = parseTypeDenoter(); - finish(declarationPos); - declarationAST = new VarDeclaration(iAST, tAST, declarationPos); - } - break; - - case Token.PROC: { - acceptIt(); - Identifier iAST = parseIdentifier(); - accept(Token.LPAREN); - FormalParameterSequence fpsAST = parseFormalParameterSequence(); - accept(Token.RPAREN); - accept(Token.IS); - Command cAST = parseSingleCommand(); - finish(declarationPos); - declarationAST = new ProcDeclaration(iAST, fpsAST, cAST, declarationPos); - } - break; - - case Token.FUNC: { - acceptIt(); - Identifier iAST = parseIdentifier(); - accept(Token.LPAREN); - FormalParameterSequence fpsAST = parseFormalParameterSequence(); - accept(Token.RPAREN); - accept(Token.COLON); - TypeDenoter tAST = parseTypeDenoter(); - accept(Token.IS); - Expression eAST = parseExpression(); - finish(declarationPos); - declarationAST = new FuncDeclaration(iAST, fpsAST, tAST, eAST, - declarationPos); - } - break; - - case Token.TYPE: { - acceptIt(); - Identifier iAST = parseIdentifier(); - accept(Token.IS); - TypeDenoter tAST = parseTypeDenoter(); - finish(declarationPos); - declarationAST = new TypeDeclaration(iAST, tAST, declarationPos); - } - break; - - default: - syntacticError("\"%\" cannot start a declaration", - currentToken.spelling); - break; - - } - return declarationAST; - } - - /////////////////////////////////////////////////////////////////////////////// - // - // PARAMETERS - // - /////////////////////////////////////////////////////////////////////////////// - - FormalParameterSequence parseFormalParameterSequence() throws SyntaxError { - FormalParameterSequence formalsAST; - - SourcePosition formalsPos = new SourcePosition(); - - start(formalsPos); - if (currentToken.kind == Token.RPAREN) { - finish(formalsPos); - formalsAST = new EmptyFormalParameterSequence(formalsPos); - - } else { - formalsAST = parseProperFormalParameterSequence(); - } - return formalsAST; - } - - FormalParameterSequence parseProperFormalParameterSequence() throws SyntaxError { - FormalParameterSequence formalsAST = null; // in case there's a syntactic error; - - SourcePosition formalsPos = new SourcePosition(); - start(formalsPos); - FormalParameter fpAST = parseFormalParameter(); - if (currentToken.kind == Token.COMMA) { - acceptIt(); - FormalParameterSequence fpsAST = parseProperFormalParameterSequence(); - finish(formalsPos); - formalsAST = new MultipleFormalParameterSequence(fpAST, fpsAST, - formalsPos); - - } else { - finish(formalsPos); - formalsAST = new SingleFormalParameterSequence(fpAST, formalsPos); - } - return formalsAST; - } - - FormalParameter parseFormalParameter() throws SyntaxError { - FormalParameter formalAST = null; // in case there's a syntactic error; - - SourcePosition formalPos = new SourcePosition(); - start(formalPos); - - switch (currentToken.kind) { - - case Token.IDENTIFIER: { - Identifier iAST = parseIdentifier(); - accept(Token.COLON); - TypeDenoter tAST = parseTypeDenoter(); - finish(formalPos); - formalAST = new ConstFormalParameter(iAST, tAST, formalPos); - } - break; - - case Token.VAR: { - acceptIt(); - Identifier iAST = parseIdentifier(); - accept(Token.COLON); - TypeDenoter tAST = parseTypeDenoter(); - finish(formalPos); - formalAST = new VarFormalParameter(iAST, tAST, formalPos); - } - break; - - case Token.PROC: { - acceptIt(); - Identifier iAST = parseIdentifier(); - accept(Token.LPAREN); - FormalParameterSequence fpsAST = parseFormalParameterSequence(); - accept(Token.RPAREN); - finish(formalPos); - formalAST = new ProcFormalParameter(iAST, fpsAST, formalPos); - } - break; - - case Token.FUNC: { - acceptIt(); - Identifier iAST = parseIdentifier(); - accept(Token.LPAREN); - FormalParameterSequence fpsAST = parseFormalParameterSequence(); - accept(Token.RPAREN); - accept(Token.COLON); - TypeDenoter tAST = parseTypeDenoter(); - finish(formalPos); - formalAST = new FuncFormalParameter(iAST, fpsAST, tAST, formalPos); - } - break; - - default: - syntacticError("\"%\" cannot start a formal parameter", - currentToken.spelling); - break; - - } - return formalAST; - } - - ActualParameterSequence parseActualParameterSequence() throws SyntaxError { - ActualParameterSequence actualsAST; - - SourcePosition actualsPos = new SourcePosition(); - - start(actualsPos); - if (currentToken.kind == Token.RPAREN) { - finish(actualsPos); - actualsAST = new EmptyActualParameterSequence(actualsPos); - - } else { - actualsAST = parseProperActualParameterSequence(); - } - return actualsAST; - } - - ActualParameterSequence parseProperActualParameterSequence() throws SyntaxError { - ActualParameterSequence actualsAST = null; // in case there's a syntactic error - - SourcePosition actualsPos = new SourcePosition(); - - start(actualsPos); - ActualParameter apAST = parseActualParameter(); - if (currentToken.kind == Token.COMMA) { - acceptIt(); - ActualParameterSequence apsAST = parseProperActualParameterSequence(); - finish(actualsPos); - actualsAST = new MultipleActualParameterSequence(apAST, apsAST, - actualsPos); - } else { - finish(actualsPos); - actualsAST = new SingleActualParameterSequence(apAST, actualsPos); - } - return actualsAST; - } - - ActualParameter parseActualParameter() throws SyntaxError { - ActualParameter actualAST = null; // in case there's a syntactic error - - SourcePosition actualPos = new SourcePosition(); - - start(actualPos); - - switch (currentToken.kind) { - - case Token.IDENTIFIER: - case Token.INTLITERAL: - case Token.CHARLITERAL: - case Token.OPERATOR: - case Token.LET: - case Token.IF: - case Token.LPAREN: - case Token.LBRACKET: - case Token.LCURLY: { - Expression eAST = parseExpression(); - finish(actualPos); - actualAST = new ConstActualParameter(eAST, actualPos); - } - break; - - case Token.VAR: { - acceptIt(); - Vname vAST = parseVname(); - finish(actualPos); - actualAST = new VarActualParameter(vAST, actualPos); - } - break; - - case Token.PROC: { - acceptIt(); - Identifier iAST = parseIdentifier(); - finish(actualPos); - actualAST = new ProcActualParameter(iAST, actualPos); - } - break; - - case Token.FUNC: { - acceptIt(); - Identifier iAST = parseIdentifier(); - finish(actualPos); - actualAST = new FuncActualParameter(iAST, actualPos); - } - break; - - default: - syntacticError("\"%\" cannot start an actual parameter", - currentToken.spelling); - break; - - } - return actualAST; - } - - /////////////////////////////////////////////////////////////////////////////// - // - // TYPE-DENOTERS - // - /////////////////////////////////////////////////////////////////////////////// - - TypeDenoter parseTypeDenoter() throws SyntaxError { - TypeDenoter typeAST = null; // in case there's a syntactic error - SourcePosition typePos = new SourcePosition(); - - start(typePos); - - switch (currentToken.kind) { - - case Token.IDENTIFIER: { - Identifier iAST = parseIdentifier(); - finish(typePos); - typeAST = new SimpleTypeDenoter(iAST, typePos); - } - break; - - case Token.ARRAY: { - acceptIt(); - IntegerLiteral ilAST = parseIntegerLiteral(); - accept(Token.OF); - TypeDenoter tAST = parseTypeDenoter(); - finish(typePos); - typeAST = new ArrayTypeDenoter(ilAST, tAST, typePos); - } - break; - - case Token.RECORD: { - acceptIt(); - FieldTypeDenoter fAST = parseFieldTypeDenoter(); - accept(Token.END); - finish(typePos); - typeAST = new RecordTypeDenoter(fAST, typePos); - } - break; - - default: - syntacticError("\"%\" cannot start a type denoter", - currentToken.spelling); - break; - - } - return typeAST; - } - - FieldTypeDenoter parseFieldTypeDenoter() throws SyntaxError { - FieldTypeDenoter fieldAST = null; // in case there's a syntactic error - - SourcePosition fieldPos = new SourcePosition(); - - start(fieldPos); - Identifier iAST = parseIdentifier(); - accept(Token.COLON); - TypeDenoter tAST = parseTypeDenoter(); - if (currentToken.kind == Token.COMMA) { - acceptIt(); - FieldTypeDenoter fAST = parseFieldTypeDenoter(); - finish(fieldPos); - fieldAST = new MultipleFieldTypeDenoter(iAST, tAST, fAST, fieldPos); - } else { - finish(fieldPos); - fieldAST = new SingleFieldTypeDenoter(iAST, tAST, fieldPos); - } - return fieldAST; - } + private Scanner lexicalAnalyser; + private ErrorReporter errorReporter; + private Token currentToken; + private SourcePosition previousTokenPosition; + + public Parser(Scanner lexer, ErrorReporter reporter) { + lexicalAnalyser = lexer; + errorReporter = reporter; + previousTokenPosition = new SourcePosition(); + } + + // accept checks whether the current token matches tokenExpected. + // If so, fetches the next token. + // If not, reports a syntactic error. + + void accept(int tokenExpected) throws SyntaxError { + if (currentToken.kind == tokenExpected) { + previousTokenPosition = currentToken.position; + currentToken = lexicalAnalyser.scan(); + } else { + syntacticError("\"%\" expected here", Token.spell(tokenExpected)); + } + } + + void acceptIt() { + previousTokenPosition = currentToken.position; + currentToken = lexicalAnalyser.scan(); + } + + // start records the position of the start of a phrase. + // This is defined to be the position of the first + // character of the first token of the phrase. + + void start(SourcePosition position) { + position.start = currentToken.position.start; + } + + // finish records the position of the end of a phrase. + // This is defined to be the position of the last + // character of the last token of the phrase. + + void finish(SourcePosition position) { + position.finish = previousTokenPosition.finish; + } + + void syntacticError(String messageTemplate, String tokenQuoted) throws SyntaxError { + SourcePosition pos = currentToken.position; + errorReporter.reportError(messageTemplate, tokenQuoted, pos); + throw (new SyntaxError()); + } + + /////////////////////////////////////////////////////////////////////////////// + // + // PROGRAMS + // + /////////////////////////////////////////////////////////////////////////////// + + public Program parseProgram() { + + Program programAST = null; + + previousTokenPosition.start = 0; + previousTokenPosition.finish = 0; + currentToken = lexicalAnalyser.scan(); + + try { + Command cAST = parseCommand(); + programAST = new Program(cAST, previousTokenPosition); + if (currentToken.kind != Token.EOT) { + syntacticError("\"%\" not expected after end of program", currentToken.spelling); + } + } catch (SyntaxError s) { + return null; + } + return programAST; + } + + /////////////////////////////////////////////////////////////////////////////// + // + // LITERALS + // + /////////////////////////////////////////////////////////////////////////////// + + // parseIntegerLiteral parses an integer-literal, and constructs + // a leaf AST to represent it. + + IntegerLiteral parseIntegerLiteral() throws SyntaxError { + IntegerLiteral IL = null; + + if (currentToken.kind == Token.INTLITERAL) { + previousTokenPosition = currentToken.position; + String spelling = currentToken.spelling; + IL = new IntegerLiteral(spelling, previousTokenPosition); + currentToken = lexicalAnalyser.scan(); + } else { + IL = null; + syntacticError("integer literal expected here", ""); + } + return IL; + } + + // parseCharacterLiteral parses a character-literal, and constructs a leaf + // AST to represent it. + + CharacterLiteral parseCharacterLiteral() throws SyntaxError { + CharacterLiteral CL = null; + + if (currentToken.kind == Token.CHARLITERAL) { + previousTokenPosition = currentToken.position; + String spelling = currentToken.spelling; + CL = new CharacterLiteral(spelling, previousTokenPosition); + currentToken = lexicalAnalyser.scan(); + } else { + CL = null; + syntacticError("character literal expected here", ""); + } + return CL; + } + + // parseIdentifier parses an identifier, and constructs a leaf AST to + // represent it. + + Identifier parseIdentifier() throws SyntaxError { + Identifier I = null; + + if (currentToken.kind == Token.IDENTIFIER) { + previousTokenPosition = currentToken.position; + String spelling = currentToken.spelling; + I = new Identifier(spelling, previousTokenPosition); + currentToken = lexicalAnalyser.scan(); + } else { + I = null; + syntacticError("identifier expected here", ""); + } + return I; + } + + // parseOperator parses an operator, and constructs a leaf AST to + // represent it. + + Operator parseOperator() throws SyntaxError { + Operator O = null; + + if (currentToken.kind == Token.OPERATOR) { + previousTokenPosition = currentToken.position; + String spelling = currentToken.spelling; + O = new Operator(spelling, previousTokenPosition); + currentToken = lexicalAnalyser.scan(); + } else { + O = null; + syntacticError("operator expected here", ""); + } + return O; + } + + /////////////////////////////////////////////////////////////////////////////// + // + // COMMANDS + // + /////////////////////////////////////////////////////////////////////////////// + + // parseCommand parses the command, and constructs an AST + // to represent its phrase structure. + + Command parseCommand() throws SyntaxError { + Command commandAST = null; // in case there's a syntactic error + + SourcePosition commandPos = new SourcePosition(); + + start(commandPos); + commandAST = parseSingleCommand(); + while (currentToken.kind == Token.SEMICOLON) { + acceptIt(); + Command c2AST = parseSingleCommand(); + finish(commandPos); + commandAST = new SequentialCommand(commandAST, c2AST, commandPos); + } + return commandAST; + } + + Command parseSingleCommand() throws SyntaxError { + Command commandAST = null; // in case there's a syntactic error + + SourcePosition commandPos = new SourcePosition(); + start(commandPos); + + switch (currentToken.kind) { + + case Token.IDENTIFIER: { + Identifier iAST = parseIdentifier(); + if (currentToken.kind == Token.LPAREN) { + acceptIt(); + ActualParameterSequence apsAST = parseActualParameterSequence(); + accept(Token.RPAREN); + finish(commandPos); + commandAST = new CallCommand(iAST, apsAST, commandPos); + + } else { + + Vname vAST = parseRestOfVname(iAST); + accept(Token.BECOMES); + Expression eAST = parseExpression(); + finish(commandPos); + commandAST = new AssignCommand(vAST, eAST, commandPos); + } + } + break; + + case Token.BEGIN: + acceptIt(); + commandAST = parseCommand(); + accept(Token.END); + break; + + case Token.LET: { + acceptIt(); + Declaration dAST = parseDeclaration(); + accept(Token.IN); + Command cAST = parseSingleCommand(); + finish(commandPos); + commandAST = new LetCommand(dAST, cAST, commandPos); + } + break; + + case Token.IF: { + acceptIt(); + Expression eAST = parseExpression(); + accept(Token.THEN); + Command c1AST = parseSingleCommand(); + accept(Token.ELSE); + Command c2AST = parseSingleCommand(); + finish(commandPos); + commandAST = new IfCommand(eAST, c1AST, c2AST, commandPos); + } + break; + + case Token.WHILE: { + acceptIt(); + Expression eAST = parseExpression(); + accept(Token.DO); + Command cAST = parseSingleCommand(); + finish(commandPos); + commandAST = new WhileCommand(eAST, cAST, commandPos); + } + break; + + case Token.SEMICOLON: + case Token.END: + case Token.ELSE: + case Token.IN: + case Token.EOT: + + finish(commandPos); + commandAST = new EmptyCommand(commandPos); + break; + + default: + syntacticError("\"%\" cannot start a command", currentToken.spelling); + break; + + } + + return commandAST; + } + + /////////////////////////////////////////////////////////////////////////////// + // + // EXPRESSIONS + // + /////////////////////////////////////////////////////////////////////////////// + + Expression parseExpression() throws SyntaxError { + Expression expressionAST = null; // in case there's a syntactic error + + SourcePosition expressionPos = new SourcePosition(); + + start(expressionPos); + + switch (currentToken.kind) { + + case Token.LET: { + acceptIt(); + Declaration dAST = parseDeclaration(); + accept(Token.IN); + Expression eAST = parseExpression(); + finish(expressionPos); + expressionAST = new LetExpression(dAST, eAST, expressionPos); + } + break; + + case Token.IF: { + acceptIt(); + Expression e1AST = parseExpression(); + accept(Token.THEN); + Expression e2AST = parseExpression(); + accept(Token.ELSE); + Expression e3AST = parseExpression(); + finish(expressionPos); + expressionAST = new IfExpression(e1AST, e2AST, e3AST, expressionPos); + } + break; + + default: + expressionAST = parseSecondaryExpression(); + break; + } + return expressionAST; + } + + Expression parseSecondaryExpression() throws SyntaxError { + Expression expressionAST = null; // in case there's a syntactic error + + SourcePosition expressionPos = new SourcePosition(); + start(expressionPos); + + expressionAST = parsePrimaryExpression(); + while (currentToken.kind == Token.OPERATOR) { + Operator opAST = parseOperator(); + Expression e2AST = parsePrimaryExpression(); + expressionAST = new BinaryExpression(expressionAST, opAST, e2AST, expressionPos); + } + return expressionAST; + } + + Expression parsePrimaryExpression() throws SyntaxError { + Expression expressionAST = null; // in case there's a syntactic error + + SourcePosition expressionPos = new SourcePosition(); + start(expressionPos); + + switch (currentToken.kind) { + + case Token.INTLITERAL: { + IntegerLiteral ilAST = parseIntegerLiteral(); + finish(expressionPos); + expressionAST = new IntegerExpression(ilAST, expressionPos); + } + break; + + case Token.CHARLITERAL: { + CharacterLiteral clAST = parseCharacterLiteral(); + finish(expressionPos); + expressionAST = new CharacterExpression(clAST, expressionPos); + } + break; + + case Token.LBRACKET: { + acceptIt(); + ArrayAggregate aaAST = parseArrayAggregate(); + accept(Token.RBRACKET); + finish(expressionPos); + expressionAST = new ArrayExpression(aaAST, expressionPos); + } + break; + + case Token.LCURLY: { + acceptIt(); + RecordAggregate raAST = parseRecordAggregate(); + accept(Token.RCURLY); + finish(expressionPos); + expressionAST = new RecordExpression(raAST, expressionPos); + } + break; + + case Token.IDENTIFIER: { + Identifier iAST = parseIdentifier(); + if (currentToken.kind == Token.LPAREN) { + acceptIt(); + ActualParameterSequence apsAST = parseActualParameterSequence(); + accept(Token.RPAREN); + finish(expressionPos); + expressionAST = new CallExpression(iAST, apsAST, expressionPos); + + } else { + Vname vAST = parseRestOfVname(iAST); + finish(expressionPos); + expressionAST = new VnameExpression(vAST, expressionPos); + } + } + break; + + case Token.OPERATOR: { + Operator opAST = parseOperator(); + Expression eAST = parsePrimaryExpression(); + finish(expressionPos); + expressionAST = new UnaryExpression(opAST, eAST, expressionPos); + } + break; + + case Token.LPAREN: + acceptIt(); + expressionAST = parseExpression(); + accept(Token.RPAREN); + break; + + default: + syntacticError("\"%\" cannot start an expression", currentToken.spelling); + break; + + } + return expressionAST; + } + + RecordAggregate parseRecordAggregate() throws SyntaxError { + RecordAggregate aggregateAST = null; // in case there's a syntactic error + + SourcePosition aggregatePos = new SourcePosition(); + start(aggregatePos); + + Identifier iAST = parseIdentifier(); + accept(Token.IS); + Expression eAST = parseExpression(); + + if (currentToken.kind == Token.COMMA) { + acceptIt(); + RecordAggregate aAST = parseRecordAggregate(); + finish(aggregatePos); + aggregateAST = new MultipleRecordAggregate(iAST, eAST, aAST, aggregatePos); + } else { + finish(aggregatePos); + aggregateAST = new SingleRecordAggregate(iAST, eAST, aggregatePos); + } + return aggregateAST; + } + + ArrayAggregate parseArrayAggregate() throws SyntaxError { + ArrayAggregate aggregateAST = null; // in case there's a syntactic error + + SourcePosition aggregatePos = new SourcePosition(); + start(aggregatePos); + + Expression eAST = parseExpression(); + if (currentToken.kind == Token.COMMA) { + acceptIt(); + ArrayAggregate aAST = parseArrayAggregate(); + finish(aggregatePos); + aggregateAST = new MultipleArrayAggregate(eAST, aAST, aggregatePos); + } else { + finish(aggregatePos); + aggregateAST = new SingleArrayAggregate(eAST, aggregatePos); + } + return aggregateAST; + } + + /////////////////////////////////////////////////////////////////////////////// + // + // VALUE-OR-VARIABLE NAMES + // + /////////////////////////////////////////////////////////////////////////////// + + Vname parseVname() throws SyntaxError { + Vname vnameAST = null; // in case there's a syntactic error + Identifier iAST = parseIdentifier(); + vnameAST = parseRestOfVname(iAST); + return vnameAST; + } + + Vname parseRestOfVname(Identifier identifierAST) throws SyntaxError { + SourcePosition vnamePos = new SourcePosition(); + vnamePos = identifierAST.position; + Vname vAST = new SimpleVname(identifierAST, vnamePos); + + while (currentToken.kind == Token.DOT || currentToken.kind == Token.LBRACKET) { + + if (currentToken.kind == Token.DOT) { + acceptIt(); + Identifier iAST = parseIdentifier(); + vAST = new DotVname(vAST, iAST, vnamePos); + } else { + acceptIt(); + Expression eAST = parseExpression(); + accept(Token.RBRACKET); + finish(vnamePos); + vAST = new SubscriptVname(vAST, eAST, vnamePos); + } + } + return vAST; + } + + /////////////////////////////////////////////////////////////////////////////// + // + // DECLARATIONS + // + /////////////////////////////////////////////////////////////////////////////// + + Declaration parseDeclaration() throws SyntaxError { + Declaration declarationAST = null; // in case there's a syntactic error + + SourcePosition declarationPos = new SourcePosition(); + start(declarationPos); + declarationAST = parseSingleDeclaration(); + while (currentToken.kind == Token.SEMICOLON) { + acceptIt(); + Declaration d2AST = parseSingleDeclaration(); + finish(declarationPos); + declarationAST = new SequentialDeclaration(declarationAST, d2AST, declarationPos); + } + return declarationAST; + } + + Declaration parseSingleDeclaration() throws SyntaxError { + Declaration declarationAST = null; // in case there's a syntactic error + + SourcePosition declarationPos = new SourcePosition(); + start(declarationPos); + + switch (currentToken.kind) { + + case Token.CONST: { + acceptIt(); + Identifier iAST = parseIdentifier(); + accept(Token.IS); + Expression eAST = parseExpression(); + finish(declarationPos); + declarationAST = new ConstDeclaration(iAST, eAST, declarationPos); + } + break; + + case Token.VAR: { + acceptIt(); + Identifier iAST = parseIdentifier(); + accept(Token.COLON); + TypeDenoter tAST = parseTypeDenoter(); + finish(declarationPos); + declarationAST = new VarDeclaration(iAST, tAST, declarationPos); + } + break; + + case Token.PROC: { + acceptIt(); + Identifier iAST = parseIdentifier(); + accept(Token.LPAREN); + FormalParameterSequence fpsAST = parseFormalParameterSequence(); + accept(Token.RPAREN); + accept(Token.IS); + Command cAST = parseSingleCommand(); + finish(declarationPos); + declarationAST = new ProcDeclaration(iAST, fpsAST, cAST, declarationPos); + } + break; + + case Token.FUNC: { + acceptIt(); + Identifier iAST = parseIdentifier(); + accept(Token.LPAREN); + FormalParameterSequence fpsAST = parseFormalParameterSequence(); + accept(Token.RPAREN); + accept(Token.COLON); + TypeDenoter tAST = parseTypeDenoter(); + accept(Token.IS); + Expression eAST = parseExpression(); + finish(declarationPos); + declarationAST = new FuncDeclaration(iAST, fpsAST, tAST, eAST, declarationPos); + } + break; + + case Token.TYPE: { + acceptIt(); + Identifier iAST = parseIdentifier(); + accept(Token.IS); + TypeDenoter tAST = parseTypeDenoter(); + finish(declarationPos); + declarationAST = new TypeDeclaration(iAST, tAST, declarationPos); + } + break; + + default: + syntacticError("\"%\" cannot start a declaration", currentToken.spelling); + break; + + } + return declarationAST; + } + + /////////////////////////////////////////////////////////////////////////////// + // + // PARAMETERS + // + /////////////////////////////////////////////////////////////////////////////// + + FormalParameterSequence parseFormalParameterSequence() throws SyntaxError { + FormalParameterSequence formalsAST; + + SourcePosition formalsPos = new SourcePosition(); + + start(formalsPos); + if (currentToken.kind == Token.RPAREN) { + finish(formalsPos); + formalsAST = new EmptyFormalParameterSequence(formalsPos); + + } else { + formalsAST = parseProperFormalParameterSequence(); + } + return formalsAST; + } + + FormalParameterSequence parseProperFormalParameterSequence() throws SyntaxError { + FormalParameterSequence formalsAST = null; // in case there's a syntactic error; + + SourcePosition formalsPos = new SourcePosition(); + start(formalsPos); + FormalParameter fpAST = parseFormalParameter(); + if (currentToken.kind == Token.COMMA) { + acceptIt(); + FormalParameterSequence fpsAST = parseProperFormalParameterSequence(); + finish(formalsPos); + formalsAST = new MultipleFormalParameterSequence(fpAST, fpsAST, formalsPos); + + } else { + finish(formalsPos); + formalsAST = new SingleFormalParameterSequence(fpAST, formalsPos); + } + return formalsAST; + } + + FormalParameter parseFormalParameter() throws SyntaxError { + FormalParameter formalAST = null; // in case there's a syntactic error; + + SourcePosition formalPos = new SourcePosition(); + start(formalPos); + + switch (currentToken.kind) { + + case Token.IDENTIFIER: { + Identifier iAST = parseIdentifier(); + accept(Token.COLON); + TypeDenoter tAST = parseTypeDenoter(); + finish(formalPos); + formalAST = new ConstFormalParameter(iAST, tAST, formalPos); + } + break; + + case Token.VAR: { + acceptIt(); + Identifier iAST = parseIdentifier(); + accept(Token.COLON); + TypeDenoter tAST = parseTypeDenoter(); + finish(formalPos); + formalAST = new VarFormalParameter(iAST, tAST, formalPos); + } + break; + + case Token.PROC: { + acceptIt(); + Identifier iAST = parseIdentifier(); + accept(Token.LPAREN); + FormalParameterSequence fpsAST = parseFormalParameterSequence(); + accept(Token.RPAREN); + finish(formalPos); + formalAST = new ProcFormalParameter(iAST, fpsAST, formalPos); + } + break; + + case Token.FUNC: { + acceptIt(); + Identifier iAST = parseIdentifier(); + accept(Token.LPAREN); + FormalParameterSequence fpsAST = parseFormalParameterSequence(); + accept(Token.RPAREN); + accept(Token.COLON); + TypeDenoter tAST = parseTypeDenoter(); + finish(formalPos); + formalAST = new FuncFormalParameter(iAST, fpsAST, tAST, formalPos); + } + break; + + default: + syntacticError("\"%\" cannot start a formal parameter", currentToken.spelling); + break; + + } + return formalAST; + } + + ActualParameterSequence parseActualParameterSequence() throws SyntaxError { + ActualParameterSequence actualsAST; + + SourcePosition actualsPos = new SourcePosition(); + + start(actualsPos); + if (currentToken.kind == Token.RPAREN) { + finish(actualsPos); + actualsAST = new EmptyActualParameterSequence(actualsPos); + + } else { + actualsAST = parseProperActualParameterSequence(); + } + return actualsAST; + } + + ActualParameterSequence parseProperActualParameterSequence() throws SyntaxError { + ActualParameterSequence actualsAST = null; // in case there's a syntactic error + + SourcePosition actualsPos = new SourcePosition(); + + start(actualsPos); + ActualParameter apAST = parseActualParameter(); + if (currentToken.kind == Token.COMMA) { + acceptIt(); + ActualParameterSequence apsAST = parseProperActualParameterSequence(); + finish(actualsPos); + actualsAST = new MultipleActualParameterSequence(apAST, apsAST, actualsPos); + } else { + finish(actualsPos); + actualsAST = new SingleActualParameterSequence(apAST, actualsPos); + } + return actualsAST; + } + + ActualParameter parseActualParameter() throws SyntaxError { + ActualParameter actualAST = null; // in case there's a syntactic error + + SourcePosition actualPos = new SourcePosition(); + + start(actualPos); + + switch (currentToken.kind) { + + case Token.IDENTIFIER: + case Token.INTLITERAL: + case Token.CHARLITERAL: + case Token.OPERATOR: + case Token.LET: + case Token.IF: + case Token.LPAREN: + case Token.LBRACKET: + case Token.LCURLY: { + Expression eAST = parseExpression(); + finish(actualPos); + actualAST = new ConstActualParameter(eAST, actualPos); + } + break; + + case Token.VAR: { + acceptIt(); + Vname vAST = parseVname(); + finish(actualPos); + actualAST = new VarActualParameter(vAST, actualPos); + } + break; + + case Token.PROC: { + acceptIt(); + Identifier iAST = parseIdentifier(); + finish(actualPos); + actualAST = new ProcActualParameter(iAST, actualPos); + } + break; + + case Token.FUNC: { + acceptIt(); + Identifier iAST = parseIdentifier(); + finish(actualPos); + actualAST = new FuncActualParameter(iAST, actualPos); + } + break; + + default: + syntacticError("\"%\" cannot start an actual parameter", currentToken.spelling); + break; + + } + return actualAST; + } + + /////////////////////////////////////////////////////////////////////////////// + // + // TYPE-DENOTERS + // + /////////////////////////////////////////////////////////////////////////////// + + TypeDenoter parseTypeDenoter() throws SyntaxError { + TypeDenoter typeAST = null; // in case there's a syntactic error + SourcePosition typePos = new SourcePosition(); + + start(typePos); + + switch (currentToken.kind) { + + case Token.IDENTIFIER: { + Identifier iAST = parseIdentifier(); + finish(typePos); + typeAST = new SimpleTypeDenoter(iAST, typePos); + } + break; + + case Token.ARRAY: { + acceptIt(); + IntegerLiteral ilAST = parseIntegerLiteral(); + accept(Token.OF); + TypeDenoter tAST = parseTypeDenoter(); + finish(typePos); + typeAST = new ArrayTypeDenoter(ilAST, tAST, typePos); + } + break; + + case Token.RECORD: { + acceptIt(); + FieldTypeDenoter fAST = parseFieldTypeDenoter(); + accept(Token.END); + finish(typePos); + typeAST = new RecordTypeDenoter(fAST, typePos); + } + break; + + default: + syntacticError("\"%\" cannot start a type denoter", currentToken.spelling); + break; + + } + return typeAST; + } + + FieldTypeDenoter parseFieldTypeDenoter() throws SyntaxError { + FieldTypeDenoter fieldAST = null; // in case there's a syntactic error + + SourcePosition fieldPos = new SourcePosition(); + + start(fieldPos); + Identifier iAST = parseIdentifier(); + accept(Token.COLON); + TypeDenoter tAST = parseTypeDenoter(); + if (currentToken.kind == Token.COMMA) { + acceptIt(); + FieldTypeDenoter fAST = parseFieldTypeDenoter(); + finish(fieldPos); + fieldAST = new MultipleFieldTypeDenoter(iAST, tAST, fAST, fieldPos); + } else { + finish(fieldPos); + fieldAST = new SingleFieldTypeDenoter(iAST, tAST, fieldPos); + } + return fieldAST; + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Scanner.java b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Scanner.java index 8d347a9..1d482c8 100644 --- a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Scanner.java +++ b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Scanner.java @@ -16,258 +16,253 @@ package Triangle.SyntacticAnalyzer; public final class Scanner { - private SourceFile sourceFile; - private boolean debug; - - private char currentChar; - private StringBuffer currentSpelling; - private boolean currentlyScanningToken; - - private boolean isLetter(char c) { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); - } - - private boolean isDigit(char c) { - return (c >= '0' && c <= '9'); - } - - // isOperator returns true iff the given character is an operator character. - - private boolean isOperator(char c) { - return (c == '+' || c == '-' || c == '*' || c == '/' || - c == '=' || c == '<' || c == '>' || c == '\\' || - c == '&' || c == '@' || c == '%' || c == '^' || - c == '?'); - } - - /////////////////////////////////////////////////////////////////////////////// - - public Scanner(SourceFile source) { - sourceFile = source; - currentChar = sourceFile.getSource(); - debug = false; - } - - public void enableDebugging() { - debug = true; - } - - // takeIt appends the current character to the current token, and gets - // the next character from the source program. - - private void takeIt() { - if (currentlyScanningToken) - currentSpelling.append(currentChar); - currentChar = sourceFile.getSource(); - } - - // scanSeparator skips a single separator. - - private void scanSeparator() { - switch (currentChar) { - case '!': { - takeIt(); - while ((currentChar != SourceFile.EOL) && (currentChar != SourceFile.EOT)) - takeIt(); - if (currentChar == SourceFile.EOL) - takeIt(); - } - break; - - case ' ': - case '\n': - case '\r': - case '\t': - takeIt(); - break; - } - } - - private int scanToken() { - - switch (currentChar) { - - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - case 'g': - case 'h': - case 'i': - case 'j': - case 'k': - case 'l': - case 'm': - case 'n': - case 'o': - case 'p': - case 'q': - case 'r': - case 's': - case 't': - case 'u': - case 'v': - case 'w': - case 'x': - case 'y': - case 'z': - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - case 'G': - case 'H': - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'N': - case 'O': - case 'P': - case 'Q': - case 'R': - case 'S': - case 'T': - case 'U': - case 'V': - case 'W': - case 'X': - case 'Y': - case 'Z': - takeIt(); - while (isLetter(currentChar) || isDigit(currentChar)) - takeIt(); - return Token.IDENTIFIER; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - takeIt(); - while (isDigit(currentChar)) - takeIt(); - return Token.INTLITERAL; - - case '+': - case '-': - case '*': - case '/': - case '=': - case '<': - case '>': - case '\\': - case '&': - case '@': - case '%': - case '^': - case '?': - takeIt(); - while (isOperator(currentChar)) - takeIt(); - return Token.OPERATOR; - - case '\'': - takeIt(); - takeIt(); // the quoted character - if (currentChar == '\'') { - takeIt(); - return Token.CHARLITERAL; - } else - return Token.ERROR; - - case '.': - takeIt(); - return Token.DOT; - - case ':': - takeIt(); - if (currentChar == '=') { - takeIt(); - return Token.BECOMES; - } else - return Token.COLON; - - case ';': - takeIt(); - return Token.SEMICOLON; - - case ',': - takeIt(); - return Token.COMMA; - - case '~': - takeIt(); - return Token.IS; - - case '(': - takeIt(); - return Token.LPAREN; - - case ')': - takeIt(); - return Token.RPAREN; - - case '[': - takeIt(); - return Token.LBRACKET; - - case ']': - takeIt(); - return Token.RBRACKET; - - case '{': - takeIt(); - return Token.LCURLY; - - case '}': - takeIt(); - return Token.RCURLY; - - case SourceFile.EOT: - return Token.EOT; - - default: - takeIt(); - return Token.ERROR; - } - } - - public Token scan() { - Token tok; - SourcePosition pos; - int kind; - - currentlyScanningToken = false; - while (currentChar == '!' - || currentChar == ' ' - || currentChar == '\n' - || currentChar == '\r' - || currentChar == '\t') - scanSeparator(); - - currentlyScanningToken = true; - currentSpelling = new StringBuffer(""); - pos = new SourcePosition(); - pos.start = sourceFile.getCurrentLine(); - - kind = scanToken(); - - pos.finish = sourceFile.getCurrentLine(); - tok = new Token(kind, currentSpelling.toString(), pos); - if (debug) - System.out.println(tok); - return tok; - } + private SourceFile sourceFile; + private boolean debug; + + private char currentChar; + private StringBuffer currentSpelling; + private boolean currentlyScanningToken; + + private boolean isLetter(char c) { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); + } + + private boolean isDigit(char c) { + return (c >= '0' && c <= '9'); + } + + // isOperator returns true iff the given character is an operator character. + + private boolean isOperator(char c) { + return (c == '+' || c == '-' || c == '*' || c == '/' || c == '=' || c == '<' || c == '>' || c == '\\' + || c == '&' || c == '@' || c == '%' || c == '^' || c == '?'); + } + + /////////////////////////////////////////////////////////////////////////////// + + public Scanner(SourceFile source) { + sourceFile = source; + currentChar = sourceFile.getSource(); + debug = false; + } + + public void enableDebugging() { + debug = true; + } + + // takeIt appends the current character to the current token, and gets + // the next character from the source program. + + private void takeIt() { + if (currentlyScanningToken) + currentSpelling.append(currentChar); + currentChar = sourceFile.getSource(); + } + + // scanSeparator skips a single separator. + + private void scanSeparator() { + switch (currentChar) { + case '!': { + takeIt(); + while ((currentChar != SourceFile.EOL) && (currentChar != SourceFile.EOT)) + takeIt(); + if (currentChar == SourceFile.EOL) + takeIt(); + } + break; + + case ' ': + case '\n': + case '\r': + case '\t': + takeIt(); + break; + } + } + + private int scanToken() { + + switch (currentChar) { + + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + takeIt(); + while (isLetter(currentChar) || isDigit(currentChar)) + takeIt(); + return Token.IDENTIFIER; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + takeIt(); + while (isDigit(currentChar)) + takeIt(); + return Token.INTLITERAL; + + case '+': + case '-': + case '*': + case '/': + case '=': + case '<': + case '>': + case '\\': + case '&': + case '@': + case '%': + case '^': + case '?': + takeIt(); + while (isOperator(currentChar)) + takeIt(); + return Token.OPERATOR; + + case '\'': + takeIt(); + takeIt(); // the quoted character + if (currentChar == '\'') { + takeIt(); + return Token.CHARLITERAL; + } else + return Token.ERROR; + + case '.': + takeIt(); + return Token.DOT; + + case ':': + takeIt(); + if (currentChar == '=') { + takeIt(); + return Token.BECOMES; + } else + return Token.COLON; + + case ';': + takeIt(); + return Token.SEMICOLON; + + case ',': + takeIt(); + return Token.COMMA; + + case '~': + takeIt(); + return Token.IS; + + case '(': + takeIt(); + return Token.LPAREN; + + case ')': + takeIt(); + return Token.RPAREN; + + case '[': + takeIt(); + return Token.LBRACKET; + + case ']': + takeIt(); + return Token.RBRACKET; + + case '{': + takeIt(); + return Token.LCURLY; + + case '}': + takeIt(); + return Token.RCURLY; + + case SourceFile.EOT: + return Token.EOT; + + default: + takeIt(); + return Token.ERROR; + } + } + + public Token scan() { + Token tok; + SourcePosition pos; + int kind; + + currentlyScanningToken = false; + while (currentChar == '!' || currentChar == ' ' || currentChar == '\n' || currentChar == '\r' + || currentChar == '\t') + scanSeparator(); + + currentlyScanningToken = true; + currentSpelling = new StringBuffer(""); + pos = new SourcePosition(); + pos.start = sourceFile.getCurrentLine(); + + kind = scanToken(); + + pos.finish = sourceFile.getCurrentLine(); + tok = new Token(kind, currentSpelling.toString(), pos); + if (debug) + System.out.println(tok); + return tok; + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourceFile.java b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourceFile.java index 3ec7aa2..05a6a89 100644 --- a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourceFile.java +++ b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourceFile.java @@ -16,41 +16,43 @@ package Triangle.SyntacticAnalyzer; public class SourceFile { - public static final char EOL = '\n'; - public static final char EOT = '\u0000'; - - java.io.File sourceFile; - java.io.FileInputStream source; - int currentLine; - - public SourceFile(String filename) { - try { - sourceFile = new java.io.File(filename); - source = new java.io.FileInputStream(sourceFile); - currentLine = 1; - } catch (java.io.IOException s) { - sourceFile = null; - source = null; - currentLine = 0; - } - } - - char getSource() { - try { - int c = source.read(); - - if (c == -1) { - c = EOT; - } else if (c == EOL) { - currentLine++; - } - return (char) c; - } catch (java.io.IOException s) { - return EOT; - } - } - - int getCurrentLine() { - return currentLine; - } + public static final char EOL = '\n'; + public static final char EOT = '\u0000'; + + java.io.File sourceFile; + java.io.FileInputStream source; + int currentLine; + + public static SourceFile ofPath(String pathname) { + try { + return new SourceFile(pathname); + } catch (java.io.IOException s) { + return null; + } + } + + private SourceFile(String pathname) throws java.io.FileNotFoundException { + sourceFile = new java.io.File(pathname); + source = new java.io.FileInputStream(sourceFile); + currentLine = 1; + } + + char getSource() { + try { + int c = source.read(); + + if (c == -1) { + c = EOT; + } else if (c == EOL) { + currentLine++; + } + return (char) c; + } catch (java.io.IOException s) { + return EOT; + } + } + + int getCurrentLine() { + return currentLine; + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourcePosition.java b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourcePosition.java index e67ec3b..19d0272 100644 --- a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourcePosition.java +++ b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourcePosition.java @@ -16,20 +16,20 @@ package Triangle.SyntacticAnalyzer; public class SourcePosition { - public int start, finish; + public int start, finish; - public SourcePosition() { - start = 0; - finish = 0; - } + public SourcePosition() { + start = 0; + finish = 0; + } - public SourcePosition(int s, int f) { - start = s; - finish = f; - } + public SourcePosition(int s, int f) { + start = s; + finish = f; + } - @Override -public String toString() { - return "(" + start + ", " + finish + ")"; - } + @Override + public String toString() { + return "(" + start + ", " + finish + ")"; + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SyntaxError.java b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SyntaxError.java index 3f05579..4c88d5f 100644 --- a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SyntaxError.java +++ b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SyntaxError.java @@ -16,14 +16,14 @@ package Triangle.SyntacticAnalyzer; class SyntaxError extends Exception { - private static final long serialVersionUID = -5280306336102766860L; + private static final long serialVersionUID = -5280306336102766860L; -SyntaxError() { - super(); - } + SyntaxError() { + super(); + } - SyntaxError(String s) { - super(s); - } + SyntaxError(String s) { + super(s); + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Token.java b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Token.java index 292db19..7fc5126 100644 --- a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Token.java +++ b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Token.java @@ -16,134 +16,69 @@ package Triangle.SyntacticAnalyzer; final class Token extends Object { - protected int kind; - protected String spelling; - protected SourcePosition position; - - public Token(int kind, String spelling, SourcePosition position) { - - if (kind == Token.IDENTIFIER) { - int currentKind = firstReservedWord; - boolean searching = true; - - while (searching) { - int comparison = tokenTable[currentKind].compareTo(spelling); - if (comparison == 0) { - this.kind = currentKind; - searching = false; - } else if (comparison > 0 || currentKind == lastReservedWord) { - this.kind = Token.IDENTIFIER; - searching = false; - } else { - currentKind++; - } - } - } else - this.kind = kind; - - this.spelling = spelling; - this.position = position; - - } - - public static String spell(int kind) { - return tokenTable[kind]; - } - - @Override -public String toString() { - return "Kind=" + kind + ", spelling=" + spelling + - ", position=" + position; - } - - // Token classes... - - public static final int - - // literals, identifiers, operators... - INTLITERAL = 0, - CHARLITERAL = 1, - IDENTIFIER = 2, - OPERATOR = 3, - - // reserved words - must be in alphabetical order... - ARRAY = 4, - BEGIN = 5, - CONST = 6, - DO = 7, - ELSE = 8, - END = 9, - FUNC = 10, - IF = 11, - IN = 12, - LET = 13, - OF = 14, - PROC = 15, - RECORD = 16, - THEN = 17, - TYPE = 18, - VAR = 19, - WHILE = 20, - - // punctuation... - DOT = 21, - COLON = 22, - SEMICOLON = 23, - COMMA = 24, - BECOMES = 25, - IS = 26, - - // brackets... - LPAREN = 27, - RPAREN = 28, - LBRACKET = 29, - RBRACKET = 30, - LCURLY = 31, - RCURLY = 32, - - // special tokens... - EOT = 33, - ERROR = 34; - - private static String[] tokenTable = new String[] { - "", - "", - "", - "", - "array", - "begin", - "const", - "do", - "else", - "end", - "func", - "if", - "in", - "let", - "of", - "proc", - "record", - "then", - "type", - "var", - "while", - ".", - ":", - ";", - ",", - ":=", - "~", - "(", - ")", - "[", - "]", - "{", - "}", - "", - "" - }; - - private final static int firstReservedWord = Token.ARRAY, - lastReservedWord = Token.WHILE; + protected int kind; + protected String spelling; + protected SourcePosition position; + + public Token(int kind, String spelling, SourcePosition position) { + + if (kind == Token.IDENTIFIER) { + int currentKind = firstReservedWord; + boolean searching = true; + + while (searching) { + int comparison = tokenTable[currentKind].compareTo(spelling); + if (comparison == 0) { + this.kind = currentKind; + searching = false; + } else if (comparison > 0 || currentKind == lastReservedWord) { + this.kind = Token.IDENTIFIER; + searching = false; + } else { + currentKind++; + } + } + } else + this.kind = kind; + + this.spelling = spelling; + this.position = position; + + } + + public static String spell(int kind) { + return tokenTable[kind]; + } + + @Override + public String toString() { + return "Kind=" + kind + ", spelling=" + spelling + ", position=" + position; + } + + // Token classes... + + public static final int + + // literals, identifiers, operators... + INTLITERAL = 0, CHARLITERAL = 1, IDENTIFIER = 2, OPERATOR = 3, + + // reserved words - must be in alphabetical order... + ARRAY = 4, BEGIN = 5, CONST = 6, DO = 7, ELSE = 8, END = 9, FUNC = 10, IF = 11, IN = 12, LET = 13, OF = 14, + PROC = 15, RECORD = 16, THEN = 17, TYPE = 18, VAR = 19, WHILE = 20, + + // punctuation... + DOT = 21, COLON = 22, SEMICOLON = 23, COMMA = 24, BECOMES = 25, IS = 26, + + // brackets... + LPAREN = 27, RPAREN = 28, LBRACKET = 29, RBRACKET = 30, LCURLY = 31, RCURLY = 32, + + // special tokens... + EOT = 33, ERROR = 34; + + private static String[] tokenTable = new String[] { "", "", "", "", "array", + "begin", "const", "do", "else", "end", "func", "if", "in", "let", "of", "proc", "record", "then", "type", + "var", "while", ".", ":", ";", ",", ":=", "~", "(", ")", "[", "]", "{", "}", "", "" }; + + private final static int firstReservedWord = Token.ARRAY, lastReservedWord = Token.WHILE; } diff --git a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Drawer.java b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Drawer.java index 6366c25..ea94c33 100644 --- a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Drawer.java +++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Drawer.java @@ -24,38 +24,38 @@ import Triangle.AbstractSyntaxTrees.Program; public class Drawer { - private DrawerFrame frame; - private DrawerPanel panel; + private DrawerFrame frame; + private DrawerPanel panel; - private Program theAST; - private DrawingTree theDrawing; + private Program theAST; + private DrawingTree theDrawing; - // Draw the AST representing a complete program. + // Draw the AST representing a complete program. - public void draw(Program ast) { - theAST = ast; - panel = new DrawerPanel(this); - frame = new DrawerFrame(panel); + public void draw(Program ast) { + theAST = ast; + panel = new DrawerPanel(this); + frame = new DrawerFrame(panel); - Font font = new Font("SansSerif", Font.PLAIN, 12); - frame.setFont(font); + Font font = new Font("SansSerif", Font.PLAIN, 12); + frame.setFont(font); - FontMetrics fontMetrics = frame.getFontMetrics(font); + FontMetrics fontMetrics = frame.getFontMetrics(font); - LayoutVisitor layout = new LayoutVisitor(fontMetrics); - theDrawing = (DrawingTree) theAST.visit(layout, null); - theDrawing.position(new Point(2048, 10)); + LayoutVisitor layout = new LayoutVisitor(fontMetrics); + theDrawing = (DrawingTree) theAST.visit(layout, null); + theDrawing.position(new Point(2048, 10)); - frame.setVisible(true); - } + frame.setVisible(true); + } - public void paintAST(Graphics g) { - g.setColor(panel.getBackground()); - Dimension d = panel.getSize(); - g.fillRect(0, 0, d.width, d.height); + public void paintAST(Graphics g) { + g.setColor(panel.getBackground()); + Dimension d = panel.getSize(); + g.fillRect(0, 0, d.width, d.height); - if (theDrawing != null) { - theDrawing.paint(g); - } - } + if (theDrawing != null) { + theDrawing.paint(g); + } + } } diff --git a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerFrame.java b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerFrame.java index 1945c46..3444be8 100644 --- a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerFrame.java +++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerFrame.java @@ -25,31 +25,30 @@ import javax.swing.JPanel; import javax.swing.JScrollPane; class DrawerFrame extends JFrame { - /** + /** * */ private static final long serialVersionUID = -3650404598416929282L; -public DrawerFrame(JPanel panel) { - setSize(300, 200); - Toolkit tk = Toolkit.getDefaultToolkit(); - Dimension d = tk.getScreenSize(); - int screenHeight = d.height; - int screenWidth = d.width; - setTitle("Triangle Compiler Abstract Syntax Tree"); - setSize(screenWidth / 2, screenHeight / 2); - setLocation(screenWidth / 4, screenHeight / 4); - // Image img = tk.getImage("icon.gif"); - // setIconImage(img); + public DrawerFrame(JPanel panel) { + setSize(300, 200); + Toolkit tk = Toolkit.getDefaultToolkit(); + Dimension d = tk.getScreenSize(); + int screenHeight = d.height; + int screenWidth = d.width; + setTitle("Triangle Compiler Abstract Syntax Tree"); + setSize(screenWidth / 2, screenHeight / 2); + setLocation(screenWidth / 4, screenHeight / 4); + // Image img = tk.getImage("icon.gif"); + // setIconImage(img); - addWindowListener( - new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - System.exit(0); - } - }); - Container contentPane = getContentPane(); - contentPane.add(new JScrollPane(panel)); - } + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + Container contentPane = getContentPane(); + contentPane.add(new JScrollPane(panel)); + } } \ No newline at end of file diff --git a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerPanel.java b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerPanel.java index cf5e66f..5c6e8b6 100644 --- a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerPanel.java +++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerPanel.java @@ -20,20 +20,20 @@ import java.awt.Graphics; import javax.swing.JPanel; class DrawerPanel extends JPanel { - /** + /** * */ private static final long serialVersionUID = 565914745506889669L; -private Drawer drawer; + private Drawer drawer; - public DrawerPanel(Drawer drawer) { - setPreferredSize(new Dimension(4096, 4096)); - this.drawer = drawer; - } + public DrawerPanel(Drawer drawer) { + setPreferredSize(new Dimension(4096, 4096)); + this.drawer = drawer; + } - @Override -public void paintComponent(Graphics g) { - super.paintComponent(g); - drawer.paintAST(g); - } + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + drawer.paintAST(g); + } } \ No newline at end of file diff --git a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawingTree.java b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawingTree.java index 14ba193..36a8e69 100644 --- a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawingTree.java +++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawingTree.java @@ -20,69 +20,66 @@ import java.awt.Point; public class DrawingTree { - String caption; - int width, height; - Point pos, offset; - Polygon contour; - DrawingTree parent; - DrawingTree[] children; + String caption; + int width, height; + Point pos, offset; + Polygon contour; + DrawingTree parent; + DrawingTree[] children; - public DrawingTree(String caption, int width, int height) { - this.caption = caption; - this.width = width; - this.height = height; - this.parent = null; - this.children = null; - this.pos = new Point(0, 0); - this.offset = new Point(0, 0); - this.contour = new Polygon(); - } + public DrawingTree(String caption, int width, int height) { + this.caption = caption; + this.width = width; + this.height = height; + this.parent = null; + this.children = null; + this.pos = new Point(0, 0); + this.offset = new Point(0, 0); + this.contour = new Polygon(); + } - public void setChildren(DrawingTree[] children) { - this.children = children; - for (int i = 0; i < children.length; i++) - children[i].parent = this; - } + public void setChildren(DrawingTree[] children) { + this.children = children; + for (int i = 0; i < children.length; i++) + children[i].parent = this; + } - private final int FIXED_FONT_HEIGHT = 10; - private final int FIXED_FONT_ASCENT = 3; - private final Color nodeColor = new Color(250, 220, 100); + private final int FIXED_FONT_HEIGHT = 10; + private final int FIXED_FONT_ASCENT = 3; + private final Color nodeColor = new Color(250, 220, 100); - public void paint(Graphics graphics) { - graphics.setColor(nodeColor); - graphics.fillRect(pos.x, pos.y, width, height); - graphics.setColor(Color.black); - graphics.drawRect(pos.x, pos.y, width - 1, height - 1); - graphics.drawString(caption, pos.x + 2, - pos.y + (height + FIXED_FONT_HEIGHT) / 2); + public void paint(Graphics graphics) { + graphics.setColor(nodeColor); + graphics.fillRect(pos.x, pos.y, width, height); + graphics.setColor(Color.black); + graphics.drawRect(pos.x, pos.y, width - 1, height - 1); + graphics.drawString(caption, pos.x + 2, pos.y + (height + FIXED_FONT_HEIGHT) / 2); - if (children != null) { - for (DrawingTree child : children) { - child.paint(graphics); - } - } + if (children != null) { + for (DrawingTree child : children) { + child.paint(graphics); + } + } - if (parent != null) { - graphics.drawLine(pos.x + width / 2, pos.y, - parent.pos.x + parent.width / 2, - parent.pos.y + parent.height); - } - } + if (parent != null) { + graphics.drawLine(pos.x + width / 2, pos.y, parent.pos.x + parent.width / 2, parent.pos.y + parent.height); + } + } - public void position(Point pos) { + public void position(Point pos) { - this.pos.x = pos.x + this.offset.x; - this.pos.y = pos.y + this.offset.y; + this.pos.x = pos.x + this.offset.x; + this.pos.y = pos.y + this.offset.y; - Point temp = new Point(this.pos.x, this.pos.y); + Point temp = new Point(this.pos.x, this.pos.y); - if (children != null) { - for (DrawingTree child : children) { - child.position(temp); - temp.x += child.offset.x; - temp.y = this.pos.y + children[0].offset.y; - } - } - } + if (children != null) { + for (DrawingTree child : children) { + child.position(temp); + temp.x += child.offset.x; + temp.y = this.pos.y + children[0].offset.y; + } + } + } } \ No newline at end of file diff --git a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/LayoutVisitor.java b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/LayoutVisitor.java index e4f722a..158733a 100644 --- a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/LayoutVisitor.java +++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/LayoutVisitor.java @@ -83,513 +83,507 @@ import Triangle.AbstractSyntaxTrees.WhileCommand; public class LayoutVisitor implements Visitor { - private final int BORDER = 5; - private final int PARENT_SEP = 30; - - private FontMetrics fontMetrics; - - public LayoutVisitor(FontMetrics fontMetrics) { - this.fontMetrics = fontMetrics; - } - - // Commands - @Override -public Object visitAssignCommand(AssignCommand ast, Object obj) { - return layoutBinary("AssignCom.", ast.V, ast.E); - } - - @Override -public Object visitCallCommand(CallCommand ast, Object obj) { - return layoutBinary("CallCom.", ast.I, ast.APS); - } - - @Override -public Object visitEmptyCommand(EmptyCommand ast, Object obj) { - return layoutNullary("EmptyCom."); - } - - @Override -public Object visitIfCommand(IfCommand ast, Object obj) { - return layoutTernary("IfCom.", ast.E, ast.C1, ast.C2); - } - - @Override -public Object visitLetCommand(LetCommand ast, Object obj) { - return layoutBinary("LetCom.", ast.D, ast.C); - } - - @Override -public Object visitSequentialCommand(SequentialCommand ast, Object obj) { - return layoutBinary("Seq.Com.", ast.C1, ast.C2); - } - - @Override -public Object visitWhileCommand(WhileCommand ast, Object obj) { - return layoutBinary("WhileCom.", ast.E, ast.C); - } - - // Expressions - @Override -public Object visitArrayExpression(ArrayExpression ast, Object obj) { - return layoutUnary("ArrayExpr.", ast.AA); - } - - @Override -public Object visitBinaryExpression(BinaryExpression ast, Object obj) { - return layoutTernary("Bin.Expr.", ast.E1, ast.O, ast.E2); - } - - @Override -public Object visitCallExpression(CallExpression ast, Object obj) { - return layoutBinary("CallExpr.", ast.I, ast.APS); - } - - @Override -public Object visitCharacterExpression(CharacterExpression ast, Object obj) { - return layoutUnary("Char.Expr.", ast.CL); - } - - @Override -public Object visitEmptyExpression(EmptyExpression ast, Object obj) { - return layoutNullary("EmptyExpr."); - } - - @Override -public Object visitIfExpression(IfExpression ast, Object obj) { - return layoutTernary("IfExpr.", ast.E1, ast.E2, ast.E3); - } - - @Override -public Object visitIntegerExpression(IntegerExpression ast, Object obj) { - return layoutUnary("Int.Expr.", ast.IL); - } - - @Override -public Object visitLetExpression(LetExpression ast, Object obj) { - return layoutBinary("LetExpr.", ast.D, ast.E); - } - - @Override -public Object visitRecordExpression(RecordExpression ast, Object obj) { - return layoutUnary("Rec.Expr.", ast.RA); - } - - @Override -public Object visitUnaryExpression(UnaryExpression ast, Object obj) { - return layoutBinary("UnaryExpr.", ast.O, ast.E); - } - - @Override -public Object visitVnameExpression(VnameExpression ast, Object obj) { - return layoutUnary("VnameExpr.", ast.V); - } - - // Declarations - @Override -public Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Object obj) { - return layoutQuaternary("Bin.Op.Decl.", ast.O, ast.ARG1, ast.ARG2, ast.RES); - } - - @Override -public Object visitConstDeclaration(ConstDeclaration ast, Object obj) { - return layoutBinary("ConstDecl.", ast.I, ast.E); - } - - @Override -public Object visitFuncDeclaration(FuncDeclaration ast, Object obj) { - return layoutQuaternary("FuncDecl.", ast.I, ast.FPS, ast.T, ast.E); - } - - @Override -public Object visitProcDeclaration(ProcDeclaration ast, Object obj) { - return layoutTernary("ProcDecl.", ast.I, ast.FPS, ast.C); - } - - @Override -public Object visitSequentialDeclaration(SequentialDeclaration ast, Object obj) { - return layoutBinary("Seq.Decl.", ast.D1, ast.D2); - } - - @Override -public Object visitTypeDeclaration(TypeDeclaration ast, Object obj) { - return layoutBinary("TypeDecl.", ast.I, ast.T); - } - - @Override -public Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Object obj) { - return layoutTernary("UnaryOp.Decl.", ast.O, ast.ARG, ast.RES); - } - - @Override -public Object visitVarDeclaration(VarDeclaration ast, Object obj) { - return layoutBinary("VarDecl.", ast.I, ast.T); - } - - // Array Aggregates - @Override -public Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, Object obj) { - return layoutBinary("Mult.ArrayAgg.", ast.E, ast.AA); - } - - @Override -public Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object obj) { - return layoutUnary("Sing.ArrayAgg.", ast.E); - } - - // Record Aggregates - @Override -public Object visitMultipleRecordAggregate(MultipleRecordAggregate ast, Object obj) { - return layoutTernary("Mult.Rec.Agg.", ast.I, ast.E, ast.RA); - } - - @Override -public Object visitSingleRecordAggregate(SingleRecordAggregate ast, Object obj) { - return layoutBinary("Sing.Rec.Agg.", ast.I, ast.E); - } - - // Formal Parameters - @Override -public Object visitConstFormalParameter(ConstFormalParameter ast, Object obj) { - return layoutBinary("ConstF.P.", ast.I, ast.T); - } - - @Override -public Object visitFuncFormalParameter(FuncFormalParameter ast, Object obj) { - return layoutTernary("FuncF.P.", ast.I, ast.FPS, ast.T); - } - - @Override -public Object visitProcFormalParameter(ProcFormalParameter ast, Object obj) { - return layoutBinary("ProcF.P.", ast.I, ast.FPS); - } - - @Override -public Object visitVarFormalParameter(VarFormalParameter ast, Object obj) { - return layoutBinary("VarF.P.", ast.I, ast.T); - } - - @Override -public Object visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Object obj) { - return layoutNullary("EmptyF.P.S."); - } - - @Override -public Object visitMultipleFormalParameterSequence(MultipleFormalParameterSequence ast, Object obj) { - return layoutBinary("Mult.F.P.S.", ast.FP, ast.FPS); - } - - @Override -public Object visitSingleFormalParameterSequence(SingleFormalParameterSequence ast, Object obj) { - return layoutUnary("Sing.F.P.S.", ast.FP); - } - - // Actual Parameters - @Override -public Object visitConstActualParameter(ConstActualParameter ast, Object obj) { - return layoutUnary("ConstA.P.", ast.E); - } - - @Override -public Object visitFuncActualParameter(FuncActualParameter ast, Object obj) { - return layoutUnary("FuncA.P.", ast.I); - } - - @Override -public Object visitProcActualParameter(ProcActualParameter ast, Object obj) { - return layoutUnary("ProcA.P.", ast.I); - } - - @Override -public Object visitVarActualParameter(VarActualParameter ast, Object obj) { - return layoutUnary("VarA.P.", ast.V); - } - - @Override -public Object visitEmptyActualParameterSequence(EmptyActualParameterSequence ast, Object obj) { - return layoutNullary("EmptyA.P.S."); - } - - @Override -public Object visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, Object obj) { - return layoutBinary("Mult.A.P.S.", ast.AP, ast.APS); - } - - @Override -public Object visitSingleActualParameterSequence(SingleActualParameterSequence ast, Object obj) { - return layoutUnary("Sing.A.P.S.", ast.AP); - } - - // Type Denoters - @Override -public Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object obj) { - return layoutNullary("any"); - } - - @Override -public Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object obj) { - return layoutBinary("ArrayTypeD.", ast.IL, ast.T); - } - - @Override -public Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object obj) { - return layoutNullary("bool"); - } - - @Override -public Object visitCharTypeDenoter(CharTypeDenoter ast, Object obj) { - return layoutNullary("char"); - } - - @Override -public Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object obj) { - return layoutNullary("error"); - } - - @Override -public Object visitSimpleTypeDenoter(SimpleTypeDenoter ast, Object obj) { - return layoutUnary("Sim.TypeD.", ast.I); - } - - @Override -public Object visitIntTypeDenoter(IntTypeDenoter ast, Object obj) { - return layoutNullary("int"); - } - - @Override -public Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object obj) { - return layoutUnary("Rec.TypeD.", ast.FT); - } - - @Override -public Object visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, Object obj) { - return layoutTernary("Mult.F.TypeD.", ast.I, ast.T, ast.FT); - } - - @Override -public Object visitSingleFieldTypeDenoter(SingleFieldTypeDenoter ast, Object obj) { - return layoutBinary("Sing.F.TypeD.", ast.I, ast.T); - } - - // Literals, Identifiers and Operators - @Override -public Object visitCharacterLiteral(CharacterLiteral ast, Object obj) { - return layoutNullary(ast.spelling); - } - - @Override -public Object visitIdentifier(Identifier ast, Object obj) { - return layoutNullary(ast.spelling); - } - - @Override -public Object visitIntegerLiteral(IntegerLiteral ast, Object obj) { - return layoutNullary(ast.spelling); - } - - @Override -public Object visitOperator(Operator ast, Object obj) { - return layoutNullary(ast.spelling); - } - - // Value-or-variable names - @Override -public Object visitDotVname(DotVname ast, Object obj) { - return layoutBinary("DotVname", ast.I, ast.V); - } - - @Override -public Object visitSimpleVname(SimpleVname ast, Object obj) { - return layoutUnary("Sim.Vname", ast.I); - } - - @Override -public Object visitSubscriptVname(SubscriptVname ast, Object obj) { - return layoutBinary("Sub.Vname", - ast.V, ast.E); - } - - // Programs - @Override -public Object visitProgram(Program ast, Object obj) { - return layoutUnary("Program", ast.C); - } - - private DrawingTree layoutCaption(String name) { - int w = fontMetrics.stringWidth(name) + 4; - int h = fontMetrics.getHeight() + 4; - return new DrawingTree(name, w, h); - } - - private DrawingTree layoutNullary(String name) { - DrawingTree dt = layoutCaption(name); - dt.contour.upper_tail = new Polyline(0, dt.height + 2 * BORDER, null); - dt.contour.upper_head = dt.contour.upper_tail; - dt.contour.lower_tail = new Polyline(-dt.width - 2 * BORDER, 0, null); - dt.contour.lower_head = new Polyline(0, dt.height + 2 * BORDER, dt.contour.lower_tail); - return dt; - } - - private DrawingTree layoutUnary(String name, AST child1) { - DrawingTree dt = layoutCaption(name); - DrawingTree d1 = (DrawingTree) child1.visit(this, null); - dt.setChildren(new DrawingTree[] { d1 }); - attachParent(dt, join(dt)); - return dt; - } - - private DrawingTree layoutBinary(String name, AST child1, AST child2) { - DrawingTree dt = layoutCaption(name); - DrawingTree d1 = (DrawingTree) child1.visit(this, null); - DrawingTree d2 = (DrawingTree) child2.visit(this, null); - dt.setChildren(new DrawingTree[] { d1, d2 }); - attachParent(dt, join(dt)); - return dt; - } - - private DrawingTree layoutTernary(String name, AST child1, AST child2, - AST child3) { - DrawingTree dt = layoutCaption(name); - DrawingTree d1 = (DrawingTree) child1.visit(this, null); - DrawingTree d2 = (DrawingTree) child2.visit(this, null); - DrawingTree d3 = (DrawingTree) child3.visit(this, null); - dt.setChildren(new DrawingTree[] { d1, d2, d3 }); - attachParent(dt, join(dt)); - return dt; - } - - private DrawingTree layoutQuaternary(String name, AST child1, AST child2, - AST child3, AST child4) { - DrawingTree dt = layoutCaption(name); - DrawingTree d1 = (DrawingTree) child1.visit(this, null); - DrawingTree d2 = (DrawingTree) child2.visit(this, null); - DrawingTree d3 = (DrawingTree) child3.visit(this, null); - DrawingTree d4 = (DrawingTree) child4.visit(this, null); - dt.setChildren(new DrawingTree[] { d1, d2, d3, d4 }); - attachParent(dt, join(dt)); - return dt; - } - - private void attachParent(DrawingTree dt, int w) { - int y = PARENT_SEP; - int x2 = (w - dt.width) / 2 - BORDER; - int x1 = x2 + dt.width + 2 * BORDER - w; - - dt.children[0].offset.y = y + dt.height; - dt.children[0].offset.x = x1; - dt.contour.upper_head = new Polyline(0, dt.height, - new Polyline(x1, y, dt.contour.upper_head)); - dt.contour.lower_head = new Polyline(0, dt.height, - new Polyline(x2, y, dt.contour.lower_head)); - } - - private int join(DrawingTree dt) { - int w, sum; - - dt.contour = dt.children[0].contour; - sum = w = dt.children[0].width + 2 * BORDER; - - for (int i = 1; i < dt.children.length; i++) { - int d = merge(dt.contour, dt.children[i].contour); - dt.children[i].offset.x = d + w; - dt.children[i].offset.y = 0; - w = dt.children[i].width + 2 * BORDER; - sum += d + w; - } - return sum; - } - - private int merge(Polygon c1, Polygon c2) { - int x, y, total, d; - Polyline lower, upper, b; - - x = y = total = 0; - upper = c1.lower_head; - lower = c2.upper_head; - - while (lower != null && upper != null) { - d = offset(x, y, lower.dx, lower.dy, upper.dx, upper.dy); - x += d; - total += d; - - if (y + lower.dy <= upper.dy) { - x += lower.dx; - y += lower.dy; - lower = lower.link; - } else { - x -= upper.dx; - y -= upper.dy; - upper = upper.link; - } - } - - if (lower != null) { - b = bridge(c1.upper_tail, 0, 0, lower, x, y); - c1.upper_tail = (b.link != null) ? c2.upper_tail : b; - c1.lower_tail = c2.lower_tail; - } else { - b = bridge(c2.lower_tail, x, y, upper, 0, 0); - if (b.link == null) { - c1.lower_tail = b; - } - } - - c1.lower_head = c2.lower_head; - - return total; - } - - private int offset(int p1, int p2, int a1, int a2, int b1, int b2) { - int d, s, t; - - if (b2 <= p2 || p2 + a2 <= 0) { - return 0; - } - - t = b2 * a1 - a2 * b1; - if (t > 0) { - if (p2 < 0) { - s = p2 * a1; - d = s / a2 - p1; - } else if (p2 > 0) { - s = p2 * b1; - d = s / b2 - p1; - } else { - d = -p1; - } - } else if (b2 < p2 + a2) { - s = (b2 - p2) * a1; - d = b1 - (p1 + s / a2); - } else if (b2 > p2 + a2) { - s = (a2 + p2) * b1; - d = s / b2 - (p1 + a1); - } else { - d = b1 - (p1 + a1); - } - - if (d > 0) { - return d; - } else { - return 0; - } - } - - private Polyline bridge(Polyline line1, int x1, int y1, - Polyline line2, int x2, int y2) { - int dy, dx, s; - Polyline r; - - dy = y2 + line2.dy - y1; - if (line2.dy == 0) { - dx = line2.dx; - } else { - s = dy * line2.dx; - dx = s / line2.dy; - } - - r = new Polyline(dx, dy, line2.link); - line1.link = new Polyline(x2 + line2.dx - dx - x1, 0, r); - - return r; - } + private final int BORDER = 5; + private final int PARENT_SEP = 30; + + private FontMetrics fontMetrics; + + public LayoutVisitor(FontMetrics fontMetrics) { + this.fontMetrics = fontMetrics; + } + + // Commands + @Override + public Object visitAssignCommand(AssignCommand ast, Object obj) { + return layoutBinary("AssignCom.", ast.V, ast.E); + } + + @Override + public Object visitCallCommand(CallCommand ast, Object obj) { + return layoutBinary("CallCom.", ast.I, ast.APS); + } + + @Override + public Object visitEmptyCommand(EmptyCommand ast, Object obj) { + return layoutNullary("EmptyCom."); + } + + @Override + public Object visitIfCommand(IfCommand ast, Object obj) { + return layoutTernary("IfCom.", ast.E, ast.C1, ast.C2); + } + + @Override + public Object visitLetCommand(LetCommand ast, Object obj) { + return layoutBinary("LetCom.", ast.D, ast.C); + } + + @Override + public Object visitSequentialCommand(SequentialCommand ast, Object obj) { + return layoutBinary("Seq.Com.", ast.C1, ast.C2); + } + + @Override + public Object visitWhileCommand(WhileCommand ast, Object obj) { + return layoutBinary("WhileCom.", ast.E, ast.C); + } + + // Expressions + @Override + public Object visitArrayExpression(ArrayExpression ast, Object obj) { + return layoutUnary("ArrayExpr.", ast.AA); + } + + @Override + public Object visitBinaryExpression(BinaryExpression ast, Object obj) { + return layoutTernary("Bin.Expr.", ast.E1, ast.O, ast.E2); + } + + @Override + public Object visitCallExpression(CallExpression ast, Object obj) { + return layoutBinary("CallExpr.", ast.I, ast.APS); + } + + @Override + public Object visitCharacterExpression(CharacterExpression ast, Object obj) { + return layoutUnary("Char.Expr.", ast.CL); + } + + @Override + public Object visitEmptyExpression(EmptyExpression ast, Object obj) { + return layoutNullary("EmptyExpr."); + } + + @Override + public Object visitIfExpression(IfExpression ast, Object obj) { + return layoutTernary("IfExpr.", ast.E1, ast.E2, ast.E3); + } + + @Override + public Object visitIntegerExpression(IntegerExpression ast, Object obj) { + return layoutUnary("Int.Expr.", ast.IL); + } + + @Override + public Object visitLetExpression(LetExpression ast, Object obj) { + return layoutBinary("LetExpr.", ast.D, ast.E); + } + + @Override + public Object visitRecordExpression(RecordExpression ast, Object obj) { + return layoutUnary("Rec.Expr.", ast.RA); + } + + @Override + public Object visitUnaryExpression(UnaryExpression ast, Object obj) { + return layoutBinary("UnaryExpr.", ast.O, ast.E); + } + + @Override + public Object visitVnameExpression(VnameExpression ast, Object obj) { + return layoutUnary("VnameExpr.", ast.V); + } + + // Declarations + @Override + public Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Object obj) { + return layoutQuaternary("Bin.Op.Decl.", ast.O, ast.ARG1, ast.ARG2, ast.RES); + } + + @Override + public Object visitConstDeclaration(ConstDeclaration ast, Object obj) { + return layoutBinary("ConstDecl.", ast.I, ast.E); + } + + @Override + public Object visitFuncDeclaration(FuncDeclaration ast, Object obj) { + return layoutQuaternary("FuncDecl.", ast.I, ast.FPS, ast.T, ast.E); + } + + @Override + public Object visitProcDeclaration(ProcDeclaration ast, Object obj) { + return layoutTernary("ProcDecl.", ast.I, ast.FPS, ast.C); + } + + @Override + public Object visitSequentialDeclaration(SequentialDeclaration ast, Object obj) { + return layoutBinary("Seq.Decl.", ast.D1, ast.D2); + } + + @Override + public Object visitTypeDeclaration(TypeDeclaration ast, Object obj) { + return layoutBinary("TypeDecl.", ast.I, ast.T); + } + + @Override + public Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Object obj) { + return layoutTernary("UnaryOp.Decl.", ast.O, ast.ARG, ast.RES); + } + + @Override + public Object visitVarDeclaration(VarDeclaration ast, Object obj) { + return layoutBinary("VarDecl.", ast.I, ast.T); + } + + // Array Aggregates + @Override + public Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, Object obj) { + return layoutBinary("Mult.ArrayAgg.", ast.E, ast.AA); + } + + @Override + public Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object obj) { + return layoutUnary("Sing.ArrayAgg.", ast.E); + } + + // Record Aggregates + @Override + public Object visitMultipleRecordAggregate(MultipleRecordAggregate ast, Object obj) { + return layoutTernary("Mult.Rec.Agg.", ast.I, ast.E, ast.RA); + } + + @Override + public Object visitSingleRecordAggregate(SingleRecordAggregate ast, Object obj) { + return layoutBinary("Sing.Rec.Agg.", ast.I, ast.E); + } + + // Formal Parameters + @Override + public Object visitConstFormalParameter(ConstFormalParameter ast, Object obj) { + return layoutBinary("ConstF.P.", ast.I, ast.T); + } + + @Override + public Object visitFuncFormalParameter(FuncFormalParameter ast, Object obj) { + return layoutTernary("FuncF.P.", ast.I, ast.FPS, ast.T); + } + + @Override + public Object visitProcFormalParameter(ProcFormalParameter ast, Object obj) { + return layoutBinary("ProcF.P.", ast.I, ast.FPS); + } + + @Override + public Object visitVarFormalParameter(VarFormalParameter ast, Object obj) { + return layoutBinary("VarF.P.", ast.I, ast.T); + } + + @Override + public Object visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Object obj) { + return layoutNullary("EmptyF.P.S."); + } + + @Override + public Object visitMultipleFormalParameterSequence(MultipleFormalParameterSequence ast, Object obj) { + return layoutBinary("Mult.F.P.S.", ast.FP, ast.FPS); + } + + @Override + public Object visitSingleFormalParameterSequence(SingleFormalParameterSequence ast, Object obj) { + return layoutUnary("Sing.F.P.S.", ast.FP); + } + + // Actual Parameters + @Override + public Object visitConstActualParameter(ConstActualParameter ast, Object obj) { + return layoutUnary("ConstA.P.", ast.E); + } + + @Override + public Object visitFuncActualParameter(FuncActualParameter ast, Object obj) { + return layoutUnary("FuncA.P.", ast.I); + } + + @Override + public Object visitProcActualParameter(ProcActualParameter ast, Object obj) { + return layoutUnary("ProcA.P.", ast.I); + } + + @Override + public Object visitVarActualParameter(VarActualParameter ast, Object obj) { + return layoutUnary("VarA.P.", ast.V); + } + + @Override + public Object visitEmptyActualParameterSequence(EmptyActualParameterSequence ast, Object obj) { + return layoutNullary("EmptyA.P.S."); + } + + @Override + public Object visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, Object obj) { + return layoutBinary("Mult.A.P.S.", ast.AP, ast.APS); + } + + @Override + public Object visitSingleActualParameterSequence(SingleActualParameterSequence ast, Object obj) { + return layoutUnary("Sing.A.P.S.", ast.AP); + } + + // Type Denoters + @Override + public Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object obj) { + return layoutNullary("any"); + } + + @Override + public Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object obj) { + return layoutBinary("ArrayTypeD.", ast.IL, ast.T); + } + + @Override + public Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object obj) { + return layoutNullary("bool"); + } + + @Override + public Object visitCharTypeDenoter(CharTypeDenoter ast, Object obj) { + return layoutNullary("char"); + } + + @Override + public Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object obj) { + return layoutNullary("error"); + } + + @Override + public Object visitSimpleTypeDenoter(SimpleTypeDenoter ast, Object obj) { + return layoutUnary("Sim.TypeD.", ast.I); + } + + @Override + public Object visitIntTypeDenoter(IntTypeDenoter ast, Object obj) { + return layoutNullary("int"); + } + + @Override + public Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object obj) { + return layoutUnary("Rec.TypeD.", ast.FT); + } + + @Override + public Object visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, Object obj) { + return layoutTernary("Mult.F.TypeD.", ast.I, ast.T, ast.FT); + } + + @Override + public Object visitSingleFieldTypeDenoter(SingleFieldTypeDenoter ast, Object obj) { + return layoutBinary("Sing.F.TypeD.", ast.I, ast.T); + } + + // Literals, Identifiers and Operators + @Override + public Object visitCharacterLiteral(CharacterLiteral ast, Object obj) { + return layoutNullary(ast.spelling); + } + + @Override + public Object visitIdentifier(Identifier ast, Object obj) { + return layoutNullary(ast.spelling); + } + + @Override + public Object visitIntegerLiteral(IntegerLiteral ast, Object obj) { + return layoutNullary(ast.spelling); + } + + @Override + public Object visitOperator(Operator ast, Object obj) { + return layoutNullary(ast.spelling); + } + + // Value-or-variable names + @Override + public Object visitDotVname(DotVname ast, Object obj) { + return layoutBinary("DotVname", ast.I, ast.V); + } + + @Override + public Object visitSimpleVname(SimpleVname ast, Object obj) { + return layoutUnary("Sim.Vname", ast.I); + } + + @Override + public Object visitSubscriptVname(SubscriptVname ast, Object obj) { + return layoutBinary("Sub.Vname", ast.V, ast.E); + } + + // Programs + @Override + public Object visitProgram(Program ast, Object obj) { + return layoutUnary("Program", ast.C); + } + + private DrawingTree layoutCaption(String name) { + int w = fontMetrics.stringWidth(name) + 4; + int h = fontMetrics.getHeight() + 4; + return new DrawingTree(name, w, h); + } + + private DrawingTree layoutNullary(String name) { + DrawingTree dt = layoutCaption(name); + dt.contour.upper_tail = new Polyline(0, dt.height + 2 * BORDER, null); + dt.contour.upper_head = dt.contour.upper_tail; + dt.contour.lower_tail = new Polyline(-dt.width - 2 * BORDER, 0, null); + dt.contour.lower_head = new Polyline(0, dt.height + 2 * BORDER, dt.contour.lower_tail); + return dt; + } + + private DrawingTree layoutUnary(String name, AST child1) { + DrawingTree dt = layoutCaption(name); + DrawingTree d1 = (DrawingTree) child1.visit(this, null); + dt.setChildren(new DrawingTree[] { d1 }); + attachParent(dt, join(dt)); + return dt; + } + + private DrawingTree layoutBinary(String name, AST child1, AST child2) { + DrawingTree dt = layoutCaption(name); + DrawingTree d1 = (DrawingTree) child1.visit(this, null); + DrawingTree d2 = (DrawingTree) child2.visit(this, null); + dt.setChildren(new DrawingTree[] { d1, d2 }); + attachParent(dt, join(dt)); + return dt; + } + + private DrawingTree layoutTernary(String name, AST child1, AST child2, AST child3) { + DrawingTree dt = layoutCaption(name); + DrawingTree d1 = (DrawingTree) child1.visit(this, null); + DrawingTree d2 = (DrawingTree) child2.visit(this, null); + DrawingTree d3 = (DrawingTree) child3.visit(this, null); + dt.setChildren(new DrawingTree[] { d1, d2, d3 }); + attachParent(dt, join(dt)); + return dt; + } + + private DrawingTree layoutQuaternary(String name, AST child1, AST child2, AST child3, AST child4) { + DrawingTree dt = layoutCaption(name); + DrawingTree d1 = (DrawingTree) child1.visit(this, null); + DrawingTree d2 = (DrawingTree) child2.visit(this, null); + DrawingTree d3 = (DrawingTree) child3.visit(this, null); + DrawingTree d4 = (DrawingTree) child4.visit(this, null); + dt.setChildren(new DrawingTree[] { d1, d2, d3, d4 }); + attachParent(dt, join(dt)); + return dt; + } + + private void attachParent(DrawingTree dt, int w) { + int y = PARENT_SEP; + int x2 = (w - dt.width) / 2 - BORDER; + int x1 = x2 + dt.width + 2 * BORDER - w; + + dt.children[0].offset.y = y + dt.height; + dt.children[0].offset.x = x1; + dt.contour.upper_head = new Polyline(0, dt.height, new Polyline(x1, y, dt.contour.upper_head)); + dt.contour.lower_head = new Polyline(0, dt.height, new Polyline(x2, y, dt.contour.lower_head)); + } + + private int join(DrawingTree dt) { + int w, sum; + + dt.contour = dt.children[0].contour; + sum = w = dt.children[0].width + 2 * BORDER; + + for (int i = 1; i < dt.children.length; i++) { + int d = merge(dt.contour, dt.children[i].contour); + dt.children[i].offset.x = d + w; + dt.children[i].offset.y = 0; + w = dt.children[i].width + 2 * BORDER; + sum += d + w; + } + return sum; + } + + private int merge(Polygon c1, Polygon c2) { + int x, y, total, d; + Polyline lower, upper, b; + + x = y = total = 0; + upper = c1.lower_head; + lower = c2.upper_head; + + while (lower != null && upper != null) { + d = offset(x, y, lower.dx, lower.dy, upper.dx, upper.dy); + x += d; + total += d; + + if (y + lower.dy <= upper.dy) { + x += lower.dx; + y += lower.dy; + lower = lower.link; + } else { + x -= upper.dx; + y -= upper.dy; + upper = upper.link; + } + } + + if (lower != null) { + b = bridge(c1.upper_tail, 0, 0, lower, x, y); + c1.upper_tail = (b.link != null) ? c2.upper_tail : b; + c1.lower_tail = c2.lower_tail; + } else { + b = bridge(c2.lower_tail, x, y, upper, 0, 0); + if (b.link == null) { + c1.lower_tail = b; + } + } + + c1.lower_head = c2.lower_head; + + return total; + } + + private int offset(int p1, int p2, int a1, int a2, int b1, int b2) { + int d, s, t; + + if (b2 <= p2 || p2 + a2 <= 0) { + return 0; + } + + t = b2 * a1 - a2 * b1; + if (t > 0) { + if (p2 < 0) { + s = p2 * a1; + d = s / a2 - p1; + } else if (p2 > 0) { + s = p2 * b1; + d = s / b2 - p1; + } else { + d = -p1; + } + } else if (b2 < p2 + a2) { + s = (b2 - p2) * a1; + d = b1 - (p1 + s / a2); + } else if (b2 > p2 + a2) { + s = (a2 + p2) * b1; + d = s / b2 - (p1 + a1); + } else { + d = b1 - (p1 + a1); + } + + if (d > 0) { + return d; + } else { + return 0; + } + } + + private Polyline bridge(Polyline line1, int x1, int y1, Polyline line2, int x2, int y2) { + int dy, dx, s; + Polyline r; + + dy = y2 + line2.dy - y1; + if (line2.dy == 0) { + dx = line2.dx; + } else { + s = dy * line2.dx; + dx = s / line2.dy; + } + + r = new Polyline(dx, dy, line2.link); + line1.link = new Polyline(x2 + line2.dx - dx - x1, 0, r); + + return r; + } } \ No newline at end of file diff --git a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Polygon.java b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Polygon.java index 37f93f4..392ad8b 100644 --- a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Polygon.java +++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Polygon.java @@ -15,6 +15,6 @@ package Triangle.TreeDrawer; class Polygon { - Polyline lower_head, lower_tail; - Polyline upper_head, upper_tail; + Polyline lower_head, lower_tail; + Polyline upper_head, upper_tail; } \ No newline at end of file diff --git a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Polyline.java b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Polyline.java index e82aeee..74ce46c 100644 --- a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Polyline.java +++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Polyline.java @@ -15,12 +15,12 @@ package Triangle.TreeDrawer; class Polyline { - int dx, dy; - Polyline link; + int dx, dy; + Polyline link; - Polyline(int dx, int dy, Polyline link) { - this.dx = dx; - this.dy = dy; - this.link = link; - } + Polyline(int dx, int dy, Polyline link) { + this.dx = dx; + this.dy = dy; + this.link = link; + } }