Compare commits
30 Commits
version-2.
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
c3d038dd35 | ||
|
f5018e7f19 | ||
|
4be8f47351 | ||
|
82a5535d19 | ||
|
62b666992a | ||
|
e5730fe8a2 | ||
|
afc2b3e760 | ||
|
d12fc63571 | ||
|
e6487369ef | ||
|
d45c2339e1 | ||
|
0233c814ac | ||
|
71e2202512 | ||
|
fa3eb1f817 | ||
|
1000524e35 | ||
|
5cf07d1198 | ||
|
a6a078680c | ||
|
fbada163d4 | ||
|
bffeafba10 | ||
|
55f6b2d105 | ||
|
1db90b20a8 | ||
|
c8ed9462d8 | ||
|
d55ab77d0a | ||
|
d6a74fd51c | ||
|
2b0f3537de | ||
|
74b1117030 | ||
|
c183dd4c24 | ||
|
5292b42be6 | ||
|
a02acc009b | ||
|
2c426b5b2e | ||
|
7e5cf9df21 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -58,4 +58,5 @@ local.properties
|
|||||||
|
|
||||||
# Uncomment this line if you wish to ignore the project description file.
|
# Uncomment this line if you wish to ignore the project description file.
|
||||||
# Typically, this file would be tracked if it contains build/dependency configurations:
|
# Typically, this file would be tracked if it contains build/dependency configurations:
|
||||||
#.project
|
#.project
|
||||||
|
/.gradle/
|
||||||
|
6
.project
6
.project
@ -1,17 +1,17 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<projectDescription>
|
<projectDescription>
|
||||||
<name>triangle-tools</name>
|
<name>Triangle-Tools</name>
|
||||||
<comment></comment>
|
<comment></comment>
|
||||||
<projects>
|
<projects>
|
||||||
</projects>
|
</projects>
|
||||||
<buildSpec>
|
<buildSpec>
|
||||||
<buildCommand>
|
<buildCommand>
|
||||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||||
<arguments>
|
<arguments>
|
||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
</buildSpec>
|
</buildSpec>
|
||||||
<natures>
|
<natures>
|
||||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||||
</natures>
|
</natures>
|
||||||
</projectDescription>
|
</projectDescription>
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
/target/
|
/target/
|
||||||
/.classpath
|
/.classpath
|
||||||
|
/build/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<projectDescription>
|
<projectDescription>
|
||||||
<name>triangle-disassembler</name>
|
<name>Triangle.AbstractMachine.Disassembler</name>
|
||||||
<comment></comment>
|
<comment></comment>
|
||||||
<projects>
|
<projects>
|
||||||
</projects>
|
</projects>
|
||||||
@ -11,13 +11,13 @@
|
|||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
<buildCommand>
|
<buildCommand>
|
||||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||||
<arguments>
|
<arguments>
|
||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
</buildSpec>
|
</buildSpec>
|
||||||
<natures>
|
<natures>
|
||||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||||
</natures>
|
</natures>
|
||||||
</projectDescription>
|
</projectDescription>
|
||||||
|
12
Triangle.AbstractMachine.Disassembler/build.gradle
Normal file
12
Triangle.AbstractMachine.Disassembler/build.gradle
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
apply plugin: 'java'
|
||||||
|
apply plugin: 'application'
|
||||||
|
|
||||||
|
sourceCompatibility = 17
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(':Triangle.AbstractMachine')
|
||||||
|
}
|
||||||
|
|
||||||
|
application {
|
||||||
|
mainClass = 'Triangle.AbstractMachine.Disassembler'
|
||||||
|
}
|
@ -1,398 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* java TAM.Disassembler obj.tam
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* Copyright 1991 David A. Watt, University of Glasgow<br>
|
|
||||||
* Copyright 1998 Deryck F. Brown, The Robert Gordon University<br>
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class Disassembler {
|
|
||||||
|
|
||||||
static String objectName;
|
|
||||||
|
|
||||||
static int CT;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes the r-field of an instruction in the form "l<I>reg</I>r", 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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,351 @@
|
|||||||
|
/*
|
||||||
|
* @(#)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:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* java TAM.Disassembler obj.tam
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Copyright 1991 David A. Watt, University of Glasgow<br>
|
||||||
|
* Copyright 1998 Deryck F. Brown, The Robert Gordon University<br>
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Disassembler {
|
||||||
|
|
||||||
|
static String objectName;
|
||||||
|
|
||||||
|
static int CT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the r-field of an instruction in the form "l<I>reg</I>r", 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, Register r, char rightbracket) {
|
||||||
|
|
||||||
|
System.out.print(leftbracket);
|
||||||
|
System.out.print(r.toString());
|
||||||
|
System.out.print(rightbracket);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void writeR(char leftBracket, int r, char rightBracket) {
|
||||||
|
var register = Register.values()[r];
|
||||||
|
writeR(leftBracket, register, 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 displacement of the primitive routine.
|
||||||
|
*/
|
||||||
|
private static void writePrimitive(int d) {
|
||||||
|
var primitive = Primitive.values()[d];
|
||||||
|
switch (primitive) {
|
||||||
|
case ID:
|
||||||
|
System.out.print("id ");
|
||||||
|
break;
|
||||||
|
case NOT:
|
||||||
|
System.out.print("not ");
|
||||||
|
break;
|
||||||
|
case AND:
|
||||||
|
System.out.print("and ");
|
||||||
|
break;
|
||||||
|
case OR:
|
||||||
|
System.out.print("or ");
|
||||||
|
break;
|
||||||
|
case SUCC:
|
||||||
|
System.out.print("succ ");
|
||||||
|
break;
|
||||||
|
case PRED:
|
||||||
|
System.out.print("pred ");
|
||||||
|
break;
|
||||||
|
case NEG:
|
||||||
|
System.out.print("neg ");
|
||||||
|
break;
|
||||||
|
case ADD:
|
||||||
|
System.out.print("add ");
|
||||||
|
break;
|
||||||
|
case SUB:
|
||||||
|
System.out.print("sub ");
|
||||||
|
break;
|
||||||
|
case MULT:
|
||||||
|
System.out.print("mult ");
|
||||||
|
break;
|
||||||
|
case DIV:
|
||||||
|
System.out.print("div ");
|
||||||
|
break;
|
||||||
|
case MOD:
|
||||||
|
System.out.print("mod ");
|
||||||
|
break;
|
||||||
|
case LT:
|
||||||
|
System.out.print("lt ");
|
||||||
|
break;
|
||||||
|
case LE:
|
||||||
|
System.out.print("le ");
|
||||||
|
break;
|
||||||
|
case GE:
|
||||||
|
System.out.print("ge ");
|
||||||
|
break;
|
||||||
|
case GT:
|
||||||
|
System.out.print("gt ");
|
||||||
|
break;
|
||||||
|
case EQ:
|
||||||
|
System.out.print("eq ");
|
||||||
|
break;
|
||||||
|
case NE:
|
||||||
|
System.out.print("ne ");
|
||||||
|
break;
|
||||||
|
case EOL:
|
||||||
|
System.out.print("eol ");
|
||||||
|
break;
|
||||||
|
case EOF:
|
||||||
|
System.out.print("eof ");
|
||||||
|
break;
|
||||||
|
case GET:
|
||||||
|
System.out.print("get ");
|
||||||
|
break;
|
||||||
|
case PUT:
|
||||||
|
System.out.print("put ");
|
||||||
|
break;
|
||||||
|
case GETEOL:
|
||||||
|
System.out.print("geteol ");
|
||||||
|
break;
|
||||||
|
case PUTEOL:
|
||||||
|
System.out.print("puteol ");
|
||||||
|
break;
|
||||||
|
case GETINT:
|
||||||
|
System.out.print("getint ");
|
||||||
|
break;
|
||||||
|
case PUTINT:
|
||||||
|
System.out.print("putint ");
|
||||||
|
break;
|
||||||
|
case NEW:
|
||||||
|
System.out.print("new ");
|
||||||
|
break;
|
||||||
|
case DISPOSE:
|
||||||
|
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.opCode) {
|
||||||
|
case LOAD:
|
||||||
|
System.out.print("LOAD ");
|
||||||
|
writeN(instr.length);
|
||||||
|
writeD(instr.operand);
|
||||||
|
writeR('[', instr.register, ']');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LOADA:
|
||||||
|
System.out.print("LOADA ");
|
||||||
|
blankN();
|
||||||
|
writeD(instr.operand);
|
||||||
|
writeR('[', instr.register, ']');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LOADI:
|
||||||
|
System.out.print("LOADI ");
|
||||||
|
writeN(instr.length);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LOADL:
|
||||||
|
System.out.print("LOADL ");
|
||||||
|
blankN();
|
||||||
|
writeD(instr.operand);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STORE:
|
||||||
|
System.out.print("STORE ");
|
||||||
|
writeN(instr.length);
|
||||||
|
writeD(instr.operand);
|
||||||
|
writeR('[', instr.register, ']');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STOREI:
|
||||||
|
System.out.print("STOREI");
|
||||||
|
writeN(instr.length);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CALL:
|
||||||
|
System.out.print("CALL ");
|
||||||
|
if (instr.register == Register.PB) {
|
||||||
|
blankN();
|
||||||
|
writePrimitive(instr.operand);
|
||||||
|
} else {
|
||||||
|
writeR('(', instr.length, ')');
|
||||||
|
System.out.print(" ");
|
||||||
|
writeD(instr.operand);
|
||||||
|
writeR('[', instr.register, ']');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CALLI:
|
||||||
|
System.out.print("CALLI ");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RETURN:
|
||||||
|
System.out.print("RETURN");
|
||||||
|
writeN(instr.length);
|
||||||
|
writeD(instr.operand);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PUSH:
|
||||||
|
System.out.print("PUSH ");
|
||||||
|
blankN();
|
||||||
|
writeD(instr.operand);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case POP:
|
||||||
|
System.out.print("POP ");
|
||||||
|
writeN(instr.length);
|
||||||
|
writeD(instr.operand);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JUMP:
|
||||||
|
System.out.print("JUMP ");
|
||||||
|
blankN();
|
||||||
|
writeD(instr.operand);
|
||||||
|
writeR('[', instr.register, ']');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JUMPI:
|
||||||
|
System.out.print("JUMPI ");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JUMPIF:
|
||||||
|
System.out.print("JUMPIF");
|
||||||
|
writeN(instr.length);
|
||||||
|
writeD(instr.operand);
|
||||||
|
writeR('[', instr.register, ']');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HALT:
|
||||||
|
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) {
|
||||||
|
|
||||||
|
var finished = false;
|
||||||
|
|
||||||
|
try (var objectFile = new FileInputStream(objectName)) {
|
||||||
|
var objectStream = new DataInputStream(objectFile);
|
||||||
|
var addr = Machine.CB;
|
||||||
|
while (!finished) {
|
||||||
|
Machine.code[addr] = Instruction.read(objectStream);
|
||||||
|
if (Machine.code[addr] == null) {
|
||||||
|
finished = true;
|
||||||
|
} else {
|
||||||
|
addr = addr + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CT = addr;
|
||||||
|
} 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();
|
||||||
|
}
|
||||||
|
}
|
@ -1,2 +1,3 @@
|
|||||||
/target/
|
/target/
|
||||||
/.classpath
|
/.classpath
|
||||||
|
/build/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<projectDescription>
|
<projectDescription>
|
||||||
<name>triangle-interpreter</name>
|
<name>Triangle.AbstractMachine.Interpreter</name>
|
||||||
<comment></comment>
|
<comment></comment>
|
||||||
<projects>
|
<projects>
|
||||||
</projects>
|
</projects>
|
||||||
@ -11,13 +11,13 @@
|
|||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
<buildCommand>
|
<buildCommand>
|
||||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||||
<arguments>
|
<arguments>
|
||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
</buildSpec>
|
</buildSpec>
|
||||||
<natures>
|
<natures>
|
||||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||||
</natures>
|
</natures>
|
||||||
</projectDescription>
|
</projectDescription>
|
||||||
|
12
Triangle.AbstractMachine.Interpreter/build.gradle
Normal file
12
Triangle.AbstractMachine.Interpreter/build.gradle
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
apply plugin: 'java'
|
||||||
|
apply plugin: 'application'
|
||||||
|
|
||||||
|
sourceCompatibility = 17
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(':Triangle.AbstractMachine')
|
||||||
|
}
|
||||||
|
|
||||||
|
application {
|
||||||
|
mainClass = 'Triangle.AbstractMachine.Interpreter'
|
||||||
|
}
|
@ -1,620 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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] = 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,641 @@
|
|||||||
|
/*
|
||||||
|
* @(#)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) {
|
||||||
|
var register = Register.values()[r];
|
||||||
|
return content(register);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int content(Register r) {
|
||||||
|
// Returns the current content of register r,
|
||||||
|
// even if r is one of the pseudo-registers L1..L6.
|
||||||
|
|
||||||
|
switch (r) {
|
||||||
|
case CB:
|
||||||
|
return CB;
|
||||||
|
case CT:
|
||||||
|
return CT;
|
||||||
|
case PB:
|
||||||
|
return Machine.PB;
|
||||||
|
case PT:
|
||||||
|
return Machine.PT;
|
||||||
|
case SB:
|
||||||
|
return SB;
|
||||||
|
case ST:
|
||||||
|
return ST;
|
||||||
|
case HB:
|
||||||
|
return HB;
|
||||||
|
case HT:
|
||||||
|
return HT;
|
||||||
|
case LB:
|
||||||
|
return LB;
|
||||||
|
case L1:
|
||||||
|
return data[LB];
|
||||||
|
case L2:
|
||||||
|
return data[data[LB]];
|
||||||
|
case L3:
|
||||||
|
return data[data[data[LB]]];
|
||||||
|
case L4:
|
||||||
|
return data[data[data[data[LB]]]];
|
||||||
|
case L5:
|
||||||
|
return data[data[data[data[data[LB]]]]];
|
||||||
|
case L6:
|
||||||
|
return data[data[data[data[data[data[LB]]]]]];
|
||||||
|
case CP:
|
||||||
|
return CP;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PROGRAM STATUS
|
||||||
|
|
||||||
|
static void dump() {
|
||||||
|
// Writes a summary of the machine state.
|
||||||
|
|
||||||
|
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 (var 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 {
|
||||||
|
var dynamicLink = LB;
|
||||||
|
var staticLink = LB;
|
||||||
|
var localRegNum = Register.LB;
|
||||||
|
System.out.println(" ST--> |////////|");
|
||||||
|
System.out.println(" |--------|");
|
||||||
|
for (var addr = ST - 1; addr >= SB; addr--) {
|
||||||
|
System.out.print(addr + ":");
|
||||||
|
if (addr == SB) {
|
||||||
|
System.out.print(" SB-->");
|
||||||
|
} else if (addr == staticLink) {
|
||||||
|
switch (localRegNum) {
|
||||||
|
case LB:
|
||||||
|
System.out.print(" LB-->");
|
||||||
|
break;
|
||||||
|
case L1:
|
||||||
|
System.out.print(" L1-->");
|
||||||
|
break;
|
||||||
|
case L2:
|
||||||
|
System.out.print(" L2-->");
|
||||||
|
break;
|
||||||
|
case L3:
|
||||||
|
System.out.print(" L3-->");
|
||||||
|
break;
|
||||||
|
case L4:
|
||||||
|
System.out.print(" L4-->");
|
||||||
|
break;
|
||||||
|
case L5:
|
||||||
|
System.out.print(" L5-->");
|
||||||
|
break;
|
||||||
|
case L6:
|
||||||
|
System.out.print(" L6-->");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
staticLink = data[addr];
|
||||||
|
localRegNum = Register.values()[localRegNum.ordinal() + 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;
|
||||||
|
|
||||||
|
var primitive = Primitive.values()[primitiveDisplacement];
|
||||||
|
switch (primitive) {
|
||||||
|
case ID:
|
||||||
|
break; // nothing to be done
|
||||||
|
case NOT:
|
||||||
|
data[ST - 1] = toInt(!isTrue(data[ST - 1]));
|
||||||
|
break;
|
||||||
|
case AND:
|
||||||
|
ST = ST - 1;
|
||||||
|
data[ST - 1] = toInt(isTrue(data[ST - 1]) & isTrue(data[ST]));
|
||||||
|
break;
|
||||||
|
case OR:
|
||||||
|
ST = ST - 1;
|
||||||
|
data[ST - 1] = toInt(isTrue(data[ST - 1]) | isTrue(data[ST]));
|
||||||
|
break;
|
||||||
|
case SUCC:
|
||||||
|
data[ST - 1] = overflowChecked(data[ST - 1] + 1);
|
||||||
|
break;
|
||||||
|
case PRED:
|
||||||
|
data[ST - 1] = overflowChecked(data[ST - 1] - 1);
|
||||||
|
break;
|
||||||
|
case NEG:
|
||||||
|
data[ST - 1] = -data[ST - 1];
|
||||||
|
break;
|
||||||
|
case ADD:
|
||||||
|
ST = ST - 1;
|
||||||
|
accumulator = data[ST - 1];
|
||||||
|
data[ST - 1] = overflowChecked(accumulator + data[ST]);
|
||||||
|
break;
|
||||||
|
case SUB:
|
||||||
|
ST = ST - 1;
|
||||||
|
accumulator = data[ST - 1];
|
||||||
|
data[ST - 1] = overflowChecked(accumulator - data[ST]);
|
||||||
|
break;
|
||||||
|
case MULT:
|
||||||
|
ST = ST - 1;
|
||||||
|
accumulator = data[ST - 1];
|
||||||
|
data[ST - 1] = overflowChecked(accumulator * data[ST]);
|
||||||
|
break;
|
||||||
|
case DIV:
|
||||||
|
ST = ST - 1;
|
||||||
|
accumulator = data[ST - 1];
|
||||||
|
if (data[ST] != 0) {
|
||||||
|
data[ST - 1] = (int) (accumulator / data[ST]);
|
||||||
|
} else {
|
||||||
|
status = failedZeroDivide;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MOD:
|
||||||
|
ST = ST - 1;
|
||||||
|
accumulator = data[ST - 1];
|
||||||
|
if (data[ST] != 0) {
|
||||||
|
data[ST - 1] = (int) (accumulator % data[ST]);
|
||||||
|
} else {
|
||||||
|
status = failedZeroDivide;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LT:
|
||||||
|
ST = ST - 1;
|
||||||
|
data[ST - 1] = toInt(data[ST - 1] < data[ST]);
|
||||||
|
break;
|
||||||
|
case LE:
|
||||||
|
ST = ST - 1;
|
||||||
|
data[ST - 1] = toInt(data[ST - 1] <= data[ST]);
|
||||||
|
break;
|
||||||
|
case GE:
|
||||||
|
ST = ST - 1;
|
||||||
|
data[ST - 1] = toInt(data[ST - 1] >= data[ST]);
|
||||||
|
break;
|
||||||
|
case GT:
|
||||||
|
ST = ST - 1;
|
||||||
|
data[ST - 1] = toInt(data[ST - 1] > data[ST]);
|
||||||
|
break;
|
||||||
|
case EQ:
|
||||||
|
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 NE:
|
||||||
|
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 EOL:
|
||||||
|
data[ST] = toInt(currentChar == '\n');
|
||||||
|
ST = ST + 1;
|
||||||
|
break;
|
||||||
|
case EOF:
|
||||||
|
data[ST] = toInt(currentChar == -1);
|
||||||
|
ST = ST + 1;
|
||||||
|
break;
|
||||||
|
case GET:
|
||||||
|
ST = ST - 1;
|
||||||
|
addr = data[ST];
|
||||||
|
try {
|
||||||
|
currentChar = System.in.read();
|
||||||
|
} catch (java.io.IOException s) {
|
||||||
|
status = failedIOError;
|
||||||
|
}
|
||||||
|
data[addr] = currentChar;
|
||||||
|
break;
|
||||||
|
case PUT:
|
||||||
|
ST = ST - 1;
|
||||||
|
ch = (char) data[ST];
|
||||||
|
System.out.print(ch);
|
||||||
|
break;
|
||||||
|
case GETEOL:
|
||||||
|
try {
|
||||||
|
while ((currentChar = System.in.read()) != '\n')
|
||||||
|
;
|
||||||
|
} catch (java.io.IOException s) {
|
||||||
|
status = failedIOError;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PUTEOL:
|
||||||
|
System.out.println("");
|
||||||
|
break;
|
||||||
|
case GETINT:
|
||||||
|
ST = ST - 1;
|
||||||
|
addr = data[ST];
|
||||||
|
try {
|
||||||
|
accumulator = readInt();
|
||||||
|
} catch (java.io.IOException s) {
|
||||||
|
status = failedIOError;
|
||||||
|
}
|
||||||
|
data[addr] = (int) accumulator;
|
||||||
|
break;
|
||||||
|
case PUTINT:
|
||||||
|
ST = ST - 1;
|
||||||
|
accumulator = data[ST];
|
||||||
|
System.out.print(accumulator);
|
||||||
|
break;
|
||||||
|
case NEW:
|
||||||
|
size = data[ST - 1];
|
||||||
|
checkSpace(size);
|
||||||
|
HT = HT - size;
|
||||||
|
data[ST - 1] = HT;
|
||||||
|
break;
|
||||||
|
case DISPOSE:
|
||||||
|
ST = ST - 1; // no action taken at present
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void interpretProgram() {
|
||||||
|
// Runs the program in code store.
|
||||||
|
|
||||||
|
Instruction currentInstr;
|
||||||
|
|
||||||
|
// Initialize registers ...
|
||||||
|
ST = SB;
|
||||||
|
HT = HB;
|
||||||
|
LB = SB;
|
||||||
|
CP = CB;
|
||||||
|
status = running;
|
||||||
|
do {
|
||||||
|
// Fetch instruction ...
|
||||||
|
currentInstr = Machine.code[CP];
|
||||||
|
// Decode instruction ...
|
||||||
|
var op = currentInstr.opCode;
|
||||||
|
var r = currentInstr.register;
|
||||||
|
var n = currentInstr.length;
|
||||||
|
var d = currentInstr.operand;
|
||||||
|
int addr;
|
||||||
|
|
||||||
|
// Execute instruction ...
|
||||||
|
switch (op) {
|
||||||
|
case LOAD:
|
||||||
|
addr = d + content(r);
|
||||||
|
checkSpace(n);
|
||||||
|
for (var index = 0; index < n; index++) {
|
||||||
|
data[ST + index] = data[addr + index];
|
||||||
|
}
|
||||||
|
ST = ST + n;
|
||||||
|
CP = CP + 1;
|
||||||
|
break;
|
||||||
|
case LOADA:
|
||||||
|
addr = d + content(r);
|
||||||
|
checkSpace(1);
|
||||||
|
data[ST] = addr;
|
||||||
|
ST = ST + 1;
|
||||||
|
CP = CP + 1;
|
||||||
|
break;
|
||||||
|
case LOADI:
|
||||||
|
ST = ST - 1;
|
||||||
|
addr = data[ST];
|
||||||
|
checkSpace(n);
|
||||||
|
for (var index = 0; index < n; index++) {
|
||||||
|
data[ST + index] = data[addr + index];
|
||||||
|
}
|
||||||
|
ST = ST + n;
|
||||||
|
CP = CP + 1;
|
||||||
|
break;
|
||||||
|
case LOADL:
|
||||||
|
checkSpace(1);
|
||||||
|
data[ST] = d;
|
||||||
|
ST = ST + 1;
|
||||||
|
CP = CP + 1;
|
||||||
|
break;
|
||||||
|
case STORE:
|
||||||
|
addr = d + content(r);
|
||||||
|
ST = ST - n;
|
||||||
|
for (var index = 0; index < n; index++) {
|
||||||
|
data[addr + index] = data[ST + index];
|
||||||
|
}
|
||||||
|
CP = CP + 1;
|
||||||
|
break;
|
||||||
|
case STOREI:
|
||||||
|
ST = ST - 1;
|
||||||
|
addr = data[ST];
|
||||||
|
ST = ST - n;
|
||||||
|
for (var index = 0; index < n; index++) {
|
||||||
|
data[addr + index] = data[ST + index];
|
||||||
|
}
|
||||||
|
CP = CP + 1;
|
||||||
|
break;
|
||||||
|
case CALL:
|
||||||
|
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 CALLI:
|
||||||
|
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 RETURN:
|
||||||
|
addr = LB - d;
|
||||||
|
CP = data[LB + 2];
|
||||||
|
LB = data[LB + 1];
|
||||||
|
ST = ST - n;
|
||||||
|
for (var index = 0; index < n; index++) {
|
||||||
|
data[addr + index] = data[ST + index];
|
||||||
|
}
|
||||||
|
ST = addr + n;
|
||||||
|
break;
|
||||||
|
case PUSH:
|
||||||
|
checkSpace(d);
|
||||||
|
ST = ST + d;
|
||||||
|
CP = CP + 1;
|
||||||
|
break;
|
||||||
|
case POP:
|
||||||
|
addr = ST - n - d;
|
||||||
|
ST = ST - n;
|
||||||
|
for (var index = 0; index < n; index++) {
|
||||||
|
data[addr + index] = data[ST + index];
|
||||||
|
}
|
||||||
|
ST = addr + n;
|
||||||
|
CP = CP + 1;
|
||||||
|
break;
|
||||||
|
case JUMP:
|
||||||
|
CP = d + content(r);
|
||||||
|
break;
|
||||||
|
case JUMPI:
|
||||||
|
ST = ST - 1;
|
||||||
|
CP = data[ST];
|
||||||
|
break;
|
||||||
|
case JUMPIF:
|
||||||
|
ST = ST - 1;
|
||||||
|
if (data[ST] == n) {
|
||||||
|
CP = d + content(r);
|
||||||
|
} else {
|
||||||
|
CP = CP + 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HALT:
|
||||||
|
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.
|
||||||
|
|
||||||
|
boolean finished = false;
|
||||||
|
|
||||||
|
try (var objectFile = new FileInputStream(objectName)) {
|
||||||
|
var objectStream = new DataInputStream(objectFile);
|
||||||
|
|
||||||
|
var addr = Machine.CB;
|
||||||
|
while (!finished) {
|
||||||
|
Machine.code[addr] = Instruction.read(objectStream);
|
||||||
|
if (Machine.code[addr] == null) {
|
||||||
|
finished = true;
|
||||||
|
} else {
|
||||||
|
addr = addr + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CT = addr;
|
||||||
|
} 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
Triangle.AbstractMachine/.gitignore
vendored
1
Triangle.AbstractMachine/.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
/target/
|
/target/
|
||||||
/.classpath
|
/.classpath
|
||||||
|
/build/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<projectDescription>
|
<projectDescription>
|
||||||
<name>triangle-abstractmachine</name>
|
<name>Triangle.AbstractMachine</name>
|
||||||
<comment></comment>
|
<comment></comment>
|
||||||
<projects>
|
<projects>
|
||||||
</projects>
|
</projects>
|
||||||
@ -11,13 +11,13 @@
|
|||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
<buildCommand>
|
<buildCommand>
|
||||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||||
<arguments>
|
<arguments>
|
||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
</buildSpec>
|
</buildSpec>
|
||||||
<natures>
|
<natures>
|
||||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||||
</natures>
|
</natures>
|
||||||
</projectDescription>
|
</projectDescription>
|
||||||
|
4
Triangle.AbstractMachine/build.gradle
Normal file
4
Triangle.AbstractMachine/build.gradle
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
apply plugin: 'java-library'
|
||||||
|
apply plugin: 'eclipse'
|
||||||
|
|
||||||
|
sourceCompatibility = 17
|
@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,125 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* @(#)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 {
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
final OpCode opCode;
|
||||||
|
final Register register;
|
||||||
|
final int length;
|
||||||
|
int operand; // Not final to allow for patching jump address
|
||||||
|
|
||||||
|
public Instruction(OpCode opcode, Register register, int length, int operand) {
|
||||||
|
this.opCode = opcode;
|
||||||
|
this.register = register;
|
||||||
|
this.length = length;
|
||||||
|
this.operand = operand;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOperand(int operand) {
|
||||||
|
this.operand = operand;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(DataOutputStream output) throws IOException {
|
||||||
|
output.writeInt(opCode.ordinal());
|
||||||
|
output.writeInt(register.ordinal());
|
||||||
|
output.writeInt(length);
|
||||||
|
output.writeInt(operand);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Instruction read(DataInputStream input) throws IOException {
|
||||||
|
try {
|
||||||
|
var opCode = OpCode.values()[input.readInt()];
|
||||||
|
var register = Register.values()[input.readInt()];
|
||||||
|
var length = input.readInt();
|
||||||
|
var operand = input.readInt();
|
||||||
|
return new Instruction(opCode, register, length, operand);
|
||||||
|
} catch (EOFException s) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* @(#)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
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package triangle.abstractMachine;
|
||||||
|
|
||||||
|
public enum OpCode {
|
||||||
|
LOAD, LOADA, LOADI, LOADL, STORE, STOREI, CALL, CALLI, RETURN, PUSH, POP, JUMP, JUMPI, JUMPIF, HALT
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package triangle.abstractMachine;
|
||||||
|
|
||||||
|
public enum Primitive {
|
||||||
|
ID, NOT, AND, OR, SUCC, PRED, NEG, ADD, SUB, MULT, DIV, MOD, LT, LE, GE, GT, EQ, NE, EOL, EOF, GET, PUT, GETEOL,
|
||||||
|
PUTEOL, GETINT, PUTINT, NEW, DISPOSE
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package triangle.abstractMachine;
|
||||||
|
|
||||||
|
public enum Register {
|
||||||
|
CB, CT, PB, PT, SB, ST, HB, HT, LB, L1, L2, L3, L4, L5, L6, CP
|
||||||
|
}
|
1
Triangle.Compiler/.gitignore
vendored
1
Triangle.Compiler/.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
/target/
|
/target/
|
||||||
/.classpath
|
/.classpath
|
||||||
/.editorconfig
|
/.editorconfig
|
||||||
|
/build/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<projectDescription>
|
<projectDescription>
|
||||||
<name>triangle-compiler</name>
|
<name>Triangle.Compiler</name>
|
||||||
<comment></comment>
|
<comment></comment>
|
||||||
<projects>
|
<projects>
|
||||||
</projects>
|
</projects>
|
||||||
@ -11,13 +11,13 @@
|
|||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
<buildCommand>
|
<buildCommand>
|
||||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||||
<arguments>
|
<arguments>
|
||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
</buildSpec>
|
</buildSpec>
|
||||||
<natures>
|
<natures>
|
||||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||||
</natures>
|
</natures>
|
||||||
</projectDescription>
|
</projectDescription>
|
||||||
|
12
Triangle.Compiler/build.gradle
Normal file
12
Triangle.Compiler/build.gradle
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
apply plugin: 'java'
|
||||||
|
apply plugin: 'application'
|
||||||
|
|
||||||
|
sourceCompatibility = 17
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(':Triangle.AbstractMachine')
|
||||||
|
}
|
||||||
|
|
||||||
|
application {
|
||||||
|
mainClass = 'Triangle.Compiler'
|
||||||
|
}
|
@ -1,24 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitArrayTypeDenoter(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj != null && obj instanceof ErrorTypeDenoter)
|
|
||||||
return true;
|
|
||||||
else if (obj != null && obj instanceof ArrayTypeDenoter)
|
|
||||||
return this.IL.spelling.compareTo(((ArrayTypeDenoter) obj).IL.spelling) == 0 &&
|
|
||||||
this.T.equals(((ArrayTypeDenoter) obj).T);
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IntegerLiteral IL;
|
|
||||||
public TypeDenoter T;
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitBinaryOperatorDeclaration(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Operator O;
|
|
||||||
public TypeDenoter ARG1, ARG2, RES;
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitBoolTypeDenoter(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if ((obj != null) && (obj instanceof ErrorTypeDenoter))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return ((obj != null) && (obj instanceof BoolTypeDenoter));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitCallCommand(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier I;
|
|
||||||
public ActualParameterSequence APS;
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitCallExpression(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier I;
|
|
||||||
public ActualParameterSequence APS;
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitCharTypeDenoter(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj != null && obj instanceof ErrorTypeDenoter)
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return (obj != null && obj instanceof CharTypeDenoter);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitCharacterExpression(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CharacterLiteral CL;
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitConstDeclaration(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier I;
|
|
||||||
public Expression E;
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitConstFormalParameter(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier I;
|
|
||||||
public TypeDenoter T;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object fpAST) {
|
|
||||||
if (fpAST instanceof ConstFormalParameter) {
|
|
||||||
ConstFormalParameter cfpAST = (ConstFormalParameter) fpAST;
|
|
||||||
return T.equals(cfpAST.T);
|
|
||||||
} else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract boolean equals(Object fpsAST);
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitFuncDeclaration(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier I;
|
|
||||||
public FormalParameterSequence FPS;
|
|
||||||
public TypeDenoter T;
|
|
||||||
public Expression E;
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitFuncFormalParameter(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object fpAST) {
|
|
||||||
if (fpAST instanceof FuncFormalParameter) {
|
|
||||||
FuncFormalParameter ffpAST = (FuncFormalParameter) fpAST;
|
|
||||||
return FPS.equals(ffpAST.FPS) && T.equals(ffpAST.T);
|
|
||||||
} else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier I;
|
|
||||||
public FormalParameterSequence FPS;
|
|
||||||
public TypeDenoter T;
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitIdentifier(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TypeDenoter type;
|
|
||||||
public AST decl; // Either a Declaration or a FieldTypeDenoter
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitIntTypeDenoter(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj != null && obj instanceof ErrorTypeDenoter)
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return (obj != null && obj instanceof IntTypeDenoter);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitIntegerExpression(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IntegerLiteral IL;
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitMultipleFieldTypeDenoter(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj != null && obj instanceof MultipleFieldTypeDenoter) {
|
|
||||||
MultipleFieldTypeDenoter ft = (MultipleFieldTypeDenoter) obj;
|
|
||||||
return (this.I.spelling.compareTo(ft.I.spelling) == 0) &&
|
|
||||||
this.T.equals(ft.T) &&
|
|
||||||
this.FT.equals(ft.FT);
|
|
||||||
} else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier I;
|
|
||||||
public TypeDenoter T;
|
|
||||||
public FieldTypeDenoter FT;
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitMultipleFormalParameterSequence(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object fpsAST) {
|
|
||||||
if (fpsAST instanceof MultipleFormalParameterSequence) {
|
|
||||||
MultipleFormalParameterSequence mfpsAST = (MultipleFormalParameterSequence) fpsAST;
|
|
||||||
return FP.equals(mfpsAST.FP) && FPS.equals(mfpsAST.FPS);
|
|
||||||
} else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FormalParameter FP;
|
|
||||||
public FormalParameterSequence FPS;
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitMultipleRecordAggregate(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier I;
|
|
||||||
public Expression E;
|
|
||||||
public RecordAggregate RA;
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitOperator(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Declaration decl;
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitProcDeclaration(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier I;
|
|
||||||
public FormalParameterSequence FPS;
|
|
||||||
public Command C;
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitProcFormalParameter(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier I;
|
|
||||||
public FormalParameterSequence FPS;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object fpAST) {
|
|
||||||
if (fpAST instanceof ProcFormalParameter) {
|
|
||||||
ProcFormalParameter pfpAST = (ProcFormalParameter) fpAST;
|
|
||||||
return FPS.equals(pfpAST.FPS);
|
|
||||||
} else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitProgram(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Command C;
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitRecordTypeDenoter(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj != null && obj instanceof ErrorTypeDenoter)
|
|
||||||
return true;
|
|
||||||
else if (obj != null && obj instanceof RecordTypeDenoter)
|
|
||||||
return this.FT.equals(((RecordTypeDenoter) obj).FT);
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FieldTypeDenoter FT;
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitSimpleTypeDenoter(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
return false; // should not happen
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier I;
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitSingleFieldTypeDenoter(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj != null && obj instanceof SingleFieldTypeDenoter) {
|
|
||||||
SingleFieldTypeDenoter ft = (SingleFieldTypeDenoter) obj;
|
|
||||||
return (this.I.spelling.compareTo(ft.I.spelling) == 0) &&
|
|
||||||
this.T.equals(ft.T);
|
|
||||||
} else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier I;
|
|
||||||
public TypeDenoter T;
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitSingleFormalParameterSequence(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object fpsAST) {
|
|
||||||
if (fpsAST instanceof SingleFormalParameterSequence) {
|
|
||||||
SingleFormalParameterSequence sfpsAST = (SingleFormalParameterSequence) fpsAST;
|
|
||||||
return FP.equals(sfpsAST.FP);
|
|
||||||
} else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FormalParameter FP;
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitSingleRecordAggregate(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier I;
|
|
||||||
public Expression E;
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitTypeDeclaration(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier I;
|
|
||||||
public TypeDenoter T;
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract boolean equals(Object obj);
|
|
||||||
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitUnaryOperatorDeclaration(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Operator O;
|
|
||||||
public TypeDenoter ARG, RES;
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitVarDeclaration(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier I;
|
|
||||||
public TypeDenoter T;
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visit(Visitor v, Object o) {
|
|
||||||
return v.visitVarFormalParameter(this, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier I;
|
|
||||||
public TypeDenoter T;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object fpAST) {
|
|
||||||
if (fpAST instanceof VarFormalParameter) {
|
|
||||||
VarFormalParameter vfpAST = (VarFormalParameter) fpAST;
|
|
||||||
return T.equals(vfpAST.T);
|
|
||||||
} else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,154 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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);
|
|
||||||
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
|
|
||||||
}
|
|
@ -1,127 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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);
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,108 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
|
|
||||||
}
|
|
@ -1,933 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,273 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,149 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Kind=" + kind + ", spelling=" + spelling +
|
|
||||||
", position=" + position;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Token classes...
|
|
||||||
|
|
||||||
public static final int
|
|
||||||
|
|
||||||
// literals, identifiers, operators...
|
|
||||||
INTLITERAL = 0,
|
|
||||||
CHARLITERAL = 1,
|
|
||||||
IDENTIFIER = 2,
|
|
||||||
OPERATOR = 3,
|
|
||||||
|
|
||||||
// reserved words - must be in alphabetical order...
|
|
||||||
ARRAY = 4,
|
|
||||||
BEGIN = 5,
|
|
||||||
CONST = 6,
|
|
||||||
DO = 7,
|
|
||||||
ELSE = 8,
|
|
||||||
END = 9,
|
|
||||||
FUNC = 10,
|
|
||||||
IF = 11,
|
|
||||||
IN = 12,
|
|
||||||
LET = 13,
|
|
||||||
OF = 14,
|
|
||||||
PROC = 15,
|
|
||||||
RECORD = 16,
|
|
||||||
THEN = 17,
|
|
||||||
TYPE = 18,
|
|
||||||
VAR = 19,
|
|
||||||
WHILE = 20,
|
|
||||||
|
|
||||||
// punctuation...
|
|
||||||
DOT = 21,
|
|
||||||
COLON = 22,
|
|
||||||
SEMICOLON = 23,
|
|
||||||
COMMA = 24,
|
|
||||||
BECOMES = 25,
|
|
||||||
IS = 26,
|
|
||||||
|
|
||||||
// brackets...
|
|
||||||
LPAREN = 27,
|
|
||||||
RPAREN = 28,
|
|
||||||
LBRACKET = 29,
|
|
||||||
RBRACKET = 30,
|
|
||||||
LCURLY = 31,
|
|
||||||
RCURLY = 32,
|
|
||||||
|
|
||||||
// special tokens...
|
|
||||||
EOT = 33,
|
|
||||||
ERROR = 34;
|
|
||||||
|
|
||||||
private static String[] tokenTable = new String[] {
|
|
||||||
"<int>",
|
|
||||||
"<char>",
|
|
||||||
"<identifier>",
|
|
||||||
"<operator>",
|
|
||||||
"array",
|
|
||||||
"begin",
|
|
||||||
"const",
|
|
||||||
"do",
|
|
||||||
"else",
|
|
||||||
"end",
|
|
||||||
"func",
|
|
||||||
"if",
|
|
||||||
"in",
|
|
||||||
"let",
|
|
||||||
"of",
|
|
||||||
"proc",
|
|
||||||
"record",
|
|
||||||
"then",
|
|
||||||
"type",
|
|
||||||
"var",
|
|
||||||
"while",
|
|
||||||
".",
|
|
||||||
":",
|
|
||||||
";",
|
|
||||||
",",
|
|
||||||
":=",
|
|
||||||
"~",
|
|
||||||
"(",
|
|
||||||
")",
|
|
||||||
"[",
|
|
||||||
"]",
|
|
||||||
"{",
|
|
||||||
"}",
|
|
||||||
"",
|
|
||||||
"<error>"
|
|
||||||
};
|
|
||||||
|
|
||||||
private final static int firstReservedWord = Token.ARRAY,
|
|
||||||
lastReservedWord = Token.WHILE;
|
|
||||||
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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.setVisible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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 {
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static final long serialVersionUID = -3650404598416929282L;
|
|
||||||
|
|
||||||
public DrawerFrame(JPanel panel) {
|
|
||||||
setSize(300, 200);
|
|
||||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
|
||||||
Dimension d = tk.getScreenSize();
|
|
||||||
int screenHeight = d.height;
|
|
||||||
int screenWidth = d.width;
|
|
||||||
setTitle("Triangle Compiler Abstract Syntax Tree");
|
|
||||||
setSize(screenWidth / 2, screenHeight / 2);
|
|
||||||
setLocation(screenWidth / 4, screenHeight / 4);
|
|
||||||
// Image img = tk.getImage("icon.gif");
|
|
||||||
// setIconImage(img);
|
|
||||||
|
|
||||||
addWindowListener(
|
|
||||||
new WindowAdapter() {
|
|
||||||
@Override
|
|
||||||
public void windowClosing(WindowEvent e) {
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Container contentPane = getContentPane();
|
|
||||||
contentPane.add(new JScrollPane(panel));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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 (DrawingTree child : children) {
|
|
||||||
child.paint(graphics);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parent != null) {
|
|
||||||
graphics.drawLine(pos.x + width / 2, pos.y,
|
|
||||||
parent.pos.x + parent.width / 2,
|
|
||||||
parent.pos.y + parent.height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 (DrawingTree child : children) {
|
|
||||||
child.position(temp);
|
|
||||||
temp.x += child.offset.x;
|
|
||||||
temp.y = this.pos.y + children[0].offset.y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,595 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)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
|
|
||||||
@Override
|
|
||||||
public Object visitAssignCommand(AssignCommand ast, Object obj) {
|
|
||||||
return layoutBinary("AssignCom.", ast.V, ast.E);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitCallCommand(CallCommand ast, Object obj) {
|
|
||||||
return layoutBinary("CallCom.", ast.I, ast.APS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitEmptyCommand(EmptyCommand ast, Object obj) {
|
|
||||||
return layoutNullary("EmptyCom.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitIfCommand(IfCommand ast, Object obj) {
|
|
||||||
return layoutTernary("IfCom.", ast.E, ast.C1, ast.C2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitLetCommand(LetCommand ast, Object obj) {
|
|
||||||
return layoutBinary("LetCom.", ast.D, ast.C);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitSequentialCommand(SequentialCommand ast, Object obj) {
|
|
||||||
return layoutBinary("Seq.Com.", ast.C1, ast.C2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitWhileCommand(WhileCommand ast, Object obj) {
|
|
||||||
return layoutBinary("WhileCom.", ast.E, ast.C);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expressions
|
|
||||||
@Override
|
|
||||||
public Object visitArrayExpression(ArrayExpression ast, Object obj) {
|
|
||||||
return layoutUnary("ArrayExpr.", ast.AA);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitBinaryExpression(BinaryExpression ast, Object obj) {
|
|
||||||
return layoutTernary("Bin.Expr.", ast.E1, ast.O, ast.E2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitCallExpression(CallExpression ast, Object obj) {
|
|
||||||
return layoutBinary("CallExpr.", ast.I, ast.APS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitCharacterExpression(CharacterExpression ast, Object obj) {
|
|
||||||
return layoutUnary("Char.Expr.", ast.CL);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitEmptyExpression(EmptyExpression ast, Object obj) {
|
|
||||||
return layoutNullary("EmptyExpr.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitIfExpression(IfExpression ast, Object obj) {
|
|
||||||
return layoutTernary("IfExpr.", ast.E1, ast.E2, ast.E3);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitIntegerExpression(IntegerExpression ast, Object obj) {
|
|
||||||
return layoutUnary("Int.Expr.", ast.IL);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitLetExpression(LetExpression ast, Object obj) {
|
|
||||||
return layoutBinary("LetExpr.", ast.D, ast.E);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitRecordExpression(RecordExpression ast, Object obj) {
|
|
||||||
return layoutUnary("Rec.Expr.", ast.RA);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitUnaryExpression(UnaryExpression ast, Object obj) {
|
|
||||||
return layoutBinary("UnaryExpr.", ast.O, ast.E);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitVnameExpression(VnameExpression ast, Object obj) {
|
|
||||||
return layoutUnary("VnameExpr.", ast.V);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Declarations
|
|
||||||
@Override
|
|
||||||
public Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Object obj) {
|
|
||||||
return layoutQuaternary("Bin.Op.Decl.", ast.O, ast.ARG1, ast.ARG2, ast.RES);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitConstDeclaration(ConstDeclaration ast, Object obj) {
|
|
||||||
return layoutBinary("ConstDecl.", ast.I, ast.E);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitFuncDeclaration(FuncDeclaration ast, Object obj) {
|
|
||||||
return layoutQuaternary("FuncDecl.", ast.I, ast.FPS, ast.T, ast.E);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitProcDeclaration(ProcDeclaration ast, Object obj) {
|
|
||||||
return layoutTernary("ProcDecl.", ast.I, ast.FPS, ast.C);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitSequentialDeclaration(SequentialDeclaration ast, Object obj) {
|
|
||||||
return layoutBinary("Seq.Decl.", ast.D1, ast.D2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitTypeDeclaration(TypeDeclaration ast, Object obj) {
|
|
||||||
return layoutBinary("TypeDecl.", ast.I, ast.T);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Object obj) {
|
|
||||||
return layoutTernary("UnaryOp.Decl.", ast.O, ast.ARG, ast.RES);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitVarDeclaration(VarDeclaration ast, Object obj) {
|
|
||||||
return layoutBinary("VarDecl.", ast.I, ast.T);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Array Aggregates
|
|
||||||
@Override
|
|
||||||
public Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, Object obj) {
|
|
||||||
return layoutBinary("Mult.ArrayAgg.", ast.E, ast.AA);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object obj) {
|
|
||||||
return layoutUnary("Sing.ArrayAgg.", ast.E);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Record Aggregates
|
|
||||||
@Override
|
|
||||||
public Object visitMultipleRecordAggregate(MultipleRecordAggregate ast, Object obj) {
|
|
||||||
return layoutTernary("Mult.Rec.Agg.", ast.I, ast.E, ast.RA);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitSingleRecordAggregate(SingleRecordAggregate ast, Object obj) {
|
|
||||||
return layoutBinary("Sing.Rec.Agg.", ast.I, ast.E);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Formal Parameters
|
|
||||||
@Override
|
|
||||||
public Object visitConstFormalParameter(ConstFormalParameter ast, Object obj) {
|
|
||||||
return layoutBinary("ConstF.P.", ast.I, ast.T);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitFuncFormalParameter(FuncFormalParameter ast, Object obj) {
|
|
||||||
return layoutTernary("FuncF.P.", ast.I, ast.FPS, ast.T);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitProcFormalParameter(ProcFormalParameter ast, Object obj) {
|
|
||||||
return layoutBinary("ProcF.P.", ast.I, ast.FPS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitVarFormalParameter(VarFormalParameter ast, Object obj) {
|
|
||||||
return layoutBinary("VarF.P.", ast.I, ast.T);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Object obj) {
|
|
||||||
return layoutNullary("EmptyF.P.S.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitMultipleFormalParameterSequence(MultipleFormalParameterSequence ast, Object obj) {
|
|
||||||
return layoutBinary("Mult.F.P.S.", ast.FP, ast.FPS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitSingleFormalParameterSequence(SingleFormalParameterSequence ast, Object obj) {
|
|
||||||
return layoutUnary("Sing.F.P.S.", ast.FP);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actual Parameters
|
|
||||||
@Override
|
|
||||||
public Object visitConstActualParameter(ConstActualParameter ast, Object obj) {
|
|
||||||
return layoutUnary("ConstA.P.", ast.E);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitFuncActualParameter(FuncActualParameter ast, Object obj) {
|
|
||||||
return layoutUnary("FuncA.P.", ast.I);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitProcActualParameter(ProcActualParameter ast, Object obj) {
|
|
||||||
return layoutUnary("ProcA.P.", ast.I);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitVarActualParameter(VarActualParameter ast, Object obj) {
|
|
||||||
return layoutUnary("VarA.P.", ast.V);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitEmptyActualParameterSequence(EmptyActualParameterSequence ast, Object obj) {
|
|
||||||
return layoutNullary("EmptyA.P.S.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, Object obj) {
|
|
||||||
return layoutBinary("Mult.A.P.S.", ast.AP, ast.APS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitSingleActualParameterSequence(SingleActualParameterSequence ast, Object obj) {
|
|
||||||
return layoutUnary("Sing.A.P.S.", ast.AP);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type Denoters
|
|
||||||
@Override
|
|
||||||
public Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object obj) {
|
|
||||||
return layoutNullary("any");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object obj) {
|
|
||||||
return layoutBinary("ArrayTypeD.", ast.IL, ast.T);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object obj) {
|
|
||||||
return layoutNullary("bool");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitCharTypeDenoter(CharTypeDenoter ast, Object obj) {
|
|
||||||
return layoutNullary("char");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object obj) {
|
|
||||||
return layoutNullary("error");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitSimpleTypeDenoter(SimpleTypeDenoter ast, Object obj) {
|
|
||||||
return layoutUnary("Sim.TypeD.", ast.I);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitIntTypeDenoter(IntTypeDenoter ast, Object obj) {
|
|
||||||
return layoutNullary("int");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object obj) {
|
|
||||||
return layoutUnary("Rec.TypeD.", ast.FT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, Object obj) {
|
|
||||||
return layoutTernary("Mult.F.TypeD.", ast.I, ast.T, ast.FT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitSingleFieldTypeDenoter(SingleFieldTypeDenoter ast, Object obj) {
|
|
||||||
return layoutBinary("Sing.F.TypeD.", ast.I, ast.T);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Literals, Identifiers and Operators
|
|
||||||
@Override
|
|
||||||
public Object visitCharacterLiteral(CharacterLiteral ast, Object obj) {
|
|
||||||
return layoutNullary(ast.spelling);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitIdentifier(Identifier ast, Object obj) {
|
|
||||||
return layoutNullary(ast.spelling);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitIntegerLiteral(IntegerLiteral ast, Object obj) {
|
|
||||||
return layoutNullary(ast.spelling);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitOperator(Operator ast, Object obj) {
|
|
||||||
return layoutNullary(ast.spelling);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value-or-variable names
|
|
||||||
@Override
|
|
||||||
public Object visitDotVname(DotVname ast, Object obj) {
|
|
||||||
return layoutBinary("DotVname", ast.I, ast.V);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitSimpleVname(SimpleVname ast, Object obj) {
|
|
||||||
return layoutUnary("Sim.Vname", ast.I);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitSubscriptVname(SubscriptVname ast, Object obj) {
|
|
||||||
return layoutBinary("Sub.Vname",
|
|
||||||
ast.V, ast.E);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Programs
|
|
||||||
@Override
|
|
||||||
public Object visitProgram(Program ast, Object obj) {
|
|
||||||
return layoutUnary("Program", ast.C);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DrawingTree layoutCaption(String name) {
|
|
||||||
int w = fontMetrics.stringWidth(name) + 4;
|
|
||||||
int h = fontMetrics.getHeight() + 4;
|
|
||||||
return new DrawingTree(name, w, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DrawingTree layoutNullary(String name) {
|
|
||||||
DrawingTree dt = layoutCaption(name);
|
|
||||||
dt.contour.upper_tail = new Polyline(0, dt.height + 2 * BORDER, null);
|
|
||||||
dt.contour.upper_head = dt.contour.upper_tail;
|
|
||||||
dt.contour.lower_tail = new Polyline(-dt.width - 2 * BORDER, 0, null);
|
|
||||||
dt.contour.lower_head = new Polyline(0, dt.height + 2 * BORDER, dt.contour.lower_tail);
|
|
||||||
return dt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DrawingTree layoutUnary(String name, AST child1) {
|
|
||||||
DrawingTree dt = layoutCaption(name);
|
|
||||||
DrawingTree d1 = (DrawingTree) child1.visit(this, null);
|
|
||||||
dt.setChildren(new DrawingTree[] { d1 });
|
|
||||||
attachParent(dt, join(dt));
|
|
||||||
return dt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DrawingTree layoutBinary(String name, AST child1, AST child2) {
|
|
||||||
DrawingTree dt = layoutCaption(name);
|
|
||||||
DrawingTree d1 = (DrawingTree) child1.visit(this, null);
|
|
||||||
DrawingTree d2 = (DrawingTree) child2.visit(this, null);
|
|
||||||
dt.setChildren(new DrawingTree[] { d1, d2 });
|
|
||||||
attachParent(dt, join(dt));
|
|
||||||
return dt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DrawingTree layoutTernary(String name, AST child1, AST child2,
|
|
||||||
AST child3) {
|
|
||||||
DrawingTree dt = layoutCaption(name);
|
|
||||||
DrawingTree d1 = (DrawingTree) child1.visit(this, null);
|
|
||||||
DrawingTree d2 = (DrawingTree) child2.visit(this, null);
|
|
||||||
DrawingTree d3 = (DrawingTree) child3.visit(this, null);
|
|
||||||
dt.setChildren(new DrawingTree[] { d1, d2, d3 });
|
|
||||||
attachParent(dt, join(dt));
|
|
||||||
return dt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DrawingTree layoutQuaternary(String name, AST child1, AST child2,
|
|
||||||
AST child3, AST child4) {
|
|
||||||
DrawingTree dt = layoutCaption(name);
|
|
||||||
DrawingTree d1 = (DrawingTree) child1.visit(this, null);
|
|
||||||
DrawingTree d2 = (DrawingTree) child2.visit(this, null);
|
|
||||||
DrawingTree d3 = (DrawingTree) child3.visit(this, null);
|
|
||||||
DrawingTree d4 = (DrawingTree) child4.visit(this, null);
|
|
||||||
dt.setChildren(new DrawingTree[] { d1, d2, d3, d4 });
|
|
||||||
attachParent(dt, join(dt));
|
|
||||||
return dt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void attachParent(DrawingTree dt, int w) {
|
|
||||||
int y = PARENT_SEP;
|
|
||||||
int x2 = (w - dt.width) / 2 - BORDER;
|
|
||||||
int x1 = x2 + dt.width + 2 * BORDER - w;
|
|
||||||
|
|
||||||
dt.children[0].offset.y = y + dt.height;
|
|
||||||
dt.children[0].offset.x = x1;
|
|
||||||
dt.contour.upper_head = new Polyline(0, dt.height,
|
|
||||||
new Polyline(x1, y, dt.contour.upper_head));
|
|
||||||
dt.contour.lower_head = new Polyline(0, dt.height,
|
|
||||||
new Polyline(x2, y, dt.contour.lower_head));
|
|
||||||
}
|
|
||||||
|
|
||||||
private int join(DrawingTree dt) {
|
|
||||||
int w, sum;
|
|
||||||
|
|
||||||
dt.contour = dt.children[0].contour;
|
|
||||||
sum = w = dt.children[0].width + 2 * BORDER;
|
|
||||||
|
|
||||||
for (int i = 1; i < dt.children.length; i++) {
|
|
||||||
int d = merge(dt.contour, dt.children[i].contour);
|
|
||||||
dt.children[i].offset.x = d + w;
|
|
||||||
dt.children[i].offset.y = 0;
|
|
||||||
w = dt.children[i].width + 2 * BORDER;
|
|
||||||
sum += d + w;
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int merge(Polygon c1, Polygon c2) {
|
|
||||||
int x, y, total, d;
|
|
||||||
Polyline lower, upper, b;
|
|
||||||
|
|
||||||
x = y = total = 0;
|
|
||||||
upper = c1.lower_head;
|
|
||||||
lower = c2.upper_head;
|
|
||||||
|
|
||||||
while (lower != null && upper != null) {
|
|
||||||
d = offset(x, y, lower.dx, lower.dy, upper.dx, upper.dy);
|
|
||||||
x += d;
|
|
||||||
total += d;
|
|
||||||
|
|
||||||
if (y + lower.dy <= upper.dy) {
|
|
||||||
x += lower.dx;
|
|
||||||
y += lower.dy;
|
|
||||||
lower = lower.link;
|
|
||||||
} else {
|
|
||||||
x -= upper.dx;
|
|
||||||
y -= upper.dy;
|
|
||||||
upper = upper.link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lower != null) {
|
|
||||||
b = bridge(c1.upper_tail, 0, 0, lower, x, y);
|
|
||||||
c1.upper_tail = (b.link != null) ? c2.upper_tail : b;
|
|
||||||
c1.lower_tail = c2.lower_tail;
|
|
||||||
} else {
|
|
||||||
b = bridge(c2.lower_tail, x, y, upper, 0, 0);
|
|
||||||
if (b.link == null) {
|
|
||||||
c1.lower_tail = b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c1.lower_head = c2.lower_head;
|
|
||||||
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int offset(int p1, int p2, int a1, int a2, int b1, int b2) {
|
|
||||||
int d, s, t;
|
|
||||||
|
|
||||||
if (b2 <= p2 || p2 + a2 <= 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
t = b2 * a1 - a2 * b1;
|
|
||||||
if (t > 0) {
|
|
||||||
if (p2 < 0) {
|
|
||||||
s = p2 * a1;
|
|
||||||
d = s / a2 - p1;
|
|
||||||
} else if (p2 > 0) {
|
|
||||||
s = p2 * b1;
|
|
||||||
d = s / b2 - p1;
|
|
||||||
} else {
|
|
||||||
d = -p1;
|
|
||||||
}
|
|
||||||
} else if (b2 < p2 + a2) {
|
|
||||||
s = (b2 - p2) * a1;
|
|
||||||
d = b1 - (p1 + s / a2);
|
|
||||||
} else if (b2 > p2 + a2) {
|
|
||||||
s = (a2 + p2) * b1;
|
|
||||||
d = s / b2 - (p1 + a1);
|
|
||||||
} else {
|
|
||||||
d = b1 - (p1 + a1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d > 0) {
|
|
||||||
return d;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Polyline bridge(Polyline line1, int x1, int y1,
|
|
||||||
Polyline line2, int x2, int y2) {
|
|
||||||
int dy, dx, s;
|
|
||||||
Polyline r;
|
|
||||||
|
|
||||||
dy = y2 + line2.dy - y1;
|
|
||||||
if (line2.dy == 0) {
|
|
||||||
dx = line2.dx;
|
|
||||||
} else {
|
|
||||||
s = dy * line2.dx;
|
|
||||||
dx = s / line2.dy;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = new Polyline(dx, dy, line2.link);
|
|
||||||
line1.link = new Polyline(x2 + line2.dx - dx - x1, 0, r);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
129
Triangle.Compiler/src/main/java/triangle/Compiler.java
Normal file
129
Triangle.Compiler/src/main/java/triangle/Compiler.java
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* @(#)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.Emitter;
|
||||||
|
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 Emitter emitter;
|
||||||
|
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
|
||||||
|
* @param showingTable true iff the object description details are to be
|
||||||
|
* displayed during code generation (not currently
|
||||||
|
* implemented).
|
||||||
|
* @return true iff the source program is free of compile-time errors, otherwise
|
||||||
|
* false.
|
||||||
|
*/
|
||||||
|
static boolean compileProgram(String sourceName, String objectName, boolean showingAST, boolean showingTable) {
|
||||||
|
|
||||||
|
System.out.println("********** " + "Triangle Compiler (Java Version 2.1)" + " **********");
|
||||||
|
|
||||||
|
System.out.println("Syntactic Analysis ...");
|
||||||
|
SourceFile source = SourceFile.ofPath(sourceName);
|
||||||
|
|
||||||
|
if (source == null) {
|
||||||
|
System.out.println("Can't access source file " + sourceName);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
scanner = new Scanner(source);
|
||||||
|
reporter = new ErrorReporter();
|
||||||
|
parser = new Parser(scanner, reporter);
|
||||||
|
checker = new Checker(reporter);
|
||||||
|
emitter = new Emitter(reporter);
|
||||||
|
encoder = new Encoder(emitter, 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) {
|
||||||
|
emitter.saveObjectProgram(objectName);
|
||||||
|
System.out.println("Compilation was successful.");
|
||||||
|
} else {
|
||||||
|
System.out.println("Compilation was unsuccessful.");
|
||||||
|
}
|
||||||
|
return successful;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triangle compiler main program.
|
||||||
|
*
|
||||||
|
* @param args the only command-line argument to the program specifies the
|
||||||
|
* source filename.
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
if (args.length < 1) {
|
||||||
|
System.out.println("Usage: tc filename [tree]");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
String sourceName = args[0];
|
||||||
|
boolean tree = (args.length > 1 && args[1].equalsIgnoreCase("tree"));
|
||||||
|
var compiledOK = compileProgram(sourceName, objectName, tree, false);
|
||||||
|
|
||||||
|
if (!tree) {
|
||||||
|
System.exit(compiledOK ? 0 : 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
Triangle.Compiler/src/main/java/triangle/ErrorReporter.java
Normal file
42
Triangle.Compiler/src/main/java/triangle/ErrorReporter.java
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
46
Triangle.Compiler/src/main/java/triangle/StdEnvironment.java
Normal file
46
Triangle.Compiler/src/main/java/triangle/StdEnvironment.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* @(#)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.declarations.BinaryOperatorDeclaration;
|
||||||
|
import triangle.abstractSyntaxTrees.declarations.ConstDeclaration;
|
||||||
|
import triangle.abstractSyntaxTrees.declarations.FuncDeclaration;
|
||||||
|
import triangle.abstractSyntaxTrees.declarations.ProcDeclaration;
|
||||||
|
import triangle.abstractSyntaxTrees.declarations.UnaryOperatorDeclaration;
|
||||||
|
import triangle.abstractSyntaxTrees.types.TypeDeclaration;
|
||||||
|
import triangle.abstractSyntaxTrees.types.TypeDenoter;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
@ -12,24 +12,23 @@
|
|||||||
* of the authors.
|
* of the authors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package Triangle.AbstractSyntaxTrees;
|
package triangle.abstractSyntaxTrees;
|
||||||
|
|
||||||
import Triangle.CodeGenerator.RuntimeEntity;
|
import triangle.codeGenerator.entities.RuntimeEntity;
|
||||||
import Triangle.SyntacticAnalyzer.SourcePosition;
|
import triangle.syntacticAnalyzer.SourcePosition;
|
||||||
|
|
||||||
public abstract class AST {
|
public abstract class AbstractSyntaxTree {
|
||||||
|
|
||||||
public AST(SourcePosition thePosition) {
|
private final SourcePosition position;
|
||||||
position = thePosition;
|
|
||||||
entity = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SourcePosition getPosition() {
|
public AbstractSyntaxTree(SourcePosition position) {
|
||||||
return position;
|
this.position = position;
|
||||||
}
|
entity = null;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract Object visit(Visitor v, Object o);
|
public SourcePosition getPosition() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
public SourcePosition position;
|
public RuntimeEntity entity;
|
||||||
public RuntimeEntity entity;
|
|
||||||
}
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* @(#)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.abstractSyntaxTrees.commands.Command;
|
||||||
|
import triangle.abstractSyntaxTrees.visitors.ProgramVisitor;
|
||||||
|
import triangle.syntacticAnalyzer.SourcePosition;
|
||||||
|
|
||||||
|
public class Program extends AbstractSyntaxTree {
|
||||||
|
|
||||||
|
public Program(Command cAST, SourcePosition position) {
|
||||||
|
super(position);
|
||||||
|
C = cAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command C;
|
||||||
|
|
||||||
|
public <TArg, TResult> TResult visit(ProgramVisitor<TArg, TResult> visitor, TArg arg) {
|
||||||
|
return visitor.visitProgram(this, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <TResult> TResult visit(ProgramVisitor<Void, TResult> visitor) {
|
||||||
|
return visit(visitor, null);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* @(#)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.actuals;
|
||||||
|
|
||||||
|
import triangle.abstractSyntaxTrees.AbstractSyntaxTree;
|
||||||
|
import triangle.abstractSyntaxTrees.visitors.ActualParameterVisitor;
|
||||||
|
import triangle.syntacticAnalyzer.SourcePosition;
|
||||||
|
|
||||||
|
public abstract class ActualParameter extends AbstractSyntaxTree {
|
||||||
|
|
||||||
|
public ActualParameter(SourcePosition position) {
|
||||||
|
super(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract <TArg, TResult> TResult visit(ActualParameterVisitor<TArg, TResult> visitor, TArg arg);
|
||||||
|
|
||||||
|
public <TArg, TResult> TResult visit(ActualParameterVisitor<TArg, TResult> visitor) {
|
||||||
|
return visit(visitor, null);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* @(#)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.actuals;
|
||||||
|
|
||||||
|
import triangle.abstractSyntaxTrees.AbstractSyntaxTree;
|
||||||
|
import triangle.abstractSyntaxTrees.visitors.ActualParameterSequenceVisitor;
|
||||||
|
import triangle.syntacticAnalyzer.SourcePosition;
|
||||||
|
|
||||||
|
public abstract class ActualParameterSequence extends AbstractSyntaxTree {
|
||||||
|
|
||||||
|
public ActualParameterSequence(SourcePosition position) {
|
||||||
|
super(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract <TArg, TResult> TResult visit(ActualParameterSequenceVisitor<TArg, TResult> v, TArg arg);
|
||||||
|
|
||||||
|
public <TResult> TResult visit(ActualParameterSequenceVisitor<Void, TResult> v) {
|
||||||
|
return visit(v, null);
|
||||||
|
}
|
||||||
|
}
|
@ -12,21 +12,22 @@
|
|||||||
* of the authors.
|
* of the authors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package Triangle.AbstractSyntaxTrees;
|
package triangle.abstractSyntaxTrees.actuals;
|
||||||
|
|
||||||
import Triangle.SyntacticAnalyzer.SourcePosition;
|
import triangle.abstractSyntaxTrees.expressions.Expression;
|
||||||
|
import triangle.abstractSyntaxTrees.visitors.ActualParameterVisitor;
|
||||||
|
import triangle.syntacticAnalyzer.SourcePosition;
|
||||||
|
|
||||||
public class ConstActualParameter extends ActualParameter {
|
public class ConstActualParameter extends ActualParameter {
|
||||||
|
|
||||||
public ConstActualParameter(Expression eAST, SourcePosition thePosition) {
|
public ConstActualParameter(Expression eAST, SourcePosition position) {
|
||||||
super(thePosition);
|
super(position);
|
||||||
E = eAST;
|
E = eAST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public <TArg, TResult> TResult visit(ActualParameterVisitor<TArg, TResult> v, TArg arg) {
|
||||||
public Object visit(Visitor v, Object o) {
|
return v.visitConstActualParameter(this, arg);
|
||||||
return v.visitConstActualParameter(this, o);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public Expression E;
|
public final Expression E;
|
||||||
}
|
}
|
@ -12,18 +12,18 @@
|
|||||||
* of the authors.
|
* of the authors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package Triangle.AbstractSyntaxTrees;
|
package triangle.abstractSyntaxTrees.actuals;
|
||||||
|
|
||||||
import Triangle.SyntacticAnalyzer.SourcePosition;
|
import triangle.abstractSyntaxTrees.visitors.ActualParameterSequenceVisitor;
|
||||||
|
import triangle.syntacticAnalyzer.SourcePosition;
|
||||||
|
|
||||||
public class EmptyActualParameterSequence extends ActualParameterSequence {
|
public class EmptyActualParameterSequence extends ActualParameterSequence {
|
||||||
|
|
||||||
public EmptyActualParameterSequence(SourcePosition thePosition) {
|
public EmptyActualParameterSequence(SourcePosition position) {
|
||||||
super(thePosition);
|
super(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public <TArg, TResult> TResult visit(ActualParameterSequenceVisitor<TArg, TResult> v, TArg arg) {
|
||||||
public Object visit(Visitor v, Object o) {
|
return v.visitEmptyActualParameterSequence(this, arg);
|
||||||
return v.visitEmptyActualParameterSequence(this, o);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
@ -12,21 +12,22 @@
|
|||||||
* of the authors.
|
* of the authors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package Triangle.AbstractSyntaxTrees;
|
package triangle.abstractSyntaxTrees.actuals;
|
||||||
|
|
||||||
import Triangle.SyntacticAnalyzer.SourcePosition;
|
import triangle.abstractSyntaxTrees.terminals.Identifier;
|
||||||
|
import triangle.abstractSyntaxTrees.visitors.ActualParameterVisitor;
|
||||||
|
import triangle.syntacticAnalyzer.SourcePosition;
|
||||||
|
|
||||||
public class FuncActualParameter extends ActualParameter {
|
public class FuncActualParameter extends ActualParameter {
|
||||||
|
|
||||||
public FuncActualParameter(Identifier iAST, SourcePosition thePosition) {
|
public FuncActualParameter(Identifier iAST, SourcePosition position) {
|
||||||
super(thePosition);
|
super(position);
|
||||||
I = iAST;
|
I = iAST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public <TArg, TResult> TResult visit(ActualParameterVisitor<TArg, TResult> v, TArg arg) {
|
||||||
public Object visit(Visitor v, Object o) {
|
return v.visitFuncActualParameter(this, arg);
|
||||||
return v.visitFuncActualParameter(this, o);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier I;
|
public final Identifier I;
|
||||||
}
|
}
|
@ -12,24 +12,24 @@
|
|||||||
* of the authors.
|
* of the authors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package Triangle.AbstractSyntaxTrees;
|
package triangle.abstractSyntaxTrees.actuals;
|
||||||
|
|
||||||
import Triangle.SyntacticAnalyzer.SourcePosition;
|
import triangle.abstractSyntaxTrees.visitors.ActualParameterSequenceVisitor;
|
||||||
|
import triangle.syntacticAnalyzer.SourcePosition;
|
||||||
|
|
||||||
public class MultipleActualParameterSequence extends ActualParameterSequence {
|
public class MultipleActualParameterSequence extends ActualParameterSequence {
|
||||||
|
|
||||||
public MultipleActualParameterSequence(ActualParameter apAST, ActualParameterSequence apsAST,
|
public MultipleActualParameterSequence(ActualParameter apAST, ActualParameterSequence apsAST,
|
||||||
SourcePosition thePosition) {
|
SourcePosition position) {
|
||||||
super(thePosition);
|
super(position);
|
||||||
AP = apAST;
|
AP = apAST;
|
||||||
APS = apsAST;
|
APS = apsAST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public <TArg, TResult> TResult visit(ActualParameterSequenceVisitor<TArg, TResult> v, TArg arg) {
|
||||||
public Object visit(Visitor v, Object o) {
|
return v.visitMultipleActualParameterSequence(this, arg);
|
||||||
return v.visitMultipleActualParameterSequence(this, o);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public ActualParameter AP;
|
public final ActualParameter AP;
|
||||||
public ActualParameterSequence APS;
|
public final ActualParameterSequence APS;
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user