diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..c4abd8b
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,18 @@
+{
+ "cSpell.words": [
+ "actuals",
+ "Analyser",
+ "Denoter",
+ "DENOTERS",
+ "Deryck",
+ "geteol",
+ "getint",
+ "maxint",
+ "notgreater",
+ "notless",
+ "puteol",
+ "putint",
+ "Vname"
+ ],
+ "java.configuration.updateBuildConfiguration": "automatic"
+}
\ No newline at end of file
diff --git a/Triangle.AbstractMachine.Disassembler/pom.xml b/Triangle.AbstractMachine.Disassembler/pom.xml
new file mode 100644
index 0000000..0b94ffb
--- /dev/null
+++ b/Triangle.AbstractMachine.Disassembler/pom.xml
@@ -0,0 +1,20 @@
+
+ 4.0.0
+ triangle.tools
+ triangle-disassembler
+ 2.1
+
+ triangle.tools
+ triangle-tools
+ 2.1
+ ../
+
+
+
+ triangle.tools
+ triangle-abstractmachine
+ 2.1
+
+
+
diff --git a/Triangle.AbstractMachine.Disassembler/src/main/java/Triangle/AbstractMachine/Disassembler.java b/Triangle.AbstractMachine.Disassembler/src/main/java/Triangle/AbstractMachine/Disassembler.java
new file mode 100644
index 0000000..8bda415
--- /dev/null
+++ b/Triangle.AbstractMachine.Disassembler/src/main/java/Triangle/AbstractMachine/Disassembler.java
@@ -0,0 +1,398 @@
+/*
+ * @(#)Disassembler.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractMachine;
+
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+/**
+ * Disassembles the TAM code in the given file, and displays the
+ * instructions on standard output.
+ *
+ * For example:
+ *
+ *
+ * java TAM.Disassembler obj.tam
+ *
+ *
+ *
+ * Copyright 1991 David A. Watt, University of Glasgow
+ * Copyright 1998 Deryck F. Brown, The Robert Gordon University
+ *
+ *
+ */
+
+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();
+ }
+}
diff --git a/Triangle.AbstractMachine.Interpreter/pom.xml b/Triangle.AbstractMachine.Interpreter/pom.xml
new file mode 100644
index 0000000..70dc42c
--- /dev/null
+++ b/Triangle.AbstractMachine.Interpreter/pom.xml
@@ -0,0 +1,20 @@
+
+ 4.0.0
+ triangle.tools
+ triangle-interpreter
+ 2.1
+
+ triangle.tools
+ triangle-tools
+ 2.1
+ ../
+
+
+
+ triangle.tools
+ triangle-abstractmachine
+ 2.1
+
+
+
diff --git a/Triangle.AbstractMachine.Interpreter/src/main/java/Triangle/AbstractMachine/Interpreter.java b/Triangle.AbstractMachine.Interpreter/src/main/java/Triangle/AbstractMachine/Interpreter.java
new file mode 100644
index 0000000..1adbb4c
--- /dev/null
+++ b/Triangle.AbstractMachine.Interpreter/src/main/java/Triangle/AbstractMachine/Interpreter.java
@@ -0,0 +1,620 @@
+/*
+ * @(#)Interpreter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractMachine;
+
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+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] = (int) 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/pom.xml b/Triangle.AbstractMachine/pom.xml
new file mode 100644
index 0000000..c2d2726
--- /dev/null
+++ b/Triangle.AbstractMachine/pom.xml
@@ -0,0 +1,14 @@
+
+ 4.0.0
+ triangle.tools
+ triangle-abstractmachine
+ 2.1
+ jar
+
+ triangle.tools
+ triangle-tools
+ 2.1
+ ../
+
+
\ No newline at end of file
diff --git a/Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Instruction.java b/Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Instruction.java
new file mode 100644
index 0000000..785583a
--- /dev/null
+++ b/Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Instruction.java
@@ -0,0 +1,64 @@
+/*
+ * @(#)Instruction.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractMachine;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+
+public class Instruction {
+
+ 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}
+
+ // 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 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
new file mode 100644
index 0000000..65e13a3
--- /dev/null
+++ b/Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Machine.java
@@ -0,0 +1,125 @@
+/*
+ * @(#)Machine.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+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;
+
+}
diff --git a/Triangle.AbstractMachine/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/Triangle.AbstractMachine/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..4de6135
--- /dev/null
+++ b/Triangle.AbstractMachine/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,2 @@
+c:\Java\Repos\Triangle-Tools\Triangle.AbstractMachine\src\main\java\Triangle\AbstractMachine\Machine.java
+c:\Java\Repos\Triangle-Tools\Triangle.AbstractMachine\src\main\java\Triangle\AbstractMachine\Instruction.java
diff --git a/Triangle.Compiler/.editorconfig b/Triangle.Compiler/.editorconfig
new file mode 100644
index 0000000..1f494b0
--- /dev/null
+++ b/Triangle.Compiler/.editorconfig
@@ -0,0 +1,17 @@
+# Editor configuration, see http://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+insert_final_newline = true
+trim_trailing_whitespace = true
+max_line_length = 80
+
+[*.sh]
+end_of_line = lf
+
+[*.java]
+indent_size = 4
+max_line_length = 120
diff --git a/Triangle.Compiler/pom.xml b/Triangle.Compiler/pom.xml
new file mode 100644
index 0000000..c0828ab
--- /dev/null
+++ b/Triangle.Compiler/pom.xml
@@ -0,0 +1,20 @@
+
+ 4.0.0
+ triangle.tools
+ triangle-compiler
+ 2.1
+
+ triangle.tools
+ triangle-tools
+ 2.1
+ ../
+
+
+
+ triangle.tools
+ triangle-abstractmachine
+ 2.1
+
+
+
diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AST.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AST.java
new file mode 100644
index 0000000..6f3857c
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AST.java
@@ -0,0 +1,35 @@
+/*
+ * @(#)AST.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.CodeGenerator.RuntimeEntity;
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public abstract class AST {
+
+ public AST(SourcePosition thePosition) {
+ position = thePosition;
+ entity = null;
+ }
+
+ public SourcePosition getPosition() {
+ return position;
+ }
+
+ public abstract Object visit(Visitor v, Object o);
+
+ 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
new file mode 100644
index 0000000..34cae48
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ActualParameter.java
@@ -0,0 +1,24 @@
+/*
+ * @(#)ActualParameter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public abstract class ActualParameter extends AST {
+
+ 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
new file mode 100644
index 0000000..d99a36d
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ActualParameterSequence.java
@@ -0,0 +1,24 @@
+/*
+ * @(#)ActualParameterSequence.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public abstract class ActualParameterSequence extends AST {
+
+ 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
new file mode 100644
index 0000000..72d719a
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AnyTypeDenoter.java
@@ -0,0 +1,32 @@
+/*
+ * @(#)AnyTypeDenoter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class AnyTypeDenoter extends TypeDenoter {
+
+ public AnyTypeDenoter(SourcePosition thePosition) {
+ super(thePosition);
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitAnyTypeDenoter(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..811a35a
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayAggregate.java
@@ -0,0 +1,27 @@
+/*
+ * @(#)ArrayAggregate.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public abstract class ArrayAggregate extends AST {
+
+ public ArrayAggregate(SourcePosition thePosition) {
+ super(thePosition);
+ elemCount = 0;
+ }
+
+ 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
new file mode 100644
index 0000000..f2412dc
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayExpression.java
@@ -0,0 +1,32 @@
+/*
+ * @(#)ArrayExpression.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class ArrayExpression extends Expression {
+
+ public ArrayExpression(ArrayAggregate aaAST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ AA = aaAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitArrayExpression(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..5d08f5a
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayTypeDenoter.java
@@ -0,0 +1,44 @@
+/*
+ * @(#)ArrayTypeDenoter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class ArrayTypeDenoter extends TypeDenoter {
+
+ public ArrayTypeDenoter(IntegerLiteral ilAST, TypeDenoter tAST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ IL = ilAST;
+ T = tAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitArrayTypeDenoter(this, o);
+ }
+
+ 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;
+}
diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AssignCommand.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AssignCommand.java
new file mode 100644
index 0000000..cf5ebe6
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AssignCommand.java
@@ -0,0 +1,33 @@
+/*
+ * @(#)AssignCommand.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class AssignCommand extends Command {
+
+ public AssignCommand(Vname vAST, Expression eAST, SourcePosition thePosition) {
+ super(thePosition);
+ V = vAST;
+ E = eAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitAssignCommand(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..bd39acc
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BinaryExpression.java
@@ -0,0 +1,35 @@
+/*
+ * @(#)BinaryExpression.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+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 Object visit(Visitor v, Object o) {
+ return v.visitBinaryExpression(this, 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
new file mode 100644
index 0000000..9f1dcbd
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BinaryOperatorDeclaration.java
@@ -0,0 +1,37 @@
+/*
+ * @(#)BinaryOperatorDeclaration.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+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 Object visit(Visitor v, Object o) {
+ return v.visitBinaryOperatorDeclaration(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..2bb7846
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BoolTypeDenoter.java
@@ -0,0 +1,35 @@
+/*
+ * @(#)BoolTypeDenoter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class BoolTypeDenoter extends TypeDenoter {
+
+ public BoolTypeDenoter(SourcePosition thePosition) {
+ super(thePosition);
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitBoolTypeDenoter(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..d0131d1
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CallCommand.java
@@ -0,0 +1,34 @@
+/*
+ * @(#)CallCommand.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class CallCommand extends Command {
+
+ public CallCommand(Identifier iAST, ActualParameterSequence apsAST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ I = iAST;
+ APS = apsAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitCallCommand(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..03d144c
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CallExpression.java
@@ -0,0 +1,34 @@
+/*
+ * @(#)CallExpression.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class CallExpression extends Expression {
+
+ public CallExpression(Identifier iAST, ActualParameterSequence apsAST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ I = iAST;
+ APS = apsAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitCallExpression(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..147f68a
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharTypeDenoter.java
@@ -0,0 +1,35 @@
+/*
+ * @(#)CharTypeDenoter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class CharTypeDenoter extends TypeDenoter {
+
+ public CharTypeDenoter(SourcePosition thePosition) {
+ super(thePosition);
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitCharTypeDenoter(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..af34f81
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharacterExpression.java
@@ -0,0 +1,31 @@
+/*
+ * @(#)CharacterExpression.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class CharacterExpression extends Expression {
+
+ public CharacterExpression(CharacterLiteral clAST, SourcePosition thePosition) {
+ super(thePosition);
+ CL = clAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitCharacterExpression(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..f586479
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharacterLiteral.java
@@ -0,0 +1,29 @@
+/*
+ * @(#)CharacterLiteral.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class CharacterLiteral extends Terminal {
+
+ public CharacterLiteral(String theSpelling, SourcePosition thePosition) {
+ super(theSpelling, thePosition);
+ }
+
+ 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
new file mode 100644
index 0000000..69acee0
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Command.java
@@ -0,0 +1,24 @@
+/*
+ * @(#)Command.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public abstract class Command extends AST {
+
+ 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
new file mode 100644
index 0000000..35d7f62
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstActualParameter.java
@@ -0,0 +1,31 @@
+/*
+ * @(#)ConstActualParameter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class ConstActualParameter extends ActualParameter {
+
+ public ConstActualParameter(Expression eAST, SourcePosition thePosition) {
+ super(thePosition);
+ E = eAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitConstActualParameter(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..0081d10
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstDeclaration.java
@@ -0,0 +1,34 @@
+/*
+ * @(#)ConstDeclaration.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class ConstDeclaration extends Declaration {
+
+ public ConstDeclaration(Identifier iAST, Expression eAST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ I = iAST;
+ E = eAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitConstDeclaration(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..ea3e170
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstFormalParameter.java
@@ -0,0 +1,42 @@
+/*
+ * @(#)ConstFormalParameter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class ConstFormalParameter extends FormalParameter {
+
+ public ConstFormalParameter(Identifier iAST, TypeDenoter tAST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ I = iAST;
+ T = tAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitConstFormalParameter(this, o);
+ }
+
+ public Identifier I;
+ public TypeDenoter T;
+
+ 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
new file mode 100644
index 0000000..586293b
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Declaration.java
@@ -0,0 +1,27 @@
+/*
+ * @(#)Declaration.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public abstract class Declaration extends AST {
+
+ public Declaration(SourcePosition thePosition) {
+ super(thePosition);
+ duplicated = false;
+ }
+
+ 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
new file mode 100644
index 0000000..26456b8
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/DotVname.java
@@ -0,0 +1,33 @@
+/*
+ * @(#)DotVname.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class DotVname extends Vname {
+
+ public DotVname(Vname vAST, Identifier iAST, SourcePosition thePosition) {
+ super(thePosition);
+ V = vAST;
+ I = iAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitDotVname(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..3a0370d
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyActualParameterSequence.java
@@ -0,0 +1,28 @@
+/*
+ * @(#)EmptyActualParameterSequence.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class EmptyActualParameterSequence extends ActualParameterSequence {
+
+ public EmptyActualParameterSequence(SourcePosition thePosition) {
+ super(thePosition);
+ }
+
+ 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
new file mode 100644
index 0000000..2dd7249
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyCommand.java
@@ -0,0 +1,28 @@
+/*
+ * @(#)EmptyCommand.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class EmptyCommand extends Command {
+
+ public EmptyCommand(SourcePosition thePosition) {
+ super(thePosition);
+ }
+
+ 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
new file mode 100644
index 0000000..169c89c
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyExpression.java
@@ -0,0 +1,28 @@
+/*
+ * @(#)EmptyExpression.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class EmptyExpression extends Expression {
+
+ public EmptyExpression(SourcePosition thePosition) {
+ super(thePosition);
+ }
+
+ 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
new file mode 100644
index 0000000..74581ec
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyFormalParameterSequence.java
@@ -0,0 +1,32 @@
+/*
+ * @(#)EmptyFormalParameterSequence.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class EmptyFormalParameterSequence extends FormalParameterSequence {
+
+ public EmptyFormalParameterSequence(SourcePosition thePosition) {
+ super(thePosition);
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitEmptyFormalParameterSequence(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..5171dc9
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ErrorTypeDenoter.java
@@ -0,0 +1,32 @@
+/*
+ * @(#)ErrorTypeDenoter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class ErrorTypeDenoter extends TypeDenoter {
+
+ public ErrorTypeDenoter(SourcePosition thePosition) {
+ super(thePosition);
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitErrorTypeDenoter(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..682d314
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Expression.java
@@ -0,0 +1,27 @@
+/*
+ * @(#)Expression.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public abstract class Expression extends AST {
+
+ public Expression(SourcePosition thePosition) {
+ super(thePosition);
+ type = null;
+ }
+
+ 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
new file mode 100644
index 0000000..d618d08
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FieldTypeDenoter.java
@@ -0,0 +1,26 @@
+/*
+ * @(#)FieldTypeDenoter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public abstract class FieldTypeDenoter extends TypeDenoter {
+
+ public FieldTypeDenoter(SourcePosition thePosition) {
+ super(thePosition);
+ }
+
+ 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
new file mode 100644
index 0000000..c3b8505
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FormalParameter.java
@@ -0,0 +1,27 @@
+/*
+ * @(#)FormalParameter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public abstract class FormalParameter extends Declaration {
+
+ public FormalParameter(SourcePosition thePosition) {
+ super(thePosition);
+ }
+
+ 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
new file mode 100644
index 0000000..b6abc62
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FormalParameterSequence.java
@@ -0,0 +1,26 @@
+/*
+ * @(#)FormalParameterSequence.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public abstract class FormalParameterSequence extends AST {
+
+ public FormalParameterSequence(SourcePosition thePosition) {
+ super(thePosition);
+ }
+
+ 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
new file mode 100644
index 0000000..6f9360c
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncActualParameter.java
@@ -0,0 +1,31 @@
+/*
+ * @(#)FuncActualParameter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class FuncActualParameter extends ActualParameter {
+
+ public FuncActualParameter(Identifier iAST, SourcePosition thePosition) {
+ super(thePosition);
+ I = iAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitFuncActualParameter(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..bf7de92
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncDeclaration.java
@@ -0,0 +1,39 @@
+/*
+ * @(#)FuncDeclaration.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+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 Object visit(Visitor v, Object o) {
+ return v.visitFuncDeclaration(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..fe101bd
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncFormalParameter.java
@@ -0,0 +1,44 @@
+/*
+ * @(#)FuncFormalParameter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+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 Object visit(Visitor v, Object o) {
+ return v.visitFuncFormalParameter(this, o);
+ }
+
+ 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;
+}
diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Identifier.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Identifier.java
new file mode 100644
index 0000000..a24ced6
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Identifier.java
@@ -0,0 +1,33 @@
+/*
+ * @(#)Identifier.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class Identifier extends Terminal {
+
+ public Identifier(String theSpelling, SourcePosition thePosition) {
+ super(theSpelling, thePosition);
+ type = null;
+ decl = null;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitIdentifier(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..438c224
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IfCommand.java
@@ -0,0 +1,35 @@
+/*
+ * @(#)IfCommand.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+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 Object visit(Visitor v, Object o) {
+ return v.visitIfCommand(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..5714ad9
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IfExpression.java
@@ -0,0 +1,34 @@
+/*
+ * @(#)IfExpression.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+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 Object visit(Visitor v, Object o) {
+ return v.visitIfExpression(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..cf40f6a
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntTypeDenoter.java
@@ -0,0 +1,35 @@
+/*
+ * @(#)IntTypeDenoter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class IntTypeDenoter extends TypeDenoter {
+
+ public IntTypeDenoter(SourcePosition thePosition) {
+ super(thePosition);
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitIntTypeDenoter(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..8d2e1e8
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntegerExpression.java
@@ -0,0 +1,31 @@
+/*
+ * @(#)IntegerExpression.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class IntegerExpression extends Expression {
+
+ public IntegerExpression(IntegerLiteral ilAST, SourcePosition thePosition) {
+ super(thePosition);
+ IL = ilAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitIntegerExpression(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..0565b16
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntegerLiteral.java
@@ -0,0 +1,29 @@
+/*
+ * @(#)IntegerLiteral.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class IntegerLiteral extends Terminal {
+
+ public IntegerLiteral(String theSpelling, SourcePosition thePosition) {
+ super(theSpelling, thePosition);
+ }
+
+ 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
new file mode 100644
index 0000000..126a9f4
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/LetCommand.java
@@ -0,0 +1,33 @@
+/*
+ * @(#)LetCommand.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class LetCommand extends Command {
+
+ public LetCommand(Declaration dAST, Command cAST, SourcePosition thePosition) {
+ super(thePosition);
+ D = dAST;
+ C = cAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitLetCommand(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..e954f28
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/LetExpression.java
@@ -0,0 +1,33 @@
+/*
+ * @(#)LetExpression.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class LetExpression extends Expression {
+
+ public LetExpression(Declaration dAST, Expression eAST, SourcePosition thePosition) {
+ super(thePosition);
+ D = dAST;
+ E = eAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitLetExpression(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..949fa55
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleActualParameterSequence.java
@@ -0,0 +1,34 @@
+/*
+ * @(#)MultipleActualParameterSequence.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class MultipleActualParameterSequence extends ActualParameterSequence {
+
+ public MultipleActualParameterSequence(ActualParameter apAST, ActualParameterSequence apsAST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ AP = apAST;
+ APS = apsAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitMultipleActualParameterSequence(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..6a3fede
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleArrayAggregate.java
@@ -0,0 +1,34 @@
+/*
+ * @(#)MultipleArrayAggregate.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class MultipleArrayAggregate extends ArrayAggregate {
+
+ public MultipleArrayAggregate(Expression eAST, ArrayAggregate aaAST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ E = eAST;
+ AA = aaAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitMultipleArrayAggregate(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..71a077f
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFieldTypeDenoter.java
@@ -0,0 +1,46 @@
+/*
+ * @(#)MultipleFieldTypeDenoter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+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 Object visit(Visitor v, Object o) {
+ return v.visitMultipleFieldTypeDenoter(this, o);
+ }
+
+ 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;
+}
diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFormalParameterSequence.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFormalParameterSequence.java
new file mode 100644
index 0000000..ced0581
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFormalParameterSequence.java
@@ -0,0 +1,42 @@
+/*
+ * @(#)MultipleFormalParameterSequence.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class MultipleFormalParameterSequence extends FormalParameterSequence {
+
+ public MultipleFormalParameterSequence(FormalParameter fpAST, FormalParameterSequence fpsAST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ FP = fpAST;
+ FPS = fpsAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitMultipleFormalParameterSequence(this, o);
+ }
+
+ 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;
+}
diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleRecordAggregate.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleRecordAggregate.java
new file mode 100644
index 0000000..0e7c3d5
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleRecordAggregate.java
@@ -0,0 +1,36 @@
+/*
+ * @(#)MultipleRecordAggregate.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+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 Object visit(Visitor v, Object o) {
+ return v.visitMultipleRecordAggregate(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..5fb379a
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Operator.java
@@ -0,0 +1,31 @@
+/*
+ * @(#)Operator.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class Operator extends Terminal {
+
+ public Operator(String theSpelling, SourcePosition thePosition) {
+ super(theSpelling, thePosition);
+ decl = null;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitOperator(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..9b926dc
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcActualParameter.java
@@ -0,0 +1,31 @@
+/*
+ * @(#)ProcActualParameter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class ProcActualParameter extends ActualParameter {
+
+ public ProcActualParameter(Identifier iAST, SourcePosition thePosition) {
+ super(thePosition);
+ I = iAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitProcActualParameter(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..1fc4223
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcDeclaration.java
@@ -0,0 +1,36 @@
+/*
+ * @(#)ProcDeclaration.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+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 Object visit(Visitor v, Object o) {
+ return v.visitProcDeclaration(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..d6a6bc8
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcFormalParameter.java
@@ -0,0 +1,42 @@
+/*
+ * @(#)ProcFormalParameter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class ProcFormalParameter extends FormalParameter {
+
+ public ProcFormalParameter(Identifier iAST, FormalParameterSequence fpsAST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ I = iAST;
+ FPS = fpsAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitProcFormalParameter(this, o);
+ }
+
+ public Identifier I;
+ public FormalParameterSequence FPS;
+
+ 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
new file mode 100644
index 0000000..b2a513a
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Program.java
@@ -0,0 +1,31 @@
+/*
+ * @(#)Program.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class Program extends AST {
+
+ public Program(Command cAST, SourcePosition thePosition) {
+ super(thePosition);
+ C = cAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitProgram(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..9f2d923
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordAggregate.java
@@ -0,0 +1,27 @@
+/*
+ * @(#)RecordAggregate.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public abstract class RecordAggregate extends AST {
+
+ public RecordAggregate(SourcePosition thePosition) {
+ super(thePosition);
+ type = null;
+ }
+
+ 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
new file mode 100644
index 0000000..c96ad96
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordExpression.java
@@ -0,0 +1,31 @@
+/*
+ * @(#)RecordExpression.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class RecordExpression extends Expression {
+
+ public RecordExpression(RecordAggregate raAST, SourcePosition thePosition) {
+ super(thePosition);
+ RA = raAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitRecordExpression(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..979c90d
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordTypeDenoter.java
@@ -0,0 +1,40 @@
+/*
+ * @(#)RecordTypeDenoter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class RecordTypeDenoter extends TypeDenoter {
+
+ public RecordTypeDenoter(FieldTypeDenoter ftAST, SourcePosition thePosition) {
+ super(thePosition);
+ FT = ftAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitRecordTypeDenoter(this, o);
+ }
+
+ 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;
+}
diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialCommand.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialCommand.java
new file mode 100644
index 0000000..37a8a7a
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialCommand.java
@@ -0,0 +1,32 @@
+/*
+ * @(#)SequentialCommand.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class SequentialCommand extends Command {
+
+ public SequentialCommand(Command c1AST, Command c2AST, SourcePosition thePosition) {
+ super(thePosition);
+ C1 = c1AST;
+ C2 = c2AST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitSequentialCommand(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..e899258
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialDeclaration.java
@@ -0,0 +1,33 @@
+/*
+ * @(#)SequentialDeclaration.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class SequentialDeclaration extends Declaration {
+
+ public SequentialDeclaration(Declaration d1AST, Declaration d2AST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ D1 = d1AST;
+ D2 = d2AST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitSequentialDeclaration(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..d540f14
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SimpleTypeDenoter.java
@@ -0,0 +1,35 @@
+/*
+ * @(#)SimpleTypeDenoter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class SimpleTypeDenoter extends TypeDenoter {
+
+ public SimpleTypeDenoter(Identifier iAST, SourcePosition thePosition) {
+ super(thePosition);
+ I = iAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitSimpleTypeDenoter(this, o);
+ }
+
+ public boolean equals(Object obj) {
+ return false; // should not happen
+ }
+
+ 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
new file mode 100644
index 0000000..94734e4
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SimpleVname.java
@@ -0,0 +1,31 @@
+/*
+ * @(#)SimpleVname.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class SimpleVname extends Vname {
+
+ public SimpleVname(Identifier iAST, SourcePosition thePosition) {
+ super(thePosition);
+ I = iAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitSimpleVname(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..b9548ec
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleActualParameterSequence.java
@@ -0,0 +1,32 @@
+/*
+ * @(#)SingleActualParameterSequence.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class SingleActualParameterSequence extends ActualParameterSequence {
+
+ public SingleActualParameterSequence(ActualParameter apAST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ AP = apAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitSingleActualParameterSequence(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..92420d8
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleArrayAggregate.java
@@ -0,0 +1,32 @@
+/*
+ * @(#)SingleArrayAggregate.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class SingleArrayAggregate extends ArrayAggregate {
+
+ public SingleArrayAggregate(Expression eAST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ E = eAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitSingleArrayAggregate(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..e35eb95
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFieldTypeDenoter.java
@@ -0,0 +1,43 @@
+/*
+ * @(#)SingleFieldTypeDenoter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class SingleFieldTypeDenoter extends FieldTypeDenoter {
+
+ public SingleFieldTypeDenoter(Identifier iAST, TypeDenoter tAST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ I = iAST;
+ T = tAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitSingleFieldTypeDenoter(this, o);
+ }
+
+ 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;
+}
diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFormalParameterSequence.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFormalParameterSequence.java
new file mode 100644
index 0000000..b905bde
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFormalParameterSequence.java
@@ -0,0 +1,40 @@
+/*
+ * @(#)SingleFormalParameterSequence.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class SingleFormalParameterSequence extends FormalParameterSequence {
+
+ public SingleFormalParameterSequence(FormalParameter fpAST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ FP = fpAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitSingleFormalParameterSequence(this, o);
+ }
+
+ public boolean equals(Object fpsAST) {
+ if (fpsAST instanceof SingleFormalParameterSequence) {
+ SingleFormalParameterSequence sfpsAST = (SingleFormalParameterSequence) fpsAST;
+ return FP.equals(sfpsAST.FP);
+ } else
+ return false;
+ }
+
+ 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
new file mode 100644
index 0000000..211988a
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleRecordAggregate.java
@@ -0,0 +1,34 @@
+/*
+ * @(#)SingleRecordAggregate.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class SingleRecordAggregate extends RecordAggregate {
+
+ public SingleRecordAggregate(Identifier iAST, Expression eAST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ I = iAST;
+ E = eAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitSingleRecordAggregate(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..1b90ac5
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SubscriptVname.java
@@ -0,0 +1,33 @@
+/*
+ * @(#)SubscriptVname.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class SubscriptVname extends Vname {
+
+ public SubscriptVname(Vname vAST, Expression eAST, SourcePosition thePosition) {
+ super(thePosition);
+ V = vAST;
+ E = eAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitSubscriptVname(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..f14d753
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Terminal.java
@@ -0,0 +1,27 @@
+/*
+ * @(#)Terminal.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+abstract public class Terminal extends AST {
+
+ public Terminal(String theSpelling, SourcePosition thePosition) {
+ super(thePosition);
+ spelling = theSpelling;
+ }
+
+ 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
new file mode 100644
index 0000000..bf8a910
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/TypeDeclaration.java
@@ -0,0 +1,34 @@
+/*
+ * @(#)TypeDeclaration.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class TypeDeclaration extends Declaration {
+
+ public TypeDeclaration(Identifier iAST, TypeDenoter tAST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ I = iAST;
+ T = tAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitTypeDeclaration(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..ee8af46
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/TypeDenoter.java
@@ -0,0 +1,27 @@
+/*
+ * @(#)TypeDenoter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public abstract class TypeDenoter extends AST {
+
+ public TypeDenoter(SourcePosition thePosition) {
+ super(thePosition);
+ }
+
+ 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
new file mode 100644
index 0000000..b7a4f04
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/UnaryExpression.java
@@ -0,0 +1,34 @@
+/*
+ * @(#)UnaryExpression.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class UnaryExpression extends Expression {
+
+ public UnaryExpression(Operator oAST, Expression eAST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ O = oAST;
+ E = eAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitUnaryExpression(this, 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
new file mode 100644
index 0000000..152eb09
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/UnaryOperatorDeclaration.java
@@ -0,0 +1,35 @@
+/*
+ * @(#)UnaryOperatorDeclaration.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+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 Object visit(Visitor v, Object o) {
+ return v.visitUnaryOperatorDeclaration(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..a4bdbbf
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarActualParameter.java
@@ -0,0 +1,31 @@
+/*
+ * @(#)VarActualParameter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class VarActualParameter extends ActualParameter {
+
+ public VarActualParameter(Vname vAST, SourcePosition thePosition) {
+ super(thePosition);
+ V = vAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitVarActualParameter(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..0486a75
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarDeclaration.java
@@ -0,0 +1,34 @@
+/*
+ * @(#)VarDeclaration.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class VarDeclaration extends Declaration {
+
+ public VarDeclaration(Identifier iAST, TypeDenoter tAST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ I = iAST;
+ T = tAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitVarDeclaration(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..62b7cc2
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarFormalParameter.java
@@ -0,0 +1,42 @@
+/*
+ * @(#)ValFormalParameter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class VarFormalParameter extends FormalParameter {
+
+ public VarFormalParameter(Identifier iAST, TypeDenoter tAST,
+ SourcePosition thePosition) {
+ super(thePosition);
+ I = iAST;
+ T = tAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitVarFormalParameter(this, o);
+ }
+
+ public Identifier I;
+ public TypeDenoter T;
+
+ 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
new file mode 100644
index 0000000..b1be8a1
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Visitor.java
@@ -0,0 +1,154 @@
+/*
+ * @(#)Visitor.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+public interface Visitor {
+
+ // Commands
+ public abstract Object visitAssignCommand(AssignCommand ast, Object o);
+
+ public abstract Object visitCallCommand(CallCommand ast, Object o);
+
+ public abstract Object visitEmptyCommand(EmptyCommand ast, Object o);
+
+ public abstract Object visitIfCommand(IfCommand ast, Object o);
+
+ public abstract Object visitLetCommand(LetCommand ast, Object o);
+
+ public abstract Object visitSequentialCommand(SequentialCommand ast, Object o);
+
+ public abstract Object visitWhileCommand(WhileCommand ast, Object o);
+
+ // Expressions
+ public abstract Object visitArrayExpression(ArrayExpression ast, Object o);
+
+ public abstract Object visitBinaryExpression(BinaryExpression ast, Object o);
+
+ public abstract Object visitCallExpression(CallExpression ast, Object o);
+
+ public abstract Object visitCharacterExpression(CharacterExpression ast, Object o);
+
+ public abstract Object visitEmptyExpression(EmptyExpression ast, Object o);
+
+ public abstract Object visitIfExpression(IfExpression ast, Object o);
+
+ public abstract Object visitIntegerExpression(IntegerExpression ast, Object o);
+
+ public abstract Object visitLetExpression(LetExpression ast, Object o);
+
+ public abstract Object visitRecordExpression(RecordExpression ast, Object o);
+
+ public abstract Object visitUnaryExpression(UnaryExpression ast, Object o);
+
+ public abstract Object visitVnameExpression(VnameExpression ast, Object o);
+
+ // Declarations
+ public abstract Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Object o);
+
+ public abstract Object visitConstDeclaration(ConstDeclaration ast, Object o);
+
+ public abstract Object visitFuncDeclaration(FuncDeclaration ast, Object o);
+
+ public abstract Object visitProcDeclaration(ProcDeclaration ast, Object o);
+
+ public abstract Object visitSequentialDeclaration(SequentialDeclaration ast, Object o);
+
+ public abstract Object visitTypeDeclaration(TypeDeclaration ast, Object o);
+
+ public abstract Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Object o);
+
+ public abstract Object visitVarDeclaration(VarDeclaration ast, Object o);
+
+ // Array Aggregates
+ public abstract Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, Object o);
+
+ public abstract Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object o);
+
+ // Record Aggregates
+ public abstract Object visitMultipleRecordAggregate(MultipleRecordAggregate ast, Object o);
+
+ public abstract Object visitSingleRecordAggregate(SingleRecordAggregate ast, Object o);
+
+ // Formal Parameters
+ public abstract Object visitConstFormalParameter(ConstFormalParameter ast, Object o);
+
+ public abstract Object visitFuncFormalParameter(FuncFormalParameter ast, Object o);
+
+ public abstract Object visitProcFormalParameter(ProcFormalParameter ast, Object o);
+
+ public abstract Object visitVarFormalParameter(VarFormalParameter ast, Object o);
+
+ public abstract Object visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Object o);
+
+ public abstract Object visitMultipleFormalParameterSequence(MultipleFormalParameterSequence ast, Object o);
+
+ public abstract Object visitSingleFormalParameterSequence(SingleFormalParameterSequence ast, Object o);
+
+ // Actual Parameters
+ public abstract Object visitConstActualParameter(ConstActualParameter ast, Object o);
+
+ public abstract Object visitFuncActualParameter(FuncActualParameter ast, Object o);
+
+ public abstract Object visitProcActualParameter(ProcActualParameter ast, Object o);
+
+ public abstract Object visitVarActualParameter(VarActualParameter ast, Object o);
+
+ public abstract Object visitEmptyActualParameterSequence(EmptyActualParameterSequence ast, Object o);
+
+ public abstract Object visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, Object o);
+
+ public abstract Object visitSingleActualParameterSequence(SingleActualParameterSequence ast, Object o);
+
+ // Type Denoters
+ public abstract Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object o);
+
+ public abstract Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object o);
+
+ public abstract Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object o);
+
+ public abstract Object visitCharTypeDenoter(CharTypeDenoter ast, Object o);
+
+ public abstract Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object o);
+
+ public abstract Object visitSimpleTypeDenoter(SimpleTypeDenoter ast, Object o);
+
+ public abstract Object visitIntTypeDenoter(IntTypeDenoter ast, Object o);
+
+ public abstract Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object o);
+
+ public abstract Object visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, Object o);
+
+ public abstract Object visitSingleFieldTypeDenoter(SingleFieldTypeDenoter 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 visitIntegerLiteral(IntegerLiteral ast, Object o);
+
+ public abstract Object visitOperator(Operator 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 visitSubscriptVname(SubscriptVname 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
new file mode 100644
index 0000000..9c00d53
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Vname.java
@@ -0,0 +1,30 @@
+/*
+ * @(#)Vname.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public abstract class Vname extends AST {
+
+ public Vname(SourcePosition thePosition) {
+ super(thePosition);
+ variable = false;
+ type = null;
+ }
+
+ 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
new file mode 100644
index 0000000..49f23d3
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VnameExpression.java
@@ -0,0 +1,31 @@
+/*
+ * @(#)VnameExpression.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class VnameExpression extends Expression {
+
+ public VnameExpression(Vname vAST, SourcePosition thePosition) {
+ super(thePosition);
+ V = vAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitVnameExpression(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..6862e68
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/WhileCommand.java
@@ -0,0 +1,33 @@
+/*
+ * @(#)WhileCommand.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.AbstractSyntaxTrees;
+
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public class WhileCommand extends Command {
+
+ public WhileCommand(Expression eAST, Command cAST, SourcePosition thePosition) {
+ super(thePosition);
+ E = eAST;
+ C = cAST;
+ }
+
+ public Object visit(Visitor v, Object o) {
+ return v.visitWhileCommand(this, o);
+ }
+
+ 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
new file mode 100644
index 0000000..254a6ab
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Encoder.java
@@ -0,0 +1,983 @@
+/*
+ * @(#)Encoder.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.CodeGenerator;
+
+import java.io.DataOutputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import Triangle.ErrorReporter;
+import Triangle.StdEnvironment;
+import Triangle.AbstractMachine.Instruction;
+import Triangle.AbstractMachine.Machine;
+import Triangle.AbstractSyntaxTrees.AST;
+import Triangle.AbstractSyntaxTrees.AnyTypeDenoter;
+import Triangle.AbstractSyntaxTrees.ArrayExpression;
+import Triangle.AbstractSyntaxTrees.ArrayTypeDenoter;
+import Triangle.AbstractSyntaxTrees.AssignCommand;
+import Triangle.AbstractSyntaxTrees.BinaryExpression;
+import Triangle.AbstractSyntaxTrees.BinaryOperatorDeclaration;
+import Triangle.AbstractSyntaxTrees.BoolTypeDenoter;
+import Triangle.AbstractSyntaxTrees.CallCommand;
+import Triangle.AbstractSyntaxTrees.CallExpression;
+import Triangle.AbstractSyntaxTrees.CharTypeDenoter;
+import Triangle.AbstractSyntaxTrees.CharacterExpression;
+import Triangle.AbstractSyntaxTrees.CharacterLiteral;
+import Triangle.AbstractSyntaxTrees.ConstActualParameter;
+import Triangle.AbstractSyntaxTrees.ConstDeclaration;
+import Triangle.AbstractSyntaxTrees.ConstFormalParameter;
+import Triangle.AbstractSyntaxTrees.Declaration;
+import Triangle.AbstractSyntaxTrees.DotVname;
+import Triangle.AbstractSyntaxTrees.EmptyActualParameterSequence;
+import Triangle.AbstractSyntaxTrees.EmptyCommand;
+import Triangle.AbstractSyntaxTrees.EmptyExpression;
+import Triangle.AbstractSyntaxTrees.EmptyFormalParameterSequence;
+import Triangle.AbstractSyntaxTrees.ErrorTypeDenoter;
+import Triangle.AbstractSyntaxTrees.FuncActualParameter;
+import Triangle.AbstractSyntaxTrees.FuncDeclaration;
+import Triangle.AbstractSyntaxTrees.FuncFormalParameter;
+import Triangle.AbstractSyntaxTrees.Identifier;
+import Triangle.AbstractSyntaxTrees.IfCommand;
+import Triangle.AbstractSyntaxTrees.IfExpression;
+import Triangle.AbstractSyntaxTrees.IntTypeDenoter;
+import Triangle.AbstractSyntaxTrees.IntegerExpression;
+import Triangle.AbstractSyntaxTrees.IntegerLiteral;
+import Triangle.AbstractSyntaxTrees.LetCommand;
+import Triangle.AbstractSyntaxTrees.LetExpression;
+import Triangle.AbstractSyntaxTrees.MultipleActualParameterSequence;
+import Triangle.AbstractSyntaxTrees.MultipleArrayAggregate;
+import Triangle.AbstractSyntaxTrees.MultipleFieldTypeDenoter;
+import Triangle.AbstractSyntaxTrees.MultipleFormalParameterSequence;
+import Triangle.AbstractSyntaxTrees.MultipleRecordAggregate;
+import Triangle.AbstractSyntaxTrees.Operator;
+import Triangle.AbstractSyntaxTrees.ProcActualParameter;
+import Triangle.AbstractSyntaxTrees.ProcDeclaration;
+import Triangle.AbstractSyntaxTrees.ProcFormalParameter;
+import Triangle.AbstractSyntaxTrees.Program;
+import Triangle.AbstractSyntaxTrees.RecordExpression;
+import Triangle.AbstractSyntaxTrees.RecordTypeDenoter;
+import Triangle.AbstractSyntaxTrees.SequentialCommand;
+import Triangle.AbstractSyntaxTrees.SequentialDeclaration;
+import Triangle.AbstractSyntaxTrees.SimpleTypeDenoter;
+import Triangle.AbstractSyntaxTrees.SimpleVname;
+import Triangle.AbstractSyntaxTrees.SingleActualParameterSequence;
+import Triangle.AbstractSyntaxTrees.SingleArrayAggregate;
+import Triangle.AbstractSyntaxTrees.SingleFieldTypeDenoter;
+import Triangle.AbstractSyntaxTrees.SingleFormalParameterSequence;
+import Triangle.AbstractSyntaxTrees.SingleRecordAggregate;
+import Triangle.AbstractSyntaxTrees.SubscriptVname;
+import Triangle.AbstractSyntaxTrees.TypeDeclaration;
+import Triangle.AbstractSyntaxTrees.UnaryExpression;
+import Triangle.AbstractSyntaxTrees.UnaryOperatorDeclaration;
+import Triangle.AbstractSyntaxTrees.VarActualParameter;
+import Triangle.AbstractSyntaxTrees.VarDeclaration;
+import Triangle.AbstractSyntaxTrees.VarFormalParameter;
+import Triangle.AbstractSyntaxTrees.Visitor;
+import Triangle.AbstractSyntaxTrees.Vname;
+import Triangle.AbstractSyntaxTrees.VnameExpression;
+import Triangle.AbstractSyntaxTrees.WhileCommand;
+
+public final class Encoder implements Visitor {
+
+ // Commands
+ 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;
+ }
+
+ 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;
+ }
+
+ public Object visitEmptyCommand(EmptyCommand ast, Object o) {
+ return null;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ public Object visitSequentialCommand(SequentialCommand ast, Object o) {
+ ast.C1.visit(this, o);
+ ast.C2.visit(this, o);
+ return null;
+ }
+
+ 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
+ public Object visitArrayExpression(ArrayExpression ast, Object o) {
+ ast.type.visit(this, null);
+ return ast.AA.visit(this, o);
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ public Object visitEmptyExpression(EmptyExpression ast, Object o) {
+ return new Integer(0);
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ public Object visitRecordExpression(RecordExpression ast, Object o) {
+ ast.type.visit(this, null);
+ return ast.RA.visit(this, o);
+ }
+
+ 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;
+ }
+
+ 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
+ public Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast,
+ Object o) {
+ return new Integer(0);
+ }
+
+ 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 new Integer(extraSize);
+ }
+
+ 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 new Integer(0);
+ }
+
+ 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 new Integer(0);
+ }
+
+ 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 new Integer(extraSize1 + extraSize2);
+ }
+
+ public Object visitTypeDeclaration(TypeDeclaration ast, Object o) {
+ // just to ensure the type's representation is decided
+ ast.T.visit(this, null);
+ return new Integer(0);
+ }
+
+ public Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast,
+ Object o) {
+ return new Integer(0);
+ }
+
+ 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 new Integer(extraSize);
+ }
+
+ // Array Aggregates
+ 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 new Integer(elemSize + arraySize);
+ }
+
+ public Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object o) {
+ return ast.E.visit(this, o);
+ }
+
+ // Record Aggregates
+ 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 new Integer(fieldSize + recordSize);
+ }
+
+ public Object visitSingleRecordAggregate(SingleRecordAggregate ast,
+ Object o) {
+ return ast.E.visit(this, o);
+ }
+
+ // Formal Parameters
+ 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 new Integer(valSize);
+ }
+
+ 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 new Integer(argsSize);
+ }
+
+ 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 new Integer(argsSize);
+ }
+
+ 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 new Integer(Machine.addressSize);
+ }
+
+ public Object visitEmptyFormalParameterSequence(
+ EmptyFormalParameterSequence ast, Object o) {
+ return new Integer(0);
+ }
+
+ 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 new Integer(argsSize1 + argsSize2);
+ }
+
+ public Object visitSingleFormalParameterSequence(
+ SingleFormalParameterSequence ast, Object o) {
+ return ast.FP.visit(this, o);
+ }
+
+ // Actual Parameters
+ public Object visitConstActualParameter(ConstActualParameter ast, Object o) {
+ return ast.E.visit(this, o);
+ }
+
+ 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 new Integer(Machine.closureSize);
+ }
+
+ 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 new Integer(Machine.closureSize);
+ }
+
+ public Object visitVarActualParameter(VarActualParameter ast, Object o) {
+ encodeFetchAddress(ast.V, (Frame) o);
+ return new Integer(Machine.addressSize);
+ }
+
+ public Object visitEmptyActualParameterSequence(
+ EmptyActualParameterSequence ast, Object o) {
+ return new Integer(0);
+ }
+
+ 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 new Integer(argsSize1 + argsSize2);
+ }
+
+ public Object visitSingleActualParameterSequence(
+ SingleActualParameterSequence ast, Object o) {
+ return ast.AP.visit(this, o);
+ }
+
+ // Type Denoters
+ public Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object o) {
+ return new Integer(0);
+ }
+
+ 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 new Integer(typeSize);
+ }
+
+ public Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object o) {
+ if (ast.entity == null) {
+ ast.entity = new TypeRepresentation(Machine.booleanSize);
+ writeTableDetails(ast);
+ }
+ return new Integer(Machine.booleanSize);
+ }
+
+ public Object visitCharTypeDenoter(CharTypeDenoter ast, Object o) {
+ if (ast.entity == null) {
+ ast.entity = new TypeRepresentation(Machine.characterSize);
+ writeTableDetails(ast);
+ }
+ return new Integer(Machine.characterSize);
+ }
+
+ public Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object o) {
+ return new Integer(0);
+ }
+
+ public Object visitSimpleTypeDenoter(SimpleTypeDenoter ast,
+ Object o) {
+ return new Integer(0);
+ }
+
+ public Object visitIntTypeDenoter(IntTypeDenoter ast, Object o) {
+ if (ast.entity == null) {
+ ast.entity = new TypeRepresentation(Machine.integerSize);
+ writeTableDetails(ast);
+ }
+ return new Integer(Machine.integerSize);
+ }
+
+ public Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object o) {
+ int typeSize;
+ if (ast.entity == null) {
+ typeSize = ((Integer) ast.FT.visit(this, new Integer(0))).intValue();
+ ast.entity = new TypeRepresentation(typeSize);
+ writeTableDetails(ast);
+ } else
+ typeSize = ast.entity.size;
+ return new Integer(typeSize);
+ }
+
+ 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 = new Integer(offset + fieldSize);
+ int recSize = ((Integer) ast.FT.visit(this, offset1)).intValue();
+ return new Integer(fieldSize + recSize);
+ }
+
+ 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 new Integer(fieldSize);
+ }
+
+ // Literals, Identifiers and Operators
+ public Object visitCharacterLiteral(CharacterLiteral ast, Object o) {
+ return null;
+ }
+
+ 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;
+ }
+
+ public Object visitIntegerLiteral(IntegerLiteral ast, Object o) {
+ return null;
+ }
+
+ 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
+ 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;
+ }
+
+ public Object visitSimpleVname(SimpleVname ast, Object o) {
+ ast.offset = 0;
+ ast.indexed = false;
+ return ast.I.decl.entity;
+ }
+
+ 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
+ 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
new file mode 100644
index 0000000..2ae074b
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/EqualityRoutine.java
@@ -0,0 +1,30 @@
+/*
+ * @(#)EqualityRoutine.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.CodeGenerator;
+
+public class EqualityRoutine extends RuntimeEntity {
+
+ public EqualityRoutine() {
+ super();
+ }
+
+ public EqualityRoutine(int size, int displacement) {
+ super(size);
+ this.displacement = 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
new file mode 100644
index 0000000..6697e61
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Field.java
@@ -0,0 +1,31 @@
+/*
+ * @(#)Field.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.CodeGenerator;
+
+public class Field extends RuntimeEntity {
+
+ public Field() {
+ super();
+ fieldOffset = 0;
+ }
+
+ public Field(int size, int fieldOffset) {
+ super(size);
+ this.fieldOffset = 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
new file mode 100644
index 0000000..7b8066f
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Frame.java
@@ -0,0 +1,46 @@
+/*
+ * @(#)Frame.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+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;
+}
diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownAddress.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownAddress.java
new file mode 100644
index 0000000..f36a95b
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownAddress.java
@@ -0,0 +1,31 @@
+/*
+ * @(#)KnownAddress.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.CodeGenerator;
+
+public class KnownAddress extends RuntimeEntity {
+
+ public KnownAddress() {
+ super();
+ address = null;
+ }
+
+ public KnownAddress(int size, int level, int displacement) {
+ super(size);
+ address = new ObjectAddress(level, displacement);
+ }
+
+ 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
new file mode 100644
index 0000000..3e05661
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownRoutine.java
@@ -0,0 +1,31 @@
+/*
+ * @(#)KnownRoutine.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.CodeGenerator;
+
+public class KnownRoutine extends RuntimeEntity {
+
+ public KnownRoutine() {
+ super();
+ address = null;
+ }
+
+ public KnownRoutine(int size, int level, int displacement) {
+ super(size);
+ address = new ObjectAddress(level, displacement);
+ }
+
+ 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
new file mode 100644
index 0000000..24635f2
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownValue.java
@@ -0,0 +1,31 @@
+/*
+ * @(#)KnownValue.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.CodeGenerator;
+
+public class KnownValue extends RuntimeEntity {
+
+ public KnownValue() {
+ super();
+ value = 0;
+ }
+
+ public KnownValue(int size, int value) {
+ super(size);
+ this.value = 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
new file mode 100644
index 0000000..db1156a
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/ObjectAddress.java
@@ -0,0 +1,26 @@
+/*
+ * @(#)ObjectAddress.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.CodeGenerator;
+
+public final class ObjectAddress {
+
+ public ObjectAddress(int level, int displacement) {
+ this.level = level;
+ this.displacement = 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
new file mode 100644
index 0000000..37e6894
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/PrimitiveRoutine.java
@@ -0,0 +1,31 @@
+/*
+ * @(#)PrimitiveRoutine.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.CodeGenerator;
+
+public class PrimitiveRoutine extends RuntimeEntity {
+
+ public PrimitiveRoutine() {
+ super();
+ displacement = 0;
+ }
+
+ public PrimitiveRoutine(int size, int displacement) {
+ super(size);
+ this.displacement = 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
new file mode 100644
index 0000000..40d4d21
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/RuntimeEntity.java
@@ -0,0 +1,33 @@
+/*
+ * @(#)RuntimeEntity.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.CodeGenerator;
+
+// Run-time object
+
+public abstract class RuntimeEntity {
+
+ public final static int maxRoutineLevel = 7;
+
+ public RuntimeEntity() {
+ size = 0;
+ }
+
+ public RuntimeEntity(int size) {
+ this.size = 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
new file mode 100644
index 0000000..a14a087
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/TypeRepresentation.java
@@ -0,0 +1,23 @@
+/*
+ * @(#)TypeRepresentation.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.CodeGenerator;
+
+public class TypeRepresentation extends RuntimeEntity {
+
+ 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
new file mode 100644
index 0000000..f1e7605
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownAddress.java
@@ -0,0 +1,31 @@
+/*
+ * @(#)UnknownAddress.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.CodeGenerator;
+
+public class UnknownAddress extends RuntimeEntity {
+
+ public UnknownAddress() {
+ super();
+ address = null;
+ }
+
+ public UnknownAddress(int size, int level, int displacement) {
+ super(size);
+ address = new ObjectAddress(level, displacement);
+ }
+
+ 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
new file mode 100644
index 0000000..58df472
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownRoutine.java
@@ -0,0 +1,31 @@
+/*
+ * @(#)UnknownRoutine.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.CodeGenerator;
+
+public class UnknownRoutine extends RuntimeEntity {
+
+ public UnknownRoutine() {
+ super();
+ address = null;
+ }
+
+ public UnknownRoutine(int size, int level, int displacement) {
+ super(size);
+ address = new ObjectAddress(level, displacement);
+ }
+
+ 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
new file mode 100644
index 0000000..c5d3085
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownValue.java
@@ -0,0 +1,31 @@
+/*
+ * @(#)UnknownValue.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.CodeGenerator;
+
+public class UnknownValue extends RuntimeEntity {
+
+ public UnknownValue() {
+ super();
+ address = null;
+ }
+
+ public UnknownValue(int size, int level, int displacement) {
+ super(size);
+ address = new ObjectAddress(level, displacement);
+ }
+
+ public ObjectAddress address;
+
+}
diff --git a/Triangle.Compiler/src/main/java/Triangle/Compiler.java b/Triangle.Compiler/src/main/java/Triangle/Compiler.java
new file mode 100644
index 0000000..6e4be43
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/Compiler.java
@@ -0,0 +1,127 @@
+/*
+ * @(#)Compiler.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle;
+
+import Triangle.AbstractSyntaxTrees.Program;
+import Triangle.CodeGenerator.Encoder;
+import Triangle.ContextualAnalyzer.Checker;
+import Triangle.SyntacticAnalyzer.Parser;
+import Triangle.SyntacticAnalyzer.Scanner;
+import Triangle.SyntacticAnalyzer.SourceFile;
+import Triangle.TreeDrawer.Drawer;
+
+/**
+ * The main driver class for the Triangle compiler.
+ *
+ * @version 2.1 7 Oct 2003
+ * @author Deryck F. Brown
+ */
+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);
+ }
+}
diff --git a/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/Checker.java b/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/Checker.java
new file mode 100644
index 0000000..fae8e7a
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/Checker.java
@@ -0,0 +1,951 @@
+/*
+ * @(#)Checker.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.ContextualAnalyzer;
+
+import Triangle.ErrorReporter;
+import Triangle.StdEnvironment;
+import Triangle.AbstractSyntaxTrees.AnyTypeDenoter;
+import Triangle.AbstractSyntaxTrees.ArrayExpression;
+import Triangle.AbstractSyntaxTrees.ArrayTypeDenoter;
+import Triangle.AbstractSyntaxTrees.AssignCommand;
+import Triangle.AbstractSyntaxTrees.BinaryExpression;
+import Triangle.AbstractSyntaxTrees.BinaryOperatorDeclaration;
+import Triangle.AbstractSyntaxTrees.BoolTypeDenoter;
+import Triangle.AbstractSyntaxTrees.CallCommand;
+import Triangle.AbstractSyntaxTrees.CallExpression;
+import Triangle.AbstractSyntaxTrees.CharTypeDenoter;
+import Triangle.AbstractSyntaxTrees.CharacterExpression;
+import Triangle.AbstractSyntaxTrees.CharacterLiteral;
+import Triangle.AbstractSyntaxTrees.ConstActualParameter;
+import Triangle.AbstractSyntaxTrees.ConstDeclaration;
+import Triangle.AbstractSyntaxTrees.ConstFormalParameter;
+import Triangle.AbstractSyntaxTrees.Declaration;
+import Triangle.AbstractSyntaxTrees.DotVname;
+import Triangle.AbstractSyntaxTrees.EmptyActualParameterSequence;
+import Triangle.AbstractSyntaxTrees.EmptyCommand;
+import Triangle.AbstractSyntaxTrees.EmptyExpression;
+import Triangle.AbstractSyntaxTrees.EmptyFormalParameterSequence;
+import Triangle.AbstractSyntaxTrees.ErrorTypeDenoter;
+import Triangle.AbstractSyntaxTrees.FieldTypeDenoter;
+import Triangle.AbstractSyntaxTrees.FormalParameter;
+import Triangle.AbstractSyntaxTrees.FormalParameterSequence;
+import Triangle.AbstractSyntaxTrees.FuncActualParameter;
+import Triangle.AbstractSyntaxTrees.FuncDeclaration;
+import Triangle.AbstractSyntaxTrees.FuncFormalParameter;
+import Triangle.AbstractSyntaxTrees.Identifier;
+import Triangle.AbstractSyntaxTrees.IfCommand;
+import Triangle.AbstractSyntaxTrees.IfExpression;
+import Triangle.AbstractSyntaxTrees.IntTypeDenoter;
+import Triangle.AbstractSyntaxTrees.IntegerExpression;
+import Triangle.AbstractSyntaxTrees.IntegerLiteral;
+import Triangle.AbstractSyntaxTrees.LetCommand;
+import Triangle.AbstractSyntaxTrees.LetExpression;
+import Triangle.AbstractSyntaxTrees.MultipleActualParameterSequence;
+import Triangle.AbstractSyntaxTrees.MultipleArrayAggregate;
+import Triangle.AbstractSyntaxTrees.MultipleFieldTypeDenoter;
+import Triangle.AbstractSyntaxTrees.MultipleFormalParameterSequence;
+import Triangle.AbstractSyntaxTrees.MultipleRecordAggregate;
+import Triangle.AbstractSyntaxTrees.Operator;
+import Triangle.AbstractSyntaxTrees.ProcActualParameter;
+import Triangle.AbstractSyntaxTrees.ProcDeclaration;
+import Triangle.AbstractSyntaxTrees.ProcFormalParameter;
+import Triangle.AbstractSyntaxTrees.Program;
+import Triangle.AbstractSyntaxTrees.RecordExpression;
+import Triangle.AbstractSyntaxTrees.RecordTypeDenoter;
+import Triangle.AbstractSyntaxTrees.SequentialCommand;
+import Triangle.AbstractSyntaxTrees.SequentialDeclaration;
+import Triangle.AbstractSyntaxTrees.SimpleTypeDenoter;
+import Triangle.AbstractSyntaxTrees.SimpleVname;
+import Triangle.AbstractSyntaxTrees.SingleActualParameterSequence;
+import Triangle.AbstractSyntaxTrees.SingleArrayAggregate;
+import Triangle.AbstractSyntaxTrees.SingleFieldTypeDenoter;
+import Triangle.AbstractSyntaxTrees.SingleFormalParameterSequence;
+import Triangle.AbstractSyntaxTrees.SingleRecordAggregate;
+import Triangle.AbstractSyntaxTrees.SubscriptVname;
+import Triangle.AbstractSyntaxTrees.Terminal;
+import Triangle.AbstractSyntaxTrees.TypeDeclaration;
+import Triangle.AbstractSyntaxTrees.TypeDenoter;
+import Triangle.AbstractSyntaxTrees.UnaryExpression;
+import Triangle.AbstractSyntaxTrees.UnaryOperatorDeclaration;
+import Triangle.AbstractSyntaxTrees.VarActualParameter;
+import Triangle.AbstractSyntaxTrees.VarDeclaration;
+import Triangle.AbstractSyntaxTrees.VarFormalParameter;
+import Triangle.AbstractSyntaxTrees.Visitor;
+import Triangle.AbstractSyntaxTrees.VnameExpression;
+import Triangle.AbstractSyntaxTrees.WhileCommand;
+import Triangle.SyntacticAnalyzer.SourcePosition;
+
+public final class Checker implements Visitor {
+
+ // Commands
+
+ // Always returns null. Does not use the given object.
+
+ 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;
+ }
+
+ 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;
+ }
+
+ public Object visitEmptyCommand(EmptyCommand ast, Object o) {
+ return null;
+ }
+
+ 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;
+ }
+
+ public Object visitLetCommand(LetCommand ast, Object o) {
+ idTable.openScope();
+ ast.D.visit(this, null);
+ ast.C.visit(this, null);
+ idTable.closeScope();
+ return null;
+ }
+
+ public Object visitSequentialCommand(SequentialCommand ast, Object o) {
+ ast.C1.visit(this, null);
+ ast.C2.visit(this, null);
+ return null;
+ }
+
+ 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.
+
+ public Object visitArrayExpression(ArrayExpression ast, Object o) {
+ TypeDenoter elemType = (TypeDenoter) ast.AA.visit(this, null);
+ IntegerLiteral il = new IntegerLiteral(new Integer(ast.AA.elemCount).toString(),
+ ast.position);
+ ast.type = new ArrayTypeDenoter(il, elemType, ast.position);
+ return ast.type;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ public Object visitCharacterExpression(CharacterExpression ast, Object o) {
+ ast.type = StdEnvironment.charType;
+ return ast.type;
+ }
+
+ public Object visitEmptyExpression(EmptyExpression ast, Object o) {
+ ast.type = null;
+ return ast.type;
+ }
+
+ 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;
+ }
+
+ public Object visitIntegerExpression(IntegerExpression ast, Object o) {
+ ast.type = StdEnvironment.integerType;
+ return ast.type;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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.
+ public Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Object o) {
+ return null;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ public Object visitSequentialDeclaration(SequentialDeclaration ast, Object o) {
+ ast.D1.visit(this, null);
+ ast.D2.visit(this, null);
+ return null;
+ }
+
+ 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;
+ }
+
+ public Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Object o) {
+ return null;
+ }
+
+ 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.
+
+ 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;
+ }
+
+ 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.
+
+ 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;
+ }
+
+ 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.
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ public Object visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Object o) {
+ return null;
+ }
+
+ public Object visitMultipleFormalParameterSequence(MultipleFormalParameterSequence ast, Object o) {
+ ast.FP.visit(this, null);
+ ast.FPS.visit(this, null);
+ return null;
+ }
+
+ public Object visitSingleFormalParameterSequence(SingleFormalParameterSequence ast, Object o) {
+ ast.FP.visit(this, null);
+ return null;
+ }
+
+ // Actual Parameters
+
+ // Always returns null. Uses the given FormalParameter.
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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.
+
+ public Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object o) {
+ return StdEnvironment.anyType;
+ }
+
+ 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;
+ }
+
+ public Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object o) {
+ return StdEnvironment.booleanType;
+ }
+
+ public Object visitCharTypeDenoter(CharTypeDenoter ast, Object o) {
+ return StdEnvironment.charType;
+ }
+
+ public Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object o) {
+ return StdEnvironment.errorType;
+ }
+
+ 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;
+ }
+
+ public Object visitIntTypeDenoter(IntTypeDenoter ast, Object o) {
+ return StdEnvironment.integerType;
+ }
+
+ public Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object o) {
+ ast.FT = (FieldTypeDenoter) ast.FT.visit(this, null);
+ return ast;
+ }
+
+ public Object visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, Object o) {
+ ast.T = (TypeDenoter) ast.T.visit(this, null);
+ ast.FT.visit(this, null);
+ return ast;
+ }
+
+ public Object visitSingleFieldTypeDenoter(SingleFieldTypeDenoter ast, Object o) {
+ ast.T = (TypeDenoter) ast.T.visit(this, null);
+ return ast;
+ }
+
+ // Literals, Identifiers and Operators
+ public Object visitCharacterLiteral(CharacterLiteral CL, Object o) {
+ return StdEnvironment.charType;
+ }
+
+ public Object visitIdentifier(Identifier I, Object o) {
+ Declaration binding = idTable.retrieve(I.spelling);
+ if (binding != null)
+ I.decl = binding;
+ return binding;
+ }
+
+ public Object visitIntegerLiteral(IntegerLiteral IL, Object o) {
+ return StdEnvironment.integerType;
+ }
+
+ 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.
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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
+
+ 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
new file mode 100644
index 0000000..465710d
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdEntry.java
@@ -0,0 +1,33 @@
+/*
+ * @(#)IdEntry.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.ContextualAnalyzer;
+
+import Triangle.AbstractSyntaxTrees.Declaration;
+
+public class IdEntry {
+
+ 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;
+ }
+
+}
diff --git a/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdentificationTable.java b/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdentificationTable.java
new file mode 100644
index 0000000..a3276f0
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdentificationTable.java
@@ -0,0 +1,108 @@
+/*
+ * @(#)IdentificationTable.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.ContextualAnalyzer;
+
+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;
+ }
+
+}
diff --git a/Triangle.Compiler/src/main/java/Triangle/ErrorReporter.java b/Triangle.Compiler/src/main/java/Triangle/ErrorReporter.java
new file mode 100644
index 0000000..aadbfcb
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/ErrorReporter.java
@@ -0,0 +1,42 @@
+/*
+ * @(#)ErrorReporter.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle;
+
+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);
+ }
+}
diff --git a/Triangle.Compiler/src/main/java/Triangle/StdEnvironment.java b/Triangle.Compiler/src/main/java/Triangle/StdEnvironment.java
new file mode 100644
index 0000000..1366d1e
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/StdEnvironment.java
@@ -0,0 +1,47 @@
+/*
+ * @(#)StdEnvironment.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle;
+
+import Triangle.AbstractSyntaxTrees.BinaryOperatorDeclaration;
+import Triangle.AbstractSyntaxTrees.ConstDeclaration;
+import Triangle.AbstractSyntaxTrees.FuncDeclaration;
+import Triangle.AbstractSyntaxTrees.ProcDeclaration;
+import Triangle.AbstractSyntaxTrees.TypeDeclaration;
+import Triangle.AbstractSyntaxTrees.TypeDenoter;
+import Triangle.AbstractSyntaxTrees.UnaryOperatorDeclaration;
+
+public final class StdEnvironment {
+
+ // These are small ASTs representing standard types.
+
+ public static TypeDenoter booleanType, charType, integerType, anyType, errorType;
+
+ public static TypeDeclaration booleanDecl, charDecl, integerDecl;
+
+ // These are small ASTs representing "declarations" of standard entities.
+
+ public static ConstDeclaration falseDecl, trueDecl, maxintDecl;
+
+ public static UnaryOperatorDeclaration notDecl;
+
+ 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 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
new file mode 100644
index 0000000..ded9e7e
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Parser.java
@@ -0,0 +1,933 @@
+/*
+ * @(#)Parser.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.SyntacticAnalyzer;
+
+import Triangle.ErrorReporter;
+import Triangle.AbstractSyntaxTrees.ActualParameter;
+import Triangle.AbstractSyntaxTrees.ActualParameterSequence;
+import Triangle.AbstractSyntaxTrees.ArrayAggregate;
+import Triangle.AbstractSyntaxTrees.ArrayExpression;
+import Triangle.AbstractSyntaxTrees.ArrayTypeDenoter;
+import Triangle.AbstractSyntaxTrees.AssignCommand;
+import Triangle.AbstractSyntaxTrees.BinaryExpression;
+import Triangle.AbstractSyntaxTrees.CallCommand;
+import Triangle.AbstractSyntaxTrees.CallExpression;
+import Triangle.AbstractSyntaxTrees.CharacterExpression;
+import Triangle.AbstractSyntaxTrees.CharacterLiteral;
+import Triangle.AbstractSyntaxTrees.Command;
+import Triangle.AbstractSyntaxTrees.ConstActualParameter;
+import Triangle.AbstractSyntaxTrees.ConstDeclaration;
+import Triangle.AbstractSyntaxTrees.ConstFormalParameter;
+import Triangle.AbstractSyntaxTrees.Declaration;
+import Triangle.AbstractSyntaxTrees.DotVname;
+import Triangle.AbstractSyntaxTrees.EmptyActualParameterSequence;
+import Triangle.AbstractSyntaxTrees.EmptyCommand;
+import Triangle.AbstractSyntaxTrees.EmptyFormalParameterSequence;
+import Triangle.AbstractSyntaxTrees.Expression;
+import Triangle.AbstractSyntaxTrees.FieldTypeDenoter;
+import Triangle.AbstractSyntaxTrees.FormalParameter;
+import Triangle.AbstractSyntaxTrees.FormalParameterSequence;
+import Triangle.AbstractSyntaxTrees.FuncActualParameter;
+import Triangle.AbstractSyntaxTrees.FuncDeclaration;
+import Triangle.AbstractSyntaxTrees.FuncFormalParameter;
+import Triangle.AbstractSyntaxTrees.Identifier;
+import Triangle.AbstractSyntaxTrees.IfCommand;
+import Triangle.AbstractSyntaxTrees.IfExpression;
+import Triangle.AbstractSyntaxTrees.IntegerExpression;
+import Triangle.AbstractSyntaxTrees.IntegerLiteral;
+import Triangle.AbstractSyntaxTrees.LetCommand;
+import Triangle.AbstractSyntaxTrees.LetExpression;
+import Triangle.AbstractSyntaxTrees.MultipleActualParameterSequence;
+import Triangle.AbstractSyntaxTrees.MultipleArrayAggregate;
+import Triangle.AbstractSyntaxTrees.MultipleFieldTypeDenoter;
+import Triangle.AbstractSyntaxTrees.MultipleFormalParameterSequence;
+import Triangle.AbstractSyntaxTrees.MultipleRecordAggregate;
+import Triangle.AbstractSyntaxTrees.Operator;
+import Triangle.AbstractSyntaxTrees.ProcActualParameter;
+import Triangle.AbstractSyntaxTrees.ProcDeclaration;
+import Triangle.AbstractSyntaxTrees.ProcFormalParameter;
+import Triangle.AbstractSyntaxTrees.Program;
+import Triangle.AbstractSyntaxTrees.RecordAggregate;
+import Triangle.AbstractSyntaxTrees.RecordExpression;
+import Triangle.AbstractSyntaxTrees.RecordTypeDenoter;
+import Triangle.AbstractSyntaxTrees.SequentialCommand;
+import Triangle.AbstractSyntaxTrees.SequentialDeclaration;
+import Triangle.AbstractSyntaxTrees.SimpleTypeDenoter;
+import Triangle.AbstractSyntaxTrees.SimpleVname;
+import Triangle.AbstractSyntaxTrees.SingleActualParameterSequence;
+import Triangle.AbstractSyntaxTrees.SingleArrayAggregate;
+import Triangle.AbstractSyntaxTrees.SingleFieldTypeDenoter;
+import Triangle.AbstractSyntaxTrees.SingleFormalParameterSequence;
+import Triangle.AbstractSyntaxTrees.SingleRecordAggregate;
+import Triangle.AbstractSyntaxTrees.SubscriptVname;
+import Triangle.AbstractSyntaxTrees.TypeDeclaration;
+import Triangle.AbstractSyntaxTrees.TypeDenoter;
+import Triangle.AbstractSyntaxTrees.UnaryExpression;
+import Triangle.AbstractSyntaxTrees.VarActualParameter;
+import Triangle.AbstractSyntaxTrees.VarDeclaration;
+import Triangle.AbstractSyntaxTrees.VarFormalParameter;
+import Triangle.AbstractSyntaxTrees.Vname;
+import Triangle.AbstractSyntaxTrees.VnameExpression;
+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;
+ }
+}
diff --git a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Scanner.java b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Scanner.java
new file mode 100644
index 0000000..8d347a9
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Scanner.java
@@ -0,0 +1,273 @@
+/*
+ * @(#)Scanner.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+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;
+ }
+
+}
diff --git a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourceFile.java b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourceFile.java
new file mode 100644
index 0000000..3ec7aa2
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourceFile.java
@@ -0,0 +1,56 @@
+/*
+ * @(#)SourceFile.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+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;
+ }
+}
diff --git a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourcePosition.java b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourcePosition.java
new file mode 100644
index 0000000..3a70fda
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourcePosition.java
@@ -0,0 +1,34 @@
+/*
+ * @(#)SourcePosition.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.SyntacticAnalyzer;
+
+public class SourcePosition {
+
+ public int start, finish;
+
+ public SourcePosition() {
+ start = 0;
+ finish = 0;
+ }
+
+ public SourcePosition(int s, int f) {
+ start = s;
+ finish = f;
+ }
+
+ 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
new file mode 100644
index 0000000..214d5b3
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SyntaxError.java
@@ -0,0 +1,27 @@
+/*
+ * @(#)SyntaxError.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.SyntacticAnalyzer;
+
+class SyntaxError extends Exception {
+
+ SyntaxError() {
+ super();
+ };
+
+ 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
new file mode 100644
index 0000000..6f4d4a3
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Token.java
@@ -0,0 +1,148 @@
+/*
+ * @(#)Token.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+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];
+ }
+
+ 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
new file mode 100644
index 0000000..cb43f59
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Drawer.java
@@ -0,0 +1,61 @@
+/*
+ * @(#)Drawer.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.TreeDrawer;
+
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Point;
+
+import Triangle.AbstractSyntaxTrees.Program;
+
+public class Drawer {
+
+ private DrawerFrame frame;
+ private DrawerPanel panel;
+
+ private Program theAST;
+ private DrawingTree theDrawing;
+
+ // Draw the AST representing a complete program.
+
+ 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);
+
+ FontMetrics fontMetrics = frame.getFontMetrics(font);
+
+ LayoutVisitor layout = new LayoutVisitor(fontMetrics);
+ theDrawing = (DrawingTree) theAST.visit(layout, null);
+ theDrawing.position(new Point(2048, 10));
+
+ frame.show();
+ }
+
+ 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);
+ }
+ }
+}
diff --git a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerFrame.java b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerFrame.java
new file mode 100644
index 0000000..c12778d
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerFrame.java
@@ -0,0 +1,49 @@
+/*
+ * @(#)DrawerFrame.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.TreeDrawer;
+
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Toolkit;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+
+class DrawerFrame extends JFrame {
+ 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() {
+ 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
new file mode 100644
index 0000000..2ee0d12
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerPanel.java
@@ -0,0 +1,34 @@
+/*
+ * @(#)DrawerPanel.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.TreeDrawer;
+
+import java.awt.Dimension;
+import java.awt.Graphics;
+
+import javax.swing.JPanel;
+
+class DrawerPanel extends JPanel {
+ private Drawer drawer;
+
+ public DrawerPanel(Drawer drawer) {
+ setPreferredSize(new Dimension(4096, 4096));
+ this.drawer = drawer;
+ }
+
+ 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
new file mode 100644
index 0000000..d6a0991
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawingTree.java
@@ -0,0 +1,88 @@
+/*
+ * @(#)DrawingTree.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.TreeDrawer;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Point;
+
+public class DrawingTree {
+
+ 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 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);
+
+ 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 (int i = 0; i < children.length; i++) {
+ children[i].paint(graphics);
+ }
+ }
+
+ 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) {
+
+ 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);
+
+ if (children != null) {
+ for (int i = 0; i < children.length; i++) {
+ children[i].position(temp);
+ temp.x += children[i].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
new file mode 100644
index 0000000..bf192ba
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/LayoutVisitor.java
@@ -0,0 +1,533 @@
+/*
+ * @(#)LayoutVisitor.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.TreeDrawer;
+
+import java.awt.FontMetrics;
+
+import Triangle.AbstractSyntaxTrees.AST;
+import Triangle.AbstractSyntaxTrees.AnyTypeDenoter;
+import Triangle.AbstractSyntaxTrees.ArrayExpression;
+import Triangle.AbstractSyntaxTrees.ArrayTypeDenoter;
+import Triangle.AbstractSyntaxTrees.AssignCommand;
+import Triangle.AbstractSyntaxTrees.BinaryExpression;
+import Triangle.AbstractSyntaxTrees.BinaryOperatorDeclaration;
+import Triangle.AbstractSyntaxTrees.BoolTypeDenoter;
+import Triangle.AbstractSyntaxTrees.CallCommand;
+import Triangle.AbstractSyntaxTrees.CallExpression;
+import Triangle.AbstractSyntaxTrees.CharTypeDenoter;
+import Triangle.AbstractSyntaxTrees.CharacterExpression;
+import Triangle.AbstractSyntaxTrees.CharacterLiteral;
+import Triangle.AbstractSyntaxTrees.ConstActualParameter;
+import Triangle.AbstractSyntaxTrees.ConstDeclaration;
+import Triangle.AbstractSyntaxTrees.ConstFormalParameter;
+import Triangle.AbstractSyntaxTrees.DotVname;
+import Triangle.AbstractSyntaxTrees.EmptyActualParameterSequence;
+import Triangle.AbstractSyntaxTrees.EmptyCommand;
+import Triangle.AbstractSyntaxTrees.EmptyExpression;
+import Triangle.AbstractSyntaxTrees.EmptyFormalParameterSequence;
+import Triangle.AbstractSyntaxTrees.ErrorTypeDenoter;
+import Triangle.AbstractSyntaxTrees.FuncActualParameter;
+import Triangle.AbstractSyntaxTrees.FuncDeclaration;
+import Triangle.AbstractSyntaxTrees.FuncFormalParameter;
+import Triangle.AbstractSyntaxTrees.Identifier;
+import Triangle.AbstractSyntaxTrees.IfCommand;
+import Triangle.AbstractSyntaxTrees.IfExpression;
+import Triangle.AbstractSyntaxTrees.IntTypeDenoter;
+import Triangle.AbstractSyntaxTrees.IntegerExpression;
+import Triangle.AbstractSyntaxTrees.IntegerLiteral;
+import Triangle.AbstractSyntaxTrees.LetCommand;
+import Triangle.AbstractSyntaxTrees.LetExpression;
+import Triangle.AbstractSyntaxTrees.MultipleActualParameterSequence;
+import Triangle.AbstractSyntaxTrees.MultipleArrayAggregate;
+import Triangle.AbstractSyntaxTrees.MultipleFieldTypeDenoter;
+import Triangle.AbstractSyntaxTrees.MultipleFormalParameterSequence;
+import Triangle.AbstractSyntaxTrees.MultipleRecordAggregate;
+import Triangle.AbstractSyntaxTrees.Operator;
+import Triangle.AbstractSyntaxTrees.ProcActualParameter;
+import Triangle.AbstractSyntaxTrees.ProcDeclaration;
+import Triangle.AbstractSyntaxTrees.ProcFormalParameter;
+import Triangle.AbstractSyntaxTrees.Program;
+import Triangle.AbstractSyntaxTrees.RecordExpression;
+import Triangle.AbstractSyntaxTrees.RecordTypeDenoter;
+import Triangle.AbstractSyntaxTrees.SequentialCommand;
+import Triangle.AbstractSyntaxTrees.SequentialDeclaration;
+import Triangle.AbstractSyntaxTrees.SimpleTypeDenoter;
+import Triangle.AbstractSyntaxTrees.SimpleVname;
+import Triangle.AbstractSyntaxTrees.SingleActualParameterSequence;
+import Triangle.AbstractSyntaxTrees.SingleArrayAggregate;
+import Triangle.AbstractSyntaxTrees.SingleFieldTypeDenoter;
+import Triangle.AbstractSyntaxTrees.SingleFormalParameterSequence;
+import Triangle.AbstractSyntaxTrees.SingleRecordAggregate;
+import Triangle.AbstractSyntaxTrees.SubscriptVname;
+import Triangle.AbstractSyntaxTrees.TypeDeclaration;
+import Triangle.AbstractSyntaxTrees.UnaryExpression;
+import Triangle.AbstractSyntaxTrees.UnaryOperatorDeclaration;
+import Triangle.AbstractSyntaxTrees.VarActualParameter;
+import Triangle.AbstractSyntaxTrees.VarDeclaration;
+import Triangle.AbstractSyntaxTrees.VarFormalParameter;
+import Triangle.AbstractSyntaxTrees.Visitor;
+import Triangle.AbstractSyntaxTrees.VnameExpression;
+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
+ public Object visitAssignCommand(AssignCommand ast, Object obj) {
+ return layoutBinary("AssignCom.", ast.V, ast.E);
+ }
+
+ public Object visitCallCommand(CallCommand ast, Object obj) {
+ return layoutBinary("CallCom.", ast.I, ast.APS);
+ }
+
+ public Object visitEmptyCommand(EmptyCommand ast, Object obj) {
+ return layoutNullary("EmptyCom.");
+ }
+
+ public Object visitIfCommand(IfCommand ast, Object obj) {
+ return layoutTernary("IfCom.", ast.E, ast.C1, ast.C2);
+ }
+
+ public Object visitLetCommand(LetCommand ast, Object obj) {
+ return layoutBinary("LetCom.", ast.D, ast.C);
+ }
+
+ public Object visitSequentialCommand(SequentialCommand ast, Object obj) {
+ return layoutBinary("Seq.Com.", ast.C1, ast.C2);
+ }
+
+ public Object visitWhileCommand(WhileCommand ast, Object obj) {
+ return layoutBinary("WhileCom.", ast.E, ast.C);
+ }
+
+ // Expressions
+ public Object visitArrayExpression(ArrayExpression ast, Object obj) {
+ return layoutUnary("ArrayExpr.", ast.AA);
+ }
+
+ public Object visitBinaryExpression(BinaryExpression ast, Object obj) {
+ return layoutTernary("Bin.Expr.", ast.E1, ast.O, ast.E2);
+ }
+
+ public Object visitCallExpression(CallExpression ast, Object obj) {
+ return layoutBinary("CallExpr.", ast.I, ast.APS);
+ }
+
+ public Object visitCharacterExpression(CharacterExpression ast, Object obj) {
+ return layoutUnary("Char.Expr.", ast.CL);
+ }
+
+ public Object visitEmptyExpression(EmptyExpression ast, Object obj) {
+ return layoutNullary("EmptyExpr.");
+ }
+
+ public Object visitIfExpression(IfExpression ast, Object obj) {
+ return layoutTernary("IfExpr.", ast.E1, ast.E2, ast.E3);
+ }
+
+ public Object visitIntegerExpression(IntegerExpression ast, Object obj) {
+ return layoutUnary("Int.Expr.", ast.IL);
+ }
+
+ public Object visitLetExpression(LetExpression ast, Object obj) {
+ return layoutBinary("LetExpr.", ast.D, ast.E);
+ }
+
+ public Object visitRecordExpression(RecordExpression ast, Object obj) {
+ return layoutUnary("Rec.Expr.", ast.RA);
+ }
+
+ public Object visitUnaryExpression(UnaryExpression ast, Object obj) {
+ return layoutBinary("UnaryExpr.", ast.O, ast.E);
+ }
+
+ public Object visitVnameExpression(VnameExpression ast, Object obj) {
+ return layoutUnary("VnameExpr.", ast.V);
+ }
+
+ // Declarations
+ public Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Object obj) {
+ return layoutQuaternary("Bin.Op.Decl.", ast.O, ast.ARG1, ast.ARG2, ast.RES);
+ }
+
+ public Object visitConstDeclaration(ConstDeclaration ast, Object obj) {
+ return layoutBinary("ConstDecl.", ast.I, ast.E);
+ }
+
+ public Object visitFuncDeclaration(FuncDeclaration ast, Object obj) {
+ return layoutQuaternary("FuncDecl.", ast.I, ast.FPS, ast.T, ast.E);
+ }
+
+ public Object visitProcDeclaration(ProcDeclaration ast, Object obj) {
+ return layoutTernary("ProcDecl.", ast.I, ast.FPS, ast.C);
+ }
+
+ public Object visitSequentialDeclaration(SequentialDeclaration ast, Object obj) {
+ return layoutBinary("Seq.Decl.", ast.D1, ast.D2);
+ }
+
+ public Object visitTypeDeclaration(TypeDeclaration ast, Object obj) {
+ return layoutBinary("TypeDecl.", ast.I, ast.T);
+ }
+
+ public Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Object obj) {
+ return layoutTernary("UnaryOp.Decl.", ast.O, ast.ARG, ast.RES);
+ }
+
+ public Object visitVarDeclaration(VarDeclaration ast, Object obj) {
+ return layoutBinary("VarDecl.", ast.I, ast.T);
+ }
+
+ // Array Aggregates
+ public Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, Object obj) {
+ return layoutBinary("Mult.ArrayAgg.", ast.E, ast.AA);
+ }
+
+ public Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object obj) {
+ return layoutUnary("Sing.ArrayAgg.", ast.E);
+ }
+
+ // Record Aggregates
+ public Object visitMultipleRecordAggregate(MultipleRecordAggregate ast, Object obj) {
+ return layoutTernary("Mult.Rec.Agg.", ast.I, ast.E, ast.RA);
+ }
+
+ public Object visitSingleRecordAggregate(SingleRecordAggregate ast, Object obj) {
+ return layoutBinary("Sing.Rec.Agg.", ast.I, ast.E);
+ }
+
+ // Formal Parameters
+ public Object visitConstFormalParameter(ConstFormalParameter ast, Object obj) {
+ return layoutBinary("ConstF.P.", ast.I, ast.T);
+ }
+
+ public Object visitFuncFormalParameter(FuncFormalParameter ast, Object obj) {
+ return layoutTernary("FuncF.P.", ast.I, ast.FPS, ast.T);
+ }
+
+ public Object visitProcFormalParameter(ProcFormalParameter ast, Object obj) {
+ return layoutBinary("ProcF.P.", ast.I, ast.FPS);
+ }
+
+ public Object visitVarFormalParameter(VarFormalParameter ast, Object obj) {
+ return layoutBinary("VarF.P.", ast.I, ast.T);
+ }
+
+ public Object visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Object obj) {
+ return layoutNullary("EmptyF.P.S.");
+ }
+
+ public Object visitMultipleFormalParameterSequence(MultipleFormalParameterSequence ast, Object obj) {
+ return layoutBinary("Mult.F.P.S.", ast.FP, ast.FPS);
+ }
+
+ public Object visitSingleFormalParameterSequence(SingleFormalParameterSequence ast, Object obj) {
+ return layoutUnary("Sing.F.P.S.", ast.FP);
+ }
+
+ // Actual Parameters
+ public Object visitConstActualParameter(ConstActualParameter ast, Object obj) {
+ return layoutUnary("ConstA.P.", ast.E);
+ }
+
+ public Object visitFuncActualParameter(FuncActualParameter ast, Object obj) {
+ return layoutUnary("FuncA.P.", ast.I);
+ }
+
+ public Object visitProcActualParameter(ProcActualParameter ast, Object obj) {
+ return layoutUnary("ProcA.P.", ast.I);
+ }
+
+ public Object visitVarActualParameter(VarActualParameter ast, Object obj) {
+ return layoutUnary("VarA.P.", ast.V);
+ }
+
+ public Object visitEmptyActualParameterSequence(EmptyActualParameterSequence ast, Object obj) {
+ return layoutNullary("EmptyA.P.S.");
+ }
+
+ public Object visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, Object obj) {
+ return layoutBinary("Mult.A.P.S.", ast.AP, ast.APS);
+ }
+
+ public Object visitSingleActualParameterSequence(SingleActualParameterSequence ast, Object obj) {
+ return layoutUnary("Sing.A.P.S.", ast.AP);
+ }
+
+ // Type Denoters
+ public Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object obj) {
+ return layoutNullary("any");
+ }
+
+ public Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object obj) {
+ return layoutBinary("ArrayTypeD.", ast.IL, ast.T);
+ }
+
+ public Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object obj) {
+ return layoutNullary("bool");
+ }
+
+ public Object visitCharTypeDenoter(CharTypeDenoter ast, Object obj) {
+ return layoutNullary("char");
+ }
+
+ public Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object obj) {
+ return layoutNullary("error");
+ }
+
+ public Object visitSimpleTypeDenoter(SimpleTypeDenoter ast, Object obj) {
+ return layoutUnary("Sim.TypeD.", ast.I);
+ }
+
+ public Object visitIntTypeDenoter(IntTypeDenoter ast, Object obj) {
+ return layoutNullary("int");
+ }
+
+ public Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object obj) {
+ return layoutUnary("Rec.TypeD.", ast.FT);
+ }
+
+ public Object visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, Object obj) {
+ return layoutTernary("Mult.F.TypeD.", ast.I, ast.T, ast.FT);
+ }
+
+ public Object visitSingleFieldTypeDenoter(SingleFieldTypeDenoter ast, Object obj) {
+ return layoutBinary("Sing.F.TypeD.", ast.I, ast.T);
+ }
+
+ // Literals, Identifiers and Operators
+ public Object visitCharacterLiteral(CharacterLiteral ast, Object obj) {
+ return layoutNullary(ast.spelling);
+ }
+
+ public Object visitIdentifier(Identifier ast, Object obj) {
+ return layoutNullary(ast.spelling);
+ }
+
+ public Object visitIntegerLiteral(IntegerLiteral ast, Object obj) {
+ return layoutNullary(ast.spelling);
+ }
+
+ public Object visitOperator(Operator ast, Object obj) {
+ return layoutNullary(ast.spelling);
+ }
+
+ // Value-or-variable names
+ public Object visitDotVname(DotVname ast, Object obj) {
+ return layoutBinary("DotVname", ast.I, ast.V);
+ }
+
+ public Object visitSimpleVname(SimpleVname ast, Object obj) {
+ return layoutUnary("Sim.Vname", ast.I);
+ }
+
+ public Object visitSubscriptVname(SubscriptVname ast, Object obj) {
+ return layoutBinary("Sub.Vname",
+ ast.V, ast.E);
+ }
+
+ // Programs
+ 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
new file mode 100644
index 0000000..37f93f4
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Polygon.java
@@ -0,0 +1,20 @@
+/*
+ * @(#)Polygon.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.TreeDrawer;
+
+class Polygon {
+ 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
new file mode 100644
index 0000000..0d3fa90
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Polyline.java
@@ -0,0 +1,26 @@
+/*
+ * @(#)Polyline.java 2.1 2003/10/07
+ *
+ * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown
+ * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland
+ * and School of Computer and Math Sciences, The Robert Gordon University,
+ * St. Andrew Street, Aberdeen AB25 1HG, Scotland.
+ * All rights reserved.
+ *
+ * This software is provided free for educational use only. It may
+ * not be used for commercial purposes without the prior written permission
+ * of the authors.
+ */
+
+package Triangle.TreeDrawer;
+
+class Polyline {
+ int dx, dy;
+ Polyline link;
+
+ Polyline(int dx, int dy, Polyline link) {
+ this.dx = dx;
+ this.dy = dy;
+ this.link = link;
+ }
+};
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..596fe78
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,19 @@
+
+ 4.0.0
+ triangle.tools
+ triangle-tools
+ pom
+ 2.1
+
+ 1.8
+ 1.8
+ UTF-8
+
+
+ Triangle.AbstractMachine
+ Triangle.Compiler
+ Triangle.AbstractMachine.Disassembler
+ Triangle.AbstractMachine.Interpreter
+
+
\ No newline at end of file