Archived
Compare commits
1
Commits
54d9f06a9e
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c3d038dd35 |
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<classpath>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/"/>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
|
||||||
<classpathentry kind="output" path="bin/default"/>
|
|
||||||
</classpath>
|
|
||||||
@@ -60,9 +60,3 @@ local.properties
|
|||||||
# 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/
|
/.gradle/
|
||||||
|
|
||||||
# tam files
|
|
||||||
*.tam
|
|
||||||
|
|
||||||
# Build folder
|
|
||||||
/build/
|
|
||||||
|
|||||||
@@ -5,11 +5,6 @@
|
|||||||
<projects>
|
<projects>
|
||||||
</projects>
|
</projects>
|
||||||
<buildSpec>
|
<buildSpec>
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
<buildCommand>
|
<buildCommand>
|
||||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||||
<arguments>
|
<arguments>
|
||||||
@@ -17,7 +12,6 @@
|
|||||||
</buildCommand>
|
</buildCommand>
|
||||||
</buildSpec>
|
</buildSpec>
|
||||||
<natures>
|
<natures>
|
||||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
|
||||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||||
</natures>
|
</natures>
|
||||||
</projectDescription>
|
</projectDescription>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
apply plugin: 'application'
|
apply plugin: 'application'
|
||||||
|
|
||||||
sourceCompatibility = 11
|
sourceCompatibility = 17
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(':Triangle.AbstractMachine')
|
implementation project(':Triangle.AbstractMachine')
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
apply plugin: 'application'
|
apply plugin: 'application'
|
||||||
|
|
||||||
sourceCompatibility = 11
|
sourceCompatibility = 17
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(':Triangle.AbstractMachine')
|
implementation project(':Triangle.AbstractMachine')
|
||||||
|
|||||||
-4
@@ -21,8 +21,6 @@ import java.io.IOException;
|
|||||||
|
|
||||||
public class Interpreter {
|
public class Interpreter {
|
||||||
|
|
||||||
static long startTimeNanos = 0;
|
|
||||||
|
|
||||||
static String objectName;
|
static String objectName;
|
||||||
|
|
||||||
// DATA STORE
|
// DATA STORE
|
||||||
@@ -185,7 +183,6 @@ public class Interpreter {
|
|||||||
break;
|
break;
|
||||||
case halted:
|
case halted:
|
||||||
System.out.println("Program has halted normally.");
|
System.out.println("Program has halted normally.");
|
||||||
System.out.println("Total execution time (ns): " + (System.nanoTime() - startTimeNanos));
|
|
||||||
break;
|
break;
|
||||||
case failedDataStoreFull:
|
case failedDataStoreFull:
|
||||||
System.out.println("Program has failed due to exhaustion of Data Store.");
|
System.out.println("Program has failed due to exhaustion of Data Store.");
|
||||||
@@ -637,7 +634,6 @@ public class Interpreter {
|
|||||||
|
|
||||||
loadObjectProgram(objectName);
|
loadObjectProgram(objectName);
|
||||||
if (CT != CB) {
|
if (CT != CB) {
|
||||||
startTimeNanos = System.nanoTime();
|
|
||||||
interpretProgram();
|
interpretProgram();
|
||||||
showStatus();
|
showStatus();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
apply plugin: 'java-library'
|
apply plugin: 'java-library'
|
||||||
apply plugin: 'eclipse'
|
apply plugin: 'eclipse'
|
||||||
|
|
||||||
sourceCompatibility = 11
|
sourceCompatibility = 17
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
package triangle.abstractMachine;
|
package triangle.abstractMachine;
|
||||||
|
|
||||||
public enum OpCode {
|
public enum OpCode {
|
||||||
LOAD, LOADA, LOADI, LOADL, STORE, STOREI, CALL, CALLI, RETURN, NOP, PUSH, POP, JUMP, JUMPI, JUMPIF, HALT
|
LOAD, LOADA, LOADI, LOADL, STORE, STOREI, CALL, CALLI, RETURN, PUSH, POP, JUMP, JUMPI, JUMPIF, HALT
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,4 @@
|
|||||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||||
</natures>
|
</natures>
|
||||||
<linkedResources>
|
|
||||||
<link>
|
|
||||||
<name>programs</name>
|
|
||||||
<type>2</type>
|
|
||||||
<location>/home/simon/Documents/Uni/CS/CSCU9A5/Triangle-Tools/programs</location>
|
|
||||||
</link>
|
|
||||||
</linkedResources>
|
|
||||||
</projectDescription>
|
</projectDescription>
|
||||||
|
|||||||
@@ -1,21 +1,12 @@
|
|||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
apply plugin: 'application'
|
apply plugin: 'application'
|
||||||
|
|
||||||
sourceCompatibility = 11
|
sourceCompatibility = 17
|
||||||
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(':Triangle.AbstractMachine')
|
implementation project(':Triangle.AbstractMachine')
|
||||||
testImplementation group: 'junit', name: 'junit', version: '4.13.2'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
application {
|
application {
|
||||||
mainClass = 'Triangle.Compiler'
|
mainClass = 'Triangle.Compiler'
|
||||||
}
|
}
|
||||||
|
|
||||||
// allow access to programs for unit tests
|
|
||||||
sourceSets.test.resources.srcDir file("$rootDir/programs")
|
|
||||||
@@ -18,7 +18,6 @@ import triangle.abstractSyntaxTrees.Program;
|
|||||||
import triangle.codeGenerator.Emitter;
|
import triangle.codeGenerator.Emitter;
|
||||||
import triangle.codeGenerator.Encoder;
|
import triangle.codeGenerator.Encoder;
|
||||||
import triangle.contextualAnalyzer.Checker;
|
import triangle.contextualAnalyzer.Checker;
|
||||||
import triangle.optimiser.ConstantFolder;
|
|
||||||
import triangle.syntacticAnalyzer.Parser;
|
import triangle.syntacticAnalyzer.Parser;
|
||||||
import triangle.syntacticAnalyzer.Scanner;
|
import triangle.syntacticAnalyzer.Scanner;
|
||||||
import triangle.syntacticAnalyzer.SourceFile;
|
import triangle.syntacticAnalyzer.SourceFile;
|
||||||
@@ -34,9 +33,6 @@ public class Compiler {
|
|||||||
|
|
||||||
/** The filename for the object program, normally obj.tam. */
|
/** The filename for the object program, normally obj.tam. */
|
||||||
static String objectName = "obj.tam";
|
static String objectName = "obj.tam";
|
||||||
|
|
||||||
static boolean showTree = false;
|
|
||||||
static boolean folding = false;
|
|
||||||
|
|
||||||
private static Scanner scanner;
|
private static Scanner scanner;
|
||||||
private static Parser parser;
|
private static Parser parser;
|
||||||
@@ -75,7 +71,7 @@ public class Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scanner = new Scanner(source);
|
scanner = new Scanner(source);
|
||||||
reporter = new ErrorReporter(false);
|
reporter = new ErrorReporter();
|
||||||
parser = new Parser(scanner, reporter);
|
parser = new Parser(scanner, reporter);
|
||||||
checker = new Checker(reporter);
|
checker = new Checker(reporter);
|
||||||
emitter = new Emitter(reporter);
|
emitter = new Emitter(reporter);
|
||||||
@@ -84,7 +80,7 @@ public class Compiler {
|
|||||||
|
|
||||||
// scanner.enableDebugging();
|
// scanner.enableDebugging();
|
||||||
theAST = parser.parseProgram(); // 1st pass
|
theAST = parser.parseProgram(); // 1st pass
|
||||||
if (reporter.getNumErrors() == 0) {
|
if (reporter.numErrors == 0) {
|
||||||
// if (showingAST) {
|
// if (showingAST) {
|
||||||
// drawer.draw(theAST);
|
// drawer.draw(theAST);
|
||||||
// }
|
// }
|
||||||
@@ -93,17 +89,13 @@ public class Compiler {
|
|||||||
if (showingAST) {
|
if (showingAST) {
|
||||||
drawer.draw(theAST);
|
drawer.draw(theAST);
|
||||||
}
|
}
|
||||||
if (folding) {
|
if (reporter.numErrors == 0) {
|
||||||
theAST.visit(new ConstantFolder());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reporter.getNumErrors() == 0) {
|
|
||||||
System.out.println("Code Generation ...");
|
System.out.println("Code Generation ...");
|
||||||
encoder.encodeRun(theAST, showingTable); // 3rd pass
|
encoder.encodeRun(theAST, showingTable); // 3rd pass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean successful = (reporter.getNumErrors() == 0);
|
boolean successful = (reporter.numErrors == 0);
|
||||||
if (successful) {
|
if (successful) {
|
||||||
emitter.saveObjectProgram(objectName);
|
emitter.saveObjectProgram(objectName);
|
||||||
System.out.println("Compilation was successful.");
|
System.out.println("Compilation was successful.");
|
||||||
@@ -122,31 +114,16 @@ public class Compiler {
|
|||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
||||||
if (args.length < 1) {
|
if (args.length < 1) {
|
||||||
System.out.println("Usage: tc filename [-o=outputfilename] [tree] [folding]");
|
System.out.println("Usage: tc filename [tree]");
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
parseArgs(args);
|
|
||||||
|
|
||||||
String sourceName = args[0];
|
String sourceName = args[0];
|
||||||
|
boolean tree = (args.length > 1 && args[1].equalsIgnoreCase("tree"));
|
||||||
var compiledOK = compileProgram(sourceName, objectName, showTree, false);
|
var compiledOK = compileProgram(sourceName, objectName, tree, false);
|
||||||
|
|
||||||
if (!showTree) {
|
if (!tree) {
|
||||||
System.exit(compiledOK ? 0 : 1);
|
System.exit(compiledOK ? 0 : 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void parseArgs(String[] args) {
|
|
||||||
for (String s : args) {
|
|
||||||
var sl = s.toLowerCase();
|
|
||||||
if (sl.equals("tree")) {
|
|
||||||
showTree = true;
|
|
||||||
} else if (sl.startsWith("-o=")) {
|
|
||||||
objectName = s.substring(3);
|
|
||||||
} else if (sl.equals("folding")) {
|
|
||||||
folding = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,44 +18,25 @@ import triangle.syntacticAnalyzer.SourcePosition;
|
|||||||
|
|
||||||
public class ErrorReporter {
|
public class ErrorReporter {
|
||||||
|
|
||||||
private int numErrors;
|
int numErrors;
|
||||||
|
|
||||||
private boolean throwExceptions;
|
|
||||||
|
|
||||||
/**
|
ErrorReporter() {
|
||||||
* @param throwExceptions if true, throw exceptions (good for unit tests) otherwise write to stdout
|
|
||||||
*/
|
|
||||||
public ErrorReporter(boolean throwExceptions) {
|
|
||||||
numErrors = 0;
|
numErrors = 0;
|
||||||
this.throwExceptions = throwExceptions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reportError(String message, String tokenName, SourcePosition pos) {
|
public void reportError(String message, String tokenName, SourcePosition pos) {
|
||||||
|
System.out.print("ERROR: ");
|
||||||
numErrors++;
|
|
||||||
|
|
||||||
String s = ("ERROR: ");
|
|
||||||
|
|
||||||
for (int p = 0; p < message.length(); p++)
|
for (int p = 0; p < message.length(); p++)
|
||||||
if (message.charAt(p) == '%')
|
if (message.charAt(p) == '%')
|
||||||
s += tokenName;
|
System.out.print(tokenName);
|
||||||
else
|
else
|
||||||
s += message.charAt(p);
|
System.out.print(message.charAt(p));
|
||||||
s += (" " + pos.start + ".." + pos.finish);
|
System.out.println(" " + pos.start + ".." + pos.finish);
|
||||||
|
numErrors++;
|
||||||
if (throwExceptions) {
|
|
||||||
throw new RuntimeException(s);
|
|
||||||
} else {
|
|
||||||
System.out.println(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reportRestriction(String message) {
|
public void reportRestriction(String message) {
|
||||||
System.out.println("RESTRICTION: " + message);
|
System.out.println("RESTRICTION: " + message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNumErrors() {
|
|
||||||
return numErrors;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,8 +42,5 @@ public final class StdEnvironment {
|
|||||||
public static ProcDeclaration getDecl, putDecl, getintDecl, putintDecl, geteolDecl, puteolDecl;
|
public static ProcDeclaration getDecl, putDecl, getintDecl, putintDecl, geteolDecl, puteolDecl;
|
||||||
|
|
||||||
public static FuncDeclaration chrDecl, ordDecl, eolDecl, eofDecl;
|
public static FuncDeclaration chrDecl, ordDecl, eolDecl, eofDecl;
|
||||||
|
|
||||||
//keep the bar separate for practical 3 (week 3) work!
|
|
||||||
public static UnaryOperatorDeclaration barDecl;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -29,5 +29,5 @@ public class ConstActualParameter extends ActualParameter {
|
|||||||
return v.visitConstActualParameter(this, arg);
|
return v.visitConstActualParameter(this, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Expression E;
|
public final Expression E;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -30,6 +30,6 @@ public class MultipleArrayAggregate extends ArrayAggregate {
|
|||||||
return v.visitMultipleArrayAggregate(this, arg);
|
return v.visitMultipleArrayAggregate(this, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Expression E;
|
public final Expression E;
|
||||||
public final ArrayAggregate AA;
|
public final ArrayAggregate AA;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -33,6 +33,6 @@ public class MultipleRecordAggregate extends RecordAggregate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final Identifier I;
|
public final Identifier I;
|
||||||
public Expression E;
|
public final Expression E;
|
||||||
public final RecordAggregate RA;
|
public final RecordAggregate RA;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -29,5 +29,5 @@ public class SingleArrayAggregate extends ArrayAggregate {
|
|||||||
return v.visitSingleArrayAggregate(this, arg);
|
return v.visitSingleArrayAggregate(this, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Expression E;
|
public final Expression E;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -32,5 +32,5 @@ public class SingleRecordAggregate extends RecordAggregate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final Identifier I;
|
public final Identifier I;
|
||||||
public Expression E;
|
public final Expression E;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -32,5 +32,5 @@ public class AssignCommand extends Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final Vname V;
|
public final Vname V;
|
||||||
public Expression E;
|
public final Expression E;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -31,6 +31,6 @@ public class IfCommand extends Command {
|
|||||||
return v.visitIfCommand(this, arg);
|
return v.visitIfCommand(this, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Expression E;
|
public final Expression E;
|
||||||
public final Command C1, C2;
|
public final Command C1, C2;
|
||||||
}
|
}
|
||||||
|
|||||||
-22
@@ -1,22 +0,0 @@
|
|||||||
package triangle.abstractSyntaxTrees.commands;
|
|
||||||
|
|
||||||
import triangle.abstractSyntaxTrees.expressions.Expression;
|
|
||||||
import triangle.abstractSyntaxTrees.visitors.CommandVisitor;
|
|
||||||
import triangle.syntacticAnalyzer.SourcePosition;
|
|
||||||
|
|
||||||
public class RepeatCommand extends Command {
|
|
||||||
|
|
||||||
public RepeatCommand(Expression eAST, Command cAST, SourcePosition position) {
|
|
||||||
super(position);
|
|
||||||
E = eAST;
|
|
||||||
C = cAST;
|
|
||||||
}
|
|
||||||
|
|
||||||
public <TArg, TResult> TResult visit(CommandVisitor<TArg, TResult> v, TArg arg) {
|
|
||||||
return v.visitRepeatCommand(this, arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
//public final Expression E;
|
|
||||||
public Expression E;
|
|
||||||
public final Command C;
|
|
||||||
}
|
|
||||||
+1
-1
@@ -30,6 +30,6 @@ public class WhileCommand extends Command {
|
|||||||
return v.visitWhileCommand(this, arg);
|
return v.visitWhileCommand(this, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Expression E;
|
public final Expression E;
|
||||||
public final Command C;
|
public final Command C;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -38,5 +38,5 @@ public class ConstDeclaration extends Declaration implements ConstantDeclaration
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final Identifier I;
|
public final Identifier I;
|
||||||
public Expression E;
|
public final Expression E;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -49,5 +49,5 @@ public class FuncDeclaration extends Declaration implements FunctionDeclaration
|
|||||||
public final Identifier I;
|
public final Identifier I;
|
||||||
public final FormalParameterSequence FPS;
|
public final FormalParameterSequence FPS;
|
||||||
public TypeDenoter T;
|
public TypeDenoter T;
|
||||||
public Expression E;
|
public final Expression E;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -31,7 +31,6 @@ public class BinaryExpression extends Expression {
|
|||||||
return v.visitBinaryExpression(this, arg);
|
return v.visitBinaryExpression(this, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Expression E1;
|
public final Expression E1, E2;
|
||||||
public Expression E2;
|
|
||||||
public final Operator O;
|
public final Operator O;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-3
@@ -30,7 +30,5 @@ public class IfExpression extends Expression {
|
|||||||
return v.visitIfExpression(this, arg);
|
return v.visitIfExpression(this, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Expression E1;
|
public final Expression E1, E2, E3;
|
||||||
public Expression E2;
|
|
||||||
public Expression E3;
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -31,5 +31,5 @@ public class LetExpression extends Expression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final Declaration D;
|
public final Declaration D;
|
||||||
public Expression E;
|
public final Expression E;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -30,6 +30,6 @@ public class UnaryExpression extends Expression {
|
|||||||
return v.visitUnaryExpression(this, arg);
|
return v.visitUnaryExpression(this, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Expression E;
|
public final Expression E;
|
||||||
public final Operator O;
|
public final Operator O;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -39,8 +39,8 @@ public class ConstFormalParameter extends FormalParameter implements ConstantDec
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object fpAST) {
|
public boolean equals(Object fpAST) {
|
||||||
if (fpAST instanceof ConstFormalParameter) {
|
if (fpAST instanceof ConstFormalParameter cfpAST) {
|
||||||
return T.equals(((ConstFormalParameter)fpAST).T);
|
return T.equals(cfpAST.T);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -39,8 +39,8 @@ public class VarFormalParameter extends FormalParameter implements VariableDecla
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object fpAST) {
|
public boolean equals(Object fpAST) {
|
||||||
if (fpAST instanceof VarFormalParameter) {
|
if (fpAST instanceof VarFormalParameter vfpAST) {
|
||||||
return T.equals(((VarFormalParameter)fpAST).T);
|
return T.equals(vfpAST.T);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-4
@@ -5,11 +5,11 @@ import triangle.abstractSyntaxTrees.commands.CallCommand;
|
|||||||
import triangle.abstractSyntaxTrees.commands.EmptyCommand;
|
import triangle.abstractSyntaxTrees.commands.EmptyCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.IfCommand;
|
import triangle.abstractSyntaxTrees.commands.IfCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.LetCommand;
|
import triangle.abstractSyntaxTrees.commands.LetCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.RepeatCommand;
|
|
||||||
import triangle.abstractSyntaxTrees.commands.SequentialCommand;
|
import triangle.abstractSyntaxTrees.commands.SequentialCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.WhileCommand;
|
import triangle.abstractSyntaxTrees.commands.WhileCommand;
|
||||||
|
|
||||||
public interface CommandVisitor<TArg, TResult> {
|
public interface CommandVisitor<TArg, TResult> {
|
||||||
|
|
||||||
TResult visitAssignCommand(AssignCommand ast, TArg arg);
|
TResult visitAssignCommand(AssignCommand ast, TArg arg);
|
||||||
|
|
||||||
TResult visitCallCommand(CallCommand ast, TArg arg);
|
TResult visitCallCommand(CallCommand ast, TArg arg);
|
||||||
@@ -23,7 +23,5 @@ public interface CommandVisitor<TArg, TResult> {
|
|||||||
TResult visitSequentialCommand(SequentialCommand ast, TArg arg);
|
TResult visitSequentialCommand(SequentialCommand ast, TArg arg);
|
||||||
|
|
||||||
TResult visitWhileCommand(WhileCommand ast, TArg arg);
|
TResult visitWhileCommand(WhileCommand ast, TArg arg);
|
||||||
|
|
||||||
TResult visitRepeatCommand(RepeatCommand ast, TArg arg);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -30,6 +30,6 @@ public class SubscriptVname extends Vname {
|
|||||||
return v.visitSubscriptVname(this, arg);
|
return v.visitSubscriptVname(this, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Expression E;
|
public final Expression E;
|
||||||
public final Vname V;
|
public final Vname V;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ import triangle.abstractSyntaxTrees.commands.CallCommand;
|
|||||||
import triangle.abstractSyntaxTrees.commands.EmptyCommand;
|
import triangle.abstractSyntaxTrees.commands.EmptyCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.IfCommand;
|
import triangle.abstractSyntaxTrees.commands.IfCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.LetCommand;
|
import triangle.abstractSyntaxTrees.commands.LetCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.RepeatCommand;
|
|
||||||
import triangle.abstractSyntaxTrees.commands.SequentialCommand;
|
import triangle.abstractSyntaxTrees.commands.SequentialCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.WhileCommand;
|
import triangle.abstractSyntaxTrees.commands.WhileCommand;
|
||||||
import triangle.abstractSyntaxTrees.declarations.BinaryOperatorDeclaration;
|
import triangle.abstractSyntaxTrees.declarations.BinaryOperatorDeclaration;
|
||||||
@@ -101,7 +100,6 @@ import triangle.abstractSyntaxTrees.vnames.SimpleVname;
|
|||||||
import triangle.abstractSyntaxTrees.vnames.SubscriptVname;
|
import triangle.abstractSyntaxTrees.vnames.SubscriptVname;
|
||||||
import triangle.abstractSyntaxTrees.vnames.Vname;
|
import triangle.abstractSyntaxTrees.vnames.Vname;
|
||||||
import triangle.codeGenerator.entities.AddressableEntity;
|
import triangle.codeGenerator.entities.AddressableEntity;
|
||||||
import triangle.codeGenerator.entities.BarPrimitiveRoutine;
|
|
||||||
import triangle.codeGenerator.entities.EqualityRoutine;
|
import triangle.codeGenerator.entities.EqualityRoutine;
|
||||||
import triangle.codeGenerator.entities.FetchableEntity;
|
import triangle.codeGenerator.entities.FetchableEntity;
|
||||||
import triangle.codeGenerator.entities.Field;
|
import triangle.codeGenerator.entities.Field;
|
||||||
@@ -182,15 +180,6 @@ public final class Encoder implements ActualParameterVisitor<Frame, Integer>,
|
|||||||
emitter.emit(OpCode.JUMPIF, Machine.trueRep, Register.CB, loopAddr);
|
emitter.emit(OpCode.JUMPIF, Machine.trueRep, Register.CB, loopAddr);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void visitRepeatCommand(RepeatCommand ast, Frame frame) {
|
|
||||||
var loopAddr = emitter.getNextInstrAddr();
|
|
||||||
ast.E.visit(this, frame);
|
|
||||||
ast.C.visit(this, frame);
|
|
||||||
emitter.emit(OpCode.JUMPIF, Machine.trueRep, Register.CB, loopAddr);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expressions
|
// Expressions
|
||||||
@Override
|
@Override
|
||||||
@@ -745,9 +734,6 @@ public final class Encoder implements ActualParameterVisitor<Frame, Integer>,
|
|||||||
elaborateStdPrimRoutine(StdEnvironment.puteolDecl, Primitive.PUTEOL);
|
elaborateStdPrimRoutine(StdEnvironment.puteolDecl, Primitive.PUTEOL);
|
||||||
elaborateStdEqRoutine(StdEnvironment.equalDecl, Primitive.EQ);
|
elaborateStdEqRoutine(StdEnvironment.equalDecl, Primitive.EQ);
|
||||||
elaborateStdEqRoutine(StdEnvironment.unequalDecl, Primitive.NE);
|
elaborateStdEqRoutine(StdEnvironment.unequalDecl, Primitive.NE);
|
||||||
|
|
||||||
StdEnvironment.barDecl.entity = new BarPrimitiveRoutine();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean tableDetailsReqd;
|
boolean tableDetailsReqd;
|
||||||
@@ -755,9 +741,10 @@ public final class Encoder implements ActualParameterVisitor<Frame, Integer>,
|
|||||||
public static void writeTableDetails(AbstractSyntaxTree ast) {
|
public static void writeTableDetails(AbstractSyntaxTree ast) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generates code to pop the top off the stack
|
// Generates code to fetch the value of a named constant or variable
|
||||||
// and store the value in a named constant or variable
|
// and push it on to the stack.
|
||||||
// frame the local stack frame when
|
// currentLevel is the routine level where the vname occurs.
|
||||||
|
// frameSize is the anticipated size of the local stack frame when
|
||||||
// the constant or variable is fetched at run-time.
|
// the constant or variable is fetched at run-time.
|
||||||
// valSize is the size of the constant or variable's value.
|
// valSize is the size of the constant or variable's value.
|
||||||
|
|
||||||
|
|||||||
-27
@@ -1,27 +0,0 @@
|
|||||||
package triangle.codeGenerator.entities;
|
|
||||||
|
|
||||||
import triangle.abstractMachine.Machine;
|
|
||||||
import triangle.abstractMachine.OpCode;
|
|
||||||
import triangle.abstractMachine.Primitive;
|
|
||||||
import triangle.abstractMachine.Register;
|
|
||||||
import triangle.codeGenerator.Emitter;
|
|
||||||
import triangle.codeGenerator.Frame;
|
|
||||||
|
|
||||||
public class BarPrimitiveRoutine extends RuntimeEntity implements RoutineEntity {
|
|
||||||
|
|
||||||
public BarPrimitiveRoutine() {
|
|
||||||
super(Machine.closureSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void encodeCall(Emitter emitter, Frame frame) {
|
|
||||||
//push the literal value of 100 onto the stack
|
|
||||||
emitter.emit(OpCode.LOADL, 0, 100);
|
|
||||||
emitter.emit(OpCode.CALL, Register.PB, Primitive.MULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void encodeFetch(Emitter emitter, Frame frame) {
|
|
||||||
emitter.emit(OpCode.LOADA, 0, Register.SB, 0);
|
|
||||||
emitter.emit(OpCode.LOADA, Register.PB, Primitive.MULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -34,7 +34,6 @@ import triangle.abstractSyntaxTrees.commands.CallCommand;
|
|||||||
import triangle.abstractSyntaxTrees.commands.EmptyCommand;
|
import triangle.abstractSyntaxTrees.commands.EmptyCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.IfCommand;
|
import triangle.abstractSyntaxTrees.commands.IfCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.LetCommand;
|
import triangle.abstractSyntaxTrees.commands.LetCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.RepeatCommand;
|
|
||||||
import triangle.abstractSyntaxTrees.commands.SequentialCommand;
|
import triangle.abstractSyntaxTrees.commands.SequentialCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.WhileCommand;
|
import triangle.abstractSyntaxTrees.commands.WhileCommand;
|
||||||
import triangle.abstractSyntaxTrees.declarations.BinaryOperatorDeclaration;
|
import triangle.abstractSyntaxTrees.declarations.BinaryOperatorDeclaration;
|
||||||
@@ -133,8 +132,7 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|||||||
public Void visitCallCommand(CallCommand ast, Void arg) {
|
public Void visitCallCommand(CallCommand ast, Void arg) {
|
||||||
var binding = ast.I.visit(this);
|
var binding = ast.I.visit(this);
|
||||||
|
|
||||||
if (binding instanceof ProcedureDeclaration) {
|
if (binding instanceof ProcedureDeclaration procedure) {
|
||||||
ProcedureDeclaration procedure = (ProcedureDeclaration)binding;
|
|
||||||
ast.APS.visit(this, procedure.getFormals());
|
ast.APS.visit(this, procedure.getFormals());
|
||||||
} else {
|
} else {
|
||||||
reportUndeclaredOrError(binding, ast.I, "\"%\" is not a procedure identifier");
|
reportUndeclaredOrError(binding, ast.I, "\"%\" is not a procedure identifier");
|
||||||
@@ -185,15 +183,6 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void visitRepeatCommand(RepeatCommand ast, Void arg) {
|
|
||||||
var eType = ast.E.visit(this);
|
|
||||||
|
|
||||||
checkAndReportError(eType.equals(StdEnvironment.booleanType), "Boolean expression expected here", ast.E);
|
|
||||||
ast.C.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expressions
|
// Expressions
|
||||||
|
|
||||||
@@ -214,8 +203,7 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|||||||
var e2Type = ast.E2.visit(this);
|
var e2Type = ast.E2.visit(this);
|
||||||
var binding = ast.O.visit(this);
|
var binding = ast.O.visit(this);
|
||||||
|
|
||||||
if (binding instanceof BinaryOperatorDeclaration) {
|
if (binding instanceof BinaryOperatorDeclaration bbinding) {
|
||||||
BinaryOperatorDeclaration bbinding = (BinaryOperatorDeclaration)binding;
|
|
||||||
if (bbinding.ARG1 == StdEnvironment.anyType) {
|
if (bbinding.ARG1 == StdEnvironment.anyType) {
|
||||||
// this operator must be "=" or "\="
|
// this operator must be "=" or "\="
|
||||||
checkAndReportError(e1Type.equals(e2Type), "incompatible argument types for \"%\"", ast.O, ast);
|
checkAndReportError(e1Type.equals(e2Type), "incompatible argument types for \"%\"", ast.O, ast);
|
||||||
@@ -234,8 +222,7 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|||||||
public TypeDenoter visitCallExpression(CallExpression ast, Void arg) {
|
public TypeDenoter visitCallExpression(CallExpression ast, Void arg) {
|
||||||
var binding = ast.I.visit(this);
|
var binding = ast.I.visit(this);
|
||||||
|
|
||||||
if (binding instanceof FunctionDeclaration) {
|
if (binding instanceof FunctionDeclaration function) {
|
||||||
FunctionDeclaration function = (FunctionDeclaration)binding;
|
|
||||||
ast.APS.visit(this, function.getFormals());
|
ast.APS.visit(this, function.getFormals());
|
||||||
return ast.type = function.getType();
|
return ast.type = function.getType();
|
||||||
}
|
}
|
||||||
@@ -290,8 +277,7 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|||||||
var eType = ast.E.visit(this);
|
var eType = ast.E.visit(this);
|
||||||
var binding = ast.O.visit(this);
|
var binding = ast.O.visit(this);
|
||||||
|
|
||||||
if (binding instanceof UnaryOperatorDeclaration) {
|
if (binding instanceof UnaryOperatorDeclaration ubinding) {
|
||||||
UnaryOperatorDeclaration ubinding = (UnaryOperatorDeclaration)binding;
|
|
||||||
checkAndReportError(eType.equals(ubinding.ARG), "wrong argument type for \"%\"", ast.O);
|
checkAndReportError(eType.equals(ubinding.ARG), "wrong argument type for \"%\"", ast.O);
|
||||||
return ast.type = ubinding.RES;
|
return ast.type = ubinding.RES;
|
||||||
}
|
}
|
||||||
@@ -486,9 +472,8 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|||||||
@Override
|
@Override
|
||||||
public Void visitConstActualParameter(ConstActualParameter ast, FormalParameter arg) {
|
public Void visitConstActualParameter(ConstActualParameter ast, FormalParameter arg) {
|
||||||
var eType = ast.E.visit(this);
|
var eType = ast.E.visit(this);
|
||||||
if (arg instanceof ConstFormalParameter) {
|
if (arg instanceof ConstFormalParameter param) {
|
||||||
ConstFormalParameter param = (ConstFormalParameter)arg;
|
checkAndReportError(eType.equals(param.T), "wrong type for const actual parameter", ast.E);
|
||||||
checkAndReportError(eType.equals(((ConstFormalParameter)arg).T), "wrong type for const actual parameter", ast.E);
|
|
||||||
} else {
|
} else {
|
||||||
reportError("const actual parameter not expected here", ast);
|
reportError("const actual parameter not expected here", ast);
|
||||||
}
|
}
|
||||||
@@ -498,12 +483,10 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|||||||
@Override
|
@Override
|
||||||
public Void visitFuncActualParameter(FuncActualParameter ast, FormalParameter arg) {
|
public Void visitFuncActualParameter(FuncActualParameter ast, FormalParameter arg) {
|
||||||
var binding = ast.I.visit(this);
|
var binding = ast.I.visit(this);
|
||||||
if (binding instanceof FunctionDeclaration) {
|
if (binding instanceof FunctionDeclaration function) {
|
||||||
FunctionDeclaration function = (FunctionDeclaration)binding;
|
|
||||||
var formals = function.getFormals();
|
var formals = function.getFormals();
|
||||||
var functionType = function.getType();
|
var functionType = function.getType();
|
||||||
if (arg instanceof FuncFormalParameter) {
|
if (arg instanceof FuncFormalParameter param) {
|
||||||
FuncFormalParameter param = (FuncFormalParameter)arg;
|
|
||||||
if (!formals.equals(param.getFormals())) {
|
if (!formals.equals(param.getFormals())) {
|
||||||
reportError("wrong signature for function \"%\"", ast.I);
|
reportError("wrong signature for function \"%\"", ast.I);
|
||||||
} else if (!functionType.equals(param.T)) {
|
} else if (!functionType.equals(param.T)) {
|
||||||
@@ -521,11 +504,9 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|||||||
@Override
|
@Override
|
||||||
public Void visitProcActualParameter(ProcActualParameter ast, FormalParameter arg) {
|
public Void visitProcActualParameter(ProcActualParameter ast, FormalParameter arg) {
|
||||||
var binding = ast.I.visit(this);
|
var binding = ast.I.visit(this);
|
||||||
if (binding instanceof ProcedureDeclaration) {
|
if (binding instanceof ProcedureDeclaration procedure) {
|
||||||
ProcedureDeclaration procedure = (ProcedureDeclaration)binding;
|
|
||||||
var formals = procedure.getFormals();
|
var formals = procedure.getFormals();
|
||||||
if (arg instanceof ProcFormalParameter) {
|
if (arg instanceof ProcFormalParameter param) {
|
||||||
ProcFormalParameter param = (ProcFormalParameter)arg;
|
|
||||||
checkAndReportError(formals.equals(param.getFormals()), "wrong signature for procedure \"%\"", ast.I);
|
checkAndReportError(formals.equals(param.getFormals()), "wrong signature for procedure \"%\"", ast.I);
|
||||||
} else {
|
} else {
|
||||||
reportError("proc actual parameter not expected here", ast);
|
reportError("proc actual parameter not expected here", ast);
|
||||||
@@ -541,8 +522,7 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|||||||
var vType = ast.V.visit(this);
|
var vType = ast.V.visit(this);
|
||||||
if (!ast.V.variable) {
|
if (!ast.V.variable) {
|
||||||
reportError("actual parameter is not a variable", ast.V);
|
reportError("actual parameter is not a variable", ast.V);
|
||||||
} else if (arg instanceof VarFormalParameter) {
|
} else if (arg instanceof VarFormalParameter parameter) {
|
||||||
VarFormalParameter parameter = (VarFormalParameter)arg;
|
|
||||||
checkAndReportError(vType.equals(parameter.T), "wrong type for var actual parameter", ast.V);
|
checkAndReportError(vType.equals(parameter.T), "wrong type for var actual parameter", ast.V);
|
||||||
} else {
|
} else {
|
||||||
reportError("var actual parameter not expected here", ast.V);
|
reportError("var actual parameter not expected here", ast.V);
|
||||||
@@ -558,8 +538,7 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, FormalParameterSequence arg) {
|
public Void visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, FormalParameterSequence arg) {
|
||||||
if (arg instanceof MultipleFormalParameterSequence) {
|
if (arg instanceof MultipleFormalParameterSequence formals) {
|
||||||
MultipleFormalParameterSequence formals = (MultipleFormalParameterSequence)arg;
|
|
||||||
ast.AP.visit(this, formals.FP);
|
ast.AP.visit(this, formals.FP);
|
||||||
ast.APS.visit(this, formals.FPS);
|
ast.APS.visit(this, formals.FPS);
|
||||||
} else {
|
} else {
|
||||||
@@ -570,8 +549,7 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visitSingleActualParameterSequence(SingleActualParameterSequence ast, FormalParameterSequence arg) {
|
public Void visitSingleActualParameterSequence(SingleActualParameterSequence ast, FormalParameterSequence arg) {
|
||||||
if (arg instanceof SingleFormalParameterSequence) {
|
if (arg instanceof SingleFormalParameterSequence formal) {
|
||||||
SingleFormalParameterSequence formal = (SingleFormalParameterSequence)arg;
|
|
||||||
ast.AP.visit(this, formal.FP);
|
ast.AP.visit(this, formal.FP);
|
||||||
} else {
|
} else {
|
||||||
reportError("incorrect number of actual parameters", ast);
|
reportError("incorrect number of actual parameters", ast);
|
||||||
@@ -614,8 +592,7 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|||||||
@Override
|
@Override
|
||||||
public TypeDenoter visitSimpleTypeDenoter(SimpleTypeDenoter ast, Void arg) {
|
public TypeDenoter visitSimpleTypeDenoter(SimpleTypeDenoter ast, Void arg) {
|
||||||
var binding = ast.I.visit(this);
|
var binding = ast.I.visit(this);
|
||||||
if (binding instanceof TypeDeclaration) {
|
if (binding instanceof TypeDeclaration decl) {
|
||||||
TypeDeclaration decl = (TypeDeclaration)binding;
|
|
||||||
return decl.T;
|
return decl.T;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -702,8 +679,7 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|||||||
ast.type = null;
|
ast.type = null;
|
||||||
var vType = ast.V.visit(this);
|
var vType = ast.V.visit(this);
|
||||||
ast.variable = ast.V.variable;
|
ast.variable = ast.V.variable;
|
||||||
if (vType instanceof RecordTypeDenoter) {
|
if (vType instanceof RecordTypeDenoter record) {
|
||||||
RecordTypeDenoter record = (RecordTypeDenoter)vType;
|
|
||||||
ast.type = checkFieldIdentifier(record.FT, ast.I);
|
ast.type = checkFieldIdentifier(record.FT, ast.I);
|
||||||
checkAndReportError(ast.type != StdEnvironment.errorType, "no field \"%\" in this record type",
|
checkAndReportError(ast.type != StdEnvironment.errorType, "no field \"%\" in this record type",
|
||||||
ast.I);
|
ast.I);
|
||||||
@@ -719,12 +695,10 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|||||||
ast.type = StdEnvironment.errorType;
|
ast.type = StdEnvironment.errorType;
|
||||||
|
|
||||||
var binding = ast.I.visit(this);
|
var binding = ast.I.visit(this);
|
||||||
if (binding instanceof ConstantDeclaration) {
|
if (binding instanceof ConstantDeclaration constant) {
|
||||||
ConstantDeclaration constant = (ConstantDeclaration)binding;
|
|
||||||
ast.variable = false;
|
ast.variable = false;
|
||||||
return ast.type = constant.getType();
|
return ast.type = constant.getType();
|
||||||
} else if (binding instanceof VariableDeclaration) {
|
} else if (binding instanceof VariableDeclaration variable) {
|
||||||
VariableDeclaration variable = (VariableDeclaration)binding;
|
|
||||||
ast.variable = true;
|
ast.variable = true;
|
||||||
return ast.type = variable.getType();
|
return ast.type = variable.getType();
|
||||||
}
|
}
|
||||||
@@ -740,8 +714,7 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|||||||
|
|
||||||
var eType = ast.E.visit(this);
|
var eType = ast.E.visit(this);
|
||||||
if (vType != StdEnvironment.errorType) {
|
if (vType != StdEnvironment.errorType) {
|
||||||
if (vType instanceof ArrayTypeDenoter) {
|
if (vType instanceof ArrayTypeDenoter arrayType) {
|
||||||
ArrayTypeDenoter arrayType = (ArrayTypeDenoter)vType;
|
|
||||||
checkAndReportError(eType.equals(StdEnvironment.integerType), "Integer expression expected here",
|
checkAndReportError(eType.equals(StdEnvironment.integerType), "Integer expression expected here",
|
||||||
ast.E);
|
ast.E);
|
||||||
ast.type = arrayType.T;
|
ast.type = arrayType.T;
|
||||||
@@ -826,16 +799,14 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static TypeDenoter checkFieldIdentifier(FieldTypeDenoter ast, Identifier I) {
|
private static TypeDenoter checkFieldIdentifier(FieldTypeDenoter ast, Identifier I) {
|
||||||
if (ast instanceof MultipleFieldTypeDenoter) {
|
if (ast instanceof MultipleFieldTypeDenoter ft) {
|
||||||
MultipleFieldTypeDenoter ft = (MultipleFieldTypeDenoter)ast;
|
|
||||||
if (ft.I.spelling.compareTo(I.spelling) == 0) {
|
if (ft.I.spelling.compareTo(I.spelling) == 0) {
|
||||||
I.decl = ast;
|
I.decl = ast;
|
||||||
return ft.T;
|
return ft.T;
|
||||||
} else {
|
} else {
|
||||||
return checkFieldIdentifier(ft.FT, I);
|
return checkFieldIdentifier(ft.FT, I);
|
||||||
}
|
}
|
||||||
} else if (ast instanceof SingleFieldTypeDenoter) {
|
} else if (ast instanceof SingleFieldTypeDenoter ft) {
|
||||||
SingleFieldTypeDenoter ft = (SingleFieldTypeDenoter)ast;
|
|
||||||
if (ft.I.spelling.compareTo(I.spelling) == 0) {
|
if (ft.I.spelling.compareTo(I.spelling) == 0) {
|
||||||
I.decl = ast;
|
I.decl = ast;
|
||||||
return ft.T;
|
return ft.T;
|
||||||
@@ -957,11 +928,7 @@ public final class Checker implements ActualParameterVisitor<FormalParameter, Vo
|
|||||||
StdEnvironment.booleanType);
|
StdEnvironment.booleanType);
|
||||||
StdEnvironment.notlessDecl = declareStdBinaryOp(">=", StdEnvironment.integerType, StdEnvironment.integerType,
|
StdEnvironment.notlessDecl = declareStdBinaryOp(">=", StdEnvironment.integerType, StdEnvironment.integerType,
|
||||||
StdEnvironment.booleanType);
|
StdEnvironment.booleanType);
|
||||||
|
|
||||||
//add the new bar operator!
|
|
||||||
StdEnvironment.barDecl = declareStdUnaryOp("|", StdEnvironment.integerType, StdEnvironment.integerType);
|
|
||||||
|
|
||||||
|
|
||||||
StdEnvironment.charDecl = declareStdType("Char", StdEnvironment.charType);
|
StdEnvironment.charDecl = declareStdType("Char", StdEnvironment.charType);
|
||||||
StdEnvironment.chrDecl = declareStdFunc("chr",
|
StdEnvironment.chrDecl = declareStdFunc("chr",
|
||||||
new SingleFormalParameterSequence(
|
new SingleFormalParameterSequence(
|
||||||
|
|||||||
@@ -1,601 +0,0 @@
|
|||||||
package triangle.optimiser;
|
|
||||||
|
|
||||||
import triangle.StdEnvironment;
|
|
||||||
import triangle.abstractSyntaxTrees.AbstractSyntaxTree;
|
|
||||||
import triangle.abstractSyntaxTrees.Program;
|
|
||||||
import triangle.abstractSyntaxTrees.actuals.ConstActualParameter;
|
|
||||||
import triangle.abstractSyntaxTrees.actuals.EmptyActualParameterSequence;
|
|
||||||
import triangle.abstractSyntaxTrees.actuals.FuncActualParameter;
|
|
||||||
import triangle.abstractSyntaxTrees.actuals.MultipleActualParameterSequence;
|
|
||||||
import triangle.abstractSyntaxTrees.actuals.ProcActualParameter;
|
|
||||||
import triangle.abstractSyntaxTrees.actuals.SingleActualParameterSequence;
|
|
||||||
import triangle.abstractSyntaxTrees.actuals.VarActualParameter;
|
|
||||||
import triangle.abstractSyntaxTrees.aggregates.MultipleArrayAggregate;
|
|
||||||
import triangle.abstractSyntaxTrees.aggregates.MultipleRecordAggregate;
|
|
||||||
import triangle.abstractSyntaxTrees.aggregates.SingleArrayAggregate;
|
|
||||||
import triangle.abstractSyntaxTrees.aggregates.SingleRecordAggregate;
|
|
||||||
import triangle.abstractSyntaxTrees.commands.AssignCommand;
|
|
||||||
import triangle.abstractSyntaxTrees.commands.CallCommand;
|
|
||||||
import triangle.abstractSyntaxTrees.commands.EmptyCommand;
|
|
||||||
import triangle.abstractSyntaxTrees.commands.IfCommand;
|
|
||||||
import triangle.abstractSyntaxTrees.commands.LetCommand;
|
|
||||||
import triangle.abstractSyntaxTrees.commands.RepeatCommand;
|
|
||||||
import triangle.abstractSyntaxTrees.commands.SequentialCommand;
|
|
||||||
import triangle.abstractSyntaxTrees.commands.WhileCommand;
|
|
||||||
import triangle.abstractSyntaxTrees.declarations.BinaryOperatorDeclaration;
|
|
||||||
import triangle.abstractSyntaxTrees.declarations.ConstDeclaration;
|
|
||||||
import triangle.abstractSyntaxTrees.declarations.FuncDeclaration;
|
|
||||||
import triangle.abstractSyntaxTrees.declarations.ProcDeclaration;
|
|
||||||
import triangle.abstractSyntaxTrees.declarations.SequentialDeclaration;
|
|
||||||
import triangle.abstractSyntaxTrees.declarations.UnaryOperatorDeclaration;
|
|
||||||
import triangle.abstractSyntaxTrees.declarations.VarDeclaration;
|
|
||||||
import triangle.abstractSyntaxTrees.expressions.ArrayExpression;
|
|
||||||
import triangle.abstractSyntaxTrees.expressions.BinaryExpression;
|
|
||||||
import triangle.abstractSyntaxTrees.expressions.CallExpression;
|
|
||||||
import triangle.abstractSyntaxTrees.expressions.CharacterExpression;
|
|
||||||
import triangle.abstractSyntaxTrees.expressions.EmptyExpression;
|
|
||||||
import triangle.abstractSyntaxTrees.expressions.Expression;
|
|
||||||
import triangle.abstractSyntaxTrees.expressions.IfExpression;
|
|
||||||
import triangle.abstractSyntaxTrees.expressions.IntegerExpression;
|
|
||||||
import triangle.abstractSyntaxTrees.expressions.LetExpression;
|
|
||||||
import triangle.abstractSyntaxTrees.expressions.RecordExpression;
|
|
||||||
import triangle.abstractSyntaxTrees.expressions.UnaryExpression;
|
|
||||||
import triangle.abstractSyntaxTrees.expressions.VnameExpression;
|
|
||||||
import triangle.abstractSyntaxTrees.formals.ConstFormalParameter;
|
|
||||||
import triangle.abstractSyntaxTrees.formals.EmptyFormalParameterSequence;
|
|
||||||
import triangle.abstractSyntaxTrees.formals.FuncFormalParameter;
|
|
||||||
import triangle.abstractSyntaxTrees.formals.MultipleFormalParameterSequence;
|
|
||||||
import triangle.abstractSyntaxTrees.formals.ProcFormalParameter;
|
|
||||||
import triangle.abstractSyntaxTrees.formals.SingleFormalParameterSequence;
|
|
||||||
import triangle.abstractSyntaxTrees.formals.VarFormalParameter;
|
|
||||||
import triangle.abstractSyntaxTrees.terminals.CharacterLiteral;
|
|
||||||
import triangle.abstractSyntaxTrees.terminals.Identifier;
|
|
||||||
import triangle.abstractSyntaxTrees.terminals.IntegerLiteral;
|
|
||||||
import triangle.abstractSyntaxTrees.terminals.Operator;
|
|
||||||
import triangle.abstractSyntaxTrees.types.AnyTypeDenoter;
|
|
||||||
import triangle.abstractSyntaxTrees.types.ArrayTypeDenoter;
|
|
||||||
import triangle.abstractSyntaxTrees.types.BoolTypeDenoter;
|
|
||||||
import triangle.abstractSyntaxTrees.types.CharTypeDenoter;
|
|
||||||
import triangle.abstractSyntaxTrees.types.ErrorTypeDenoter;
|
|
||||||
import triangle.abstractSyntaxTrees.types.IntTypeDenoter;
|
|
||||||
import triangle.abstractSyntaxTrees.types.MultipleFieldTypeDenoter;
|
|
||||||
import triangle.abstractSyntaxTrees.types.RecordTypeDenoter;
|
|
||||||
import triangle.abstractSyntaxTrees.types.SimpleTypeDenoter;
|
|
||||||
import triangle.abstractSyntaxTrees.types.SingleFieldTypeDenoter;
|
|
||||||
import triangle.abstractSyntaxTrees.types.TypeDeclaration;
|
|
||||||
import triangle.abstractSyntaxTrees.visitors.ActualParameterSequenceVisitor;
|
|
||||||
import triangle.abstractSyntaxTrees.visitors.ActualParameterVisitor;
|
|
||||||
import triangle.abstractSyntaxTrees.visitors.ArrayAggregateVisitor;
|
|
||||||
import triangle.abstractSyntaxTrees.visitors.CommandVisitor;
|
|
||||||
import triangle.abstractSyntaxTrees.visitors.DeclarationVisitor;
|
|
||||||
import triangle.abstractSyntaxTrees.visitors.ExpressionVisitor;
|
|
||||||
import triangle.abstractSyntaxTrees.visitors.FormalParameterSequenceVisitor;
|
|
||||||
import triangle.abstractSyntaxTrees.visitors.IdentifierVisitor;
|
|
||||||
import triangle.abstractSyntaxTrees.visitors.LiteralVisitor;
|
|
||||||
import triangle.abstractSyntaxTrees.visitors.OperatorVisitor;
|
|
||||||
import triangle.abstractSyntaxTrees.visitors.ProgramVisitor;
|
|
||||||
import triangle.abstractSyntaxTrees.visitors.RecordAggregateVisitor;
|
|
||||||
import triangle.abstractSyntaxTrees.visitors.TypeDenoterVisitor;
|
|
||||||
import triangle.abstractSyntaxTrees.visitors.VnameVisitor;
|
|
||||||
import triangle.abstractSyntaxTrees.vnames.DotVname;
|
|
||||||
import triangle.abstractSyntaxTrees.vnames.SimpleVname;
|
|
||||||
import triangle.abstractSyntaxTrees.vnames.SubscriptVname;
|
|
||||||
import triangle.codeGenerator.entities.RuntimeEntity;
|
|
||||||
|
|
||||||
public class ConstantFolder implements ActualParameterVisitor<Void, AbstractSyntaxTree>,
|
|
||||||
ActualParameterSequenceVisitor<Void, AbstractSyntaxTree>, ArrayAggregateVisitor<Void, AbstractSyntaxTree>,
|
|
||||||
CommandVisitor<Void, AbstractSyntaxTree>, DeclarationVisitor<Void, AbstractSyntaxTree>,
|
|
||||||
ExpressionVisitor<Void, AbstractSyntaxTree>, FormalParameterSequenceVisitor<Void, AbstractSyntaxTree>,
|
|
||||||
IdentifierVisitor<Void, AbstractSyntaxTree>, LiteralVisitor<Void, AbstractSyntaxTree>,
|
|
||||||
OperatorVisitor<Void, AbstractSyntaxTree>, ProgramVisitor<Void, AbstractSyntaxTree>,
|
|
||||||
RecordAggregateVisitor<Void, AbstractSyntaxTree>, TypeDenoterVisitor<Void, AbstractSyntaxTree>,
|
|
||||||
VnameVisitor<Void, RuntimeEntity> {
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitConstFormalParameter(ConstFormalParameter ast, Void arg) {
|
|
||||||
ast.I.visit(this);
|
|
||||||
ast.T.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitFuncFormalParameter(FuncFormalParameter ast, Void arg) {
|
|
||||||
ast.I.visit(this);
|
|
||||||
ast.T.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitProcFormalParameter(ProcFormalParameter ast, Void arg) {
|
|
||||||
ast.I.visit(this);
|
|
||||||
ast.FPS.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitVarFormalParameter(VarFormalParameter ast, Void arg) {
|
|
||||||
ast.I.visit(this);
|
|
||||||
ast.T.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, Void arg) {
|
|
||||||
ast.FT.visit(this);
|
|
||||||
ast.I.visit(this);
|
|
||||||
ast.T.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitSingleFieldTypeDenoter(SingleFieldTypeDenoter ast, Void arg) {
|
|
||||||
ast.I.visit(this);
|
|
||||||
ast.T.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RuntimeEntity visitDotVname(DotVname ast, Void arg) {
|
|
||||||
ast.I.visit(this);
|
|
||||||
ast.V.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RuntimeEntity visitSimpleVname(SimpleVname ast, Void arg) {
|
|
||||||
ast.I.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RuntimeEntity visitSubscriptVname(SubscriptVname ast, Void arg) {
|
|
||||||
AbstractSyntaxTree replacement = ast.E.visit(this);
|
|
||||||
if (replacement != null) {
|
|
||||||
ast.E = (Expression) replacement;
|
|
||||||
}
|
|
||||||
ast.V.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitAnyTypeDenoter(AnyTypeDenoter ast, Void arg) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitArrayTypeDenoter(ArrayTypeDenoter ast, Void arg) {
|
|
||||||
ast.IL.visit(this);
|
|
||||||
ast.T.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitBoolTypeDenoter(BoolTypeDenoter ast, Void arg) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitCharTypeDenoter(CharTypeDenoter ast, Void arg) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitErrorTypeDenoter(ErrorTypeDenoter ast, Void arg) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitSimpleTypeDenoter(SimpleTypeDenoter ast, Void arg) {
|
|
||||||
ast.I.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitIntTypeDenoter(IntTypeDenoter ast, Void arg) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitRecordTypeDenoter(RecordTypeDenoter ast, Void arg) {
|
|
||||||
ast.FT.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitMultipleRecordAggregate(MultipleRecordAggregate ast, Void arg) {
|
|
||||||
AbstractSyntaxTree replacement = ast.E.visit(this);
|
|
||||||
if (replacement != null) {
|
|
||||||
ast.E = (Expression) replacement;
|
|
||||||
}
|
|
||||||
ast.I.visit(this);
|
|
||||||
ast.RA.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitSingleRecordAggregate(SingleRecordAggregate ast, Void arg) {
|
|
||||||
AbstractSyntaxTree replacement = ast.E.visit(this);
|
|
||||||
if (replacement != null) {
|
|
||||||
ast.E = (Expression) replacement;
|
|
||||||
}
|
|
||||||
ast.I.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitProgram(Program ast, Void arg) {
|
|
||||||
ast.C.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitOperator(Operator ast, Void arg) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitCharacterLiteral(CharacterLiteral ast, Void arg) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitIntegerLiteral(IntegerLiteral ast, Void arg) {
|
|
||||||
return ast;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitIdentifier(Identifier ast, Void arg) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Void arg) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitMultipleFormalParameterSequence(MultipleFormalParameterSequence ast, Void arg) {
|
|
||||||
ast.FP.visit(this);
|
|
||||||
ast.FPS.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitSingleFormalParameterSequence(SingleFormalParameterSequence ast, Void arg) {
|
|
||||||
ast.FP.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitArrayExpression(ArrayExpression ast, Void arg) {
|
|
||||||
ast.AA.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitBinaryExpression(BinaryExpression ast, Void arg) {
|
|
||||||
AbstractSyntaxTree replacement1 = ast.E1.visit(this);
|
|
||||||
AbstractSyntaxTree replacement2 = ast.E2.visit(this);
|
|
||||||
ast.O.visit(this);
|
|
||||||
|
|
||||||
// if visiting a child node returns something, it's either the original constant
|
|
||||||
// (IntegerLiteral) or a folded version replacing the expression at that child
|
|
||||||
// node
|
|
||||||
// If both child nodes are not null; return a folded version of this
|
|
||||||
// BinaryExpression
|
|
||||||
// Otherwise, at least one child node isn't constant (foldable) so just replace
|
|
||||||
// the
|
|
||||||
// foldable child nodes with their folded equivalent and return null
|
|
||||||
if (replacement1 != null && replacement2 != null) {
|
|
||||||
return foldBinaryExpression(replacement1, replacement2, ast.O);
|
|
||||||
} else if (replacement1 != null) {
|
|
||||||
ast.E1 = (Expression) replacement1;
|
|
||||||
} else if (replacement2 != null) {
|
|
||||||
ast.E2 = (Expression) replacement2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we get here, we can't fold any higher than this level
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitCallExpression(CallExpression ast, Void arg) {
|
|
||||||
ast.APS.visit(this);
|
|
||||||
ast.I.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitCharacterExpression(CharacterExpression ast, Void arg) {
|
|
||||||
ast.CL.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitEmptyExpression(EmptyExpression ast, Void arg) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitIfExpression(IfExpression ast, Void arg) {
|
|
||||||
AbstractSyntaxTree replacement1 = ast.E1.visit(this);
|
|
||||||
if (replacement1 != null) {
|
|
||||||
ast.E1 = (Expression) replacement1;
|
|
||||||
}
|
|
||||||
AbstractSyntaxTree replacement2 = ast.E2.visit(this);
|
|
||||||
if (replacement2 != null) {
|
|
||||||
ast.E2 = (Expression) replacement2;
|
|
||||||
}
|
|
||||||
AbstractSyntaxTree replacement3 = ast.E3.visit(this);
|
|
||||||
if (replacement3 != null) {
|
|
||||||
ast.E3 = (Expression) replacement3;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitIntegerExpression(IntegerExpression ast, Void arg) {
|
|
||||||
return ast;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitLetExpression(LetExpression ast, Void arg) {
|
|
||||||
ast.D.visit(this);
|
|
||||||
AbstractSyntaxTree replacement = ast.E.visit(this);
|
|
||||||
if (replacement != null) {
|
|
||||||
ast.E = (Expression) replacement;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitRecordExpression(RecordExpression ast, Void arg) {
|
|
||||||
ast.RA.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitUnaryExpression(UnaryExpression ast, Void arg) {
|
|
||||||
AbstractSyntaxTree replacement = ast.E.visit(this);
|
|
||||||
if (replacement != null) {
|
|
||||||
ast.E = (Expression) replacement;
|
|
||||||
}
|
|
||||||
|
|
||||||
ast.O.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitVnameExpression(VnameExpression ast, Void arg) {
|
|
||||||
ast.V.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Void arg) {
|
|
||||||
ast.ARG1.visit(this);
|
|
||||||
ast.ARG2.visit(this);
|
|
||||||
ast.O.visit(this);
|
|
||||||
ast.RES.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitConstDeclaration(ConstDeclaration ast, Void arg) {
|
|
||||||
AbstractSyntaxTree replacement = ast.E.visit(this);
|
|
||||||
if (replacement != null) {
|
|
||||||
ast.E = (Expression) replacement;
|
|
||||||
}
|
|
||||||
ast.I.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitFuncDeclaration(FuncDeclaration ast, Void arg) {
|
|
||||||
AbstractSyntaxTree replacement = ast.E.visit(this);
|
|
||||||
if (replacement != null) {
|
|
||||||
ast.E = (Expression) replacement;
|
|
||||||
}
|
|
||||||
ast.FPS.visit(this);
|
|
||||||
ast.I.visit(this);
|
|
||||||
ast.T.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitProcDeclaration(ProcDeclaration ast, Void arg) {
|
|
||||||
ast.C.visit(this);
|
|
||||||
ast.FPS.visit(this);
|
|
||||||
ast.I.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitSequentialDeclaration(SequentialDeclaration ast, Void arg) {
|
|
||||||
ast.D1.visit(this);
|
|
||||||
ast.D2.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitTypeDeclaration(TypeDeclaration ast, Void arg) {
|
|
||||||
ast.I.visit(this);
|
|
||||||
ast.T.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Void arg) {
|
|
||||||
ast.ARG.visit(this);
|
|
||||||
ast.O.visit(this);
|
|
||||||
ast.RES.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitVarDeclaration(VarDeclaration ast, Void arg) {
|
|
||||||
ast.I.visit(this);
|
|
||||||
ast.T.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitAssignCommand(AssignCommand ast, Void arg) {
|
|
||||||
AbstractSyntaxTree replacement = ast.E.visit(this);
|
|
||||||
if (replacement != null) {
|
|
||||||
ast.E = (Expression) replacement;
|
|
||||||
}
|
|
||||||
ast.V.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitCallCommand(CallCommand ast, Void arg) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitEmptyCommand(EmptyCommand ast, Void arg) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitIfCommand(IfCommand ast, Void arg) {
|
|
||||||
ast.C1.visit(this);
|
|
||||||
ast.C2.visit(this);
|
|
||||||
AbstractSyntaxTree replacement = ast.E.visit(this);
|
|
||||||
if (replacement != null) {
|
|
||||||
ast.E = (Expression) replacement;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitLetCommand(LetCommand ast, Void arg) {
|
|
||||||
ast.C.visit(this);
|
|
||||||
ast.D.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitSequentialCommand(SequentialCommand ast, Void arg) {
|
|
||||||
ast.C1.visit(this);
|
|
||||||
ast.C2.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitWhileCommand(WhileCommand ast, Void arg) {
|
|
||||||
ast.C.visit(this);
|
|
||||||
AbstractSyntaxTree replacement = ast.E.visit(this);
|
|
||||||
if (replacement != null) {
|
|
||||||
ast.E = (Expression) replacement;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO uncomment if you've implemented the repeat command
|
|
||||||
// @Override
|
|
||||||
// public AbstractSyntaxTree visitRepeatCommand(RepeatCommand ast, Void arg) {
|
|
||||||
// ast.C.visit(this);
|
|
||||||
// AbstractSyntaxTree replacement = ast.E.visit(this);
|
|
||||||
// if (replacement != null) {
|
|
||||||
// ast.E = (Expression) replacement;
|
|
||||||
// }
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitMultipleArrayAggregate(MultipleArrayAggregate ast, Void arg) {
|
|
||||||
ast.AA.visit(this);
|
|
||||||
AbstractSyntaxTree replacement = ast.E.visit(this);
|
|
||||||
if (replacement != null) {
|
|
||||||
ast.E = (Expression) replacement;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitSingleArrayAggregate(SingleArrayAggregate ast, Void arg) {
|
|
||||||
AbstractSyntaxTree replacement = ast.E.visit(this);
|
|
||||||
if (replacement != null) {
|
|
||||||
ast.E = (Expression) replacement;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitEmptyActualParameterSequence(EmptyActualParameterSequence ast, Void arg) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, Void arg) {
|
|
||||||
ast.AP.visit(this);
|
|
||||||
ast.APS.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitSingleActualParameterSequence(SingleActualParameterSequence ast, Void arg) {
|
|
||||||
ast.AP.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitConstActualParameter(ConstActualParameter ast, Void arg) {
|
|
||||||
AbstractSyntaxTree replacement = ast.E.visit(this);
|
|
||||||
if (replacement != null) {
|
|
||||||
ast.E = (Expression) replacement;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitFuncActualParameter(FuncActualParameter ast, Void arg) {
|
|
||||||
ast.I.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitProcActualParameter(ProcActualParameter ast, Void arg) {
|
|
||||||
ast.I.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractSyntaxTree visitVarActualParameter(VarActualParameter ast, Void arg) {
|
|
||||||
ast.V.visit(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AbstractSyntaxTree foldBinaryExpression(AbstractSyntaxTree node1, AbstractSyntaxTree node2, Operator o) {
|
|
||||||
// the only case we know how to deal with for now is two IntegerExpressions
|
|
||||||
if ((node1 instanceof IntegerExpression) && (node2 instanceof IntegerExpression)) {
|
|
||||||
int int1 = (Integer.parseInt(((IntegerExpression) node1).IL.spelling));
|
|
||||||
int int2 = (Integer.parseInt(((IntegerExpression) node2).IL.spelling));
|
|
||||||
Object foldedValue = null;
|
|
||||||
|
|
||||||
if (o.decl == StdEnvironment.addDecl) {
|
|
||||||
foldedValue = int1 + int2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (foldedValue instanceof Integer) {
|
|
||||||
IntegerLiteral il = new IntegerLiteral(foldedValue.toString(), node1.getPosition());
|
|
||||||
IntegerExpression ie = new IntegerExpression(il, node1.getPosition());
|
|
||||||
ie.type = StdEnvironment.integerType;
|
|
||||||
return ie;
|
|
||||||
} else if (foldedValue instanceof Boolean) {
|
|
||||||
/* currently not handled! */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// any unhandled situation (i.e., not foldable) is ignored
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -37,7 +37,6 @@ import triangle.abstractSyntaxTrees.commands.Command;
|
|||||||
import triangle.abstractSyntaxTrees.commands.EmptyCommand;
|
import triangle.abstractSyntaxTrees.commands.EmptyCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.IfCommand;
|
import triangle.abstractSyntaxTrees.commands.IfCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.LetCommand;
|
import triangle.abstractSyntaxTrees.commands.LetCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.RepeatCommand;
|
|
||||||
import triangle.abstractSyntaxTrees.commands.SequentialCommand;
|
import triangle.abstractSyntaxTrees.commands.SequentialCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.WhileCommand;
|
import triangle.abstractSyntaxTrees.commands.WhileCommand;
|
||||||
import triangle.abstractSyntaxTrees.declarations.ConstDeclaration;
|
import triangle.abstractSyntaxTrees.declarations.ConstDeclaration;
|
||||||
@@ -321,7 +320,7 @@ public class Parser {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Token.WHILE: { //while expr. do command
|
case Token.WHILE: {
|
||||||
acceptIt();
|
acceptIt();
|
||||||
Expression eAST = parseExpression();
|
Expression eAST = parseExpression();
|
||||||
accept(Token.DO);
|
accept(Token.DO);
|
||||||
@@ -331,16 +330,6 @@ public class Parser {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Token.REPEAT: { //repeat command until expr.
|
|
||||||
acceptIt();
|
|
||||||
Command cAST = parseSingleCommand();
|
|
||||||
accept(Token.UNTIL); //check that there is a "until"
|
|
||||||
Expression eAST = parseExpression();
|
|
||||||
finish(commandPos);
|
|
||||||
commandAST = new RepeatCommand(eAST, cAST, commandPos);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Token.SEMICOLON:
|
case Token.SEMICOLON:
|
||||||
case Token.END:
|
case Token.END:
|
||||||
case Token.ELSE:
|
case Token.ELSE:
|
||||||
@@ -929,4 +918,3 @@ public class Parser {
|
|||||||
return fieldAST;
|
return fieldAST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public final class Scanner {
|
|||||||
|
|
||||||
private boolean isOperator(char c) {
|
private boolean isOperator(char c) {
|
||||||
return (c == '+' || c == '-' || c == '*' || c == '/' || c == '=' || c == '<' || c == '>' || c == '\\'
|
return (c == '+' || c == '-' || c == '*' || c == '/' || c == '=' || c == '<' || c == '>' || c == '\\'
|
||||||
|| c == '&' || c == '@' || c == '%' || c == '^' || c == '?' || c == '|');
|
|| c == '&' || c == '@' || c == '%' || c == '^' || c == '?');
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -64,7 +64,7 @@ public final class Scanner {
|
|||||||
private void scanSeparator() {
|
private void scanSeparator() {
|
||||||
switch (currentChar) {
|
switch (currentChar) {
|
||||||
|
|
||||||
// ! comment
|
// comment
|
||||||
case '!': {
|
case '!': {
|
||||||
takeIt();
|
takeIt();
|
||||||
while ((currentChar != SourceFile.EOL) && (currentChar != SourceFile.EOT))
|
while ((currentChar != SourceFile.EOL) && (currentChar != SourceFile.EOT))
|
||||||
@@ -73,29 +73,7 @@ public final class Scanner {
|
|||||||
takeIt();
|
takeIt();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// new type of comment, the # comment, same as before when it comes to code
|
|
||||||
case '#':{
|
|
||||||
takeIt();
|
|
||||||
while((currentChar != SourceFile.EOL) && (currentChar != SourceFile.EOT))
|
|
||||||
takeIt();
|
|
||||||
if(currentChar == SourceFile.EOL)
|
|
||||||
takeIt();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// new type of comment, the multi-line $ comment
|
|
||||||
case '$':{
|
|
||||||
takeIt();
|
|
||||||
//check if it is not the comment char or EOT, skipping new lines (no EOL)
|
|
||||||
while((currentChar != '$') && (currentChar != SourceFile.EOT))
|
|
||||||
takeIt();
|
|
||||||
//if we reach another $, takeIt and move on, we've reached the end of the multi-line comment
|
|
||||||
if(currentChar == '$')
|
|
||||||
takeIt();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// whitespace
|
// whitespace
|
||||||
case ' ':
|
case ' ':
|
||||||
case '\n':
|
case '\n':
|
||||||
@@ -199,13 +177,6 @@ public final class Scanner {
|
|||||||
while (isOperator(currentChar))
|
while (isOperator(currentChar))
|
||||||
takeIt();
|
takeIt();
|
||||||
return Token.OPERATOR;
|
return Token.OPERATOR;
|
||||||
|
|
||||||
// TODO: Bar operator, week 3
|
|
||||||
case '|':
|
|
||||||
takeIt();
|
|
||||||
while(isOperator(currentChar))
|
|
||||||
takeIt();
|
|
||||||
return Token.OPERATOR;
|
|
||||||
|
|
||||||
case '\'':
|
case '\'':
|
||||||
takeIt();
|
takeIt();
|
||||||
@@ -281,7 +252,7 @@ public final class Scanner {
|
|||||||
currentlyScanningToken = false;
|
currentlyScanningToken = false;
|
||||||
// skip any whitespace or comments
|
// skip any whitespace or comments
|
||||||
while (currentChar == '!' || currentChar == ' ' || currentChar == '\n' || currentChar == '\r'
|
while (currentChar == '!' || currentChar == ' ' || currentChar == '\n' || currentChar == '\r'
|
||||||
|| currentChar == '\t' || currentChar == '#' || currentChar == '$')
|
|| currentChar == '\t')
|
||||||
scanSeparator();
|
scanSeparator();
|
||||||
|
|
||||||
currentlyScanningToken = true;
|
currentlyScanningToken = true;
|
||||||
|
|||||||
@@ -14,36 +14,26 @@
|
|||||||
|
|
||||||
package triangle.syntacticAnalyzer;
|
package triangle.syntacticAnalyzer;
|
||||||
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
public class SourceFile {
|
public class SourceFile {
|
||||||
|
|
||||||
public static final char EOL = '\n';
|
public static final char EOL = '\n';
|
||||||
public static final char EOT = '\u0000';
|
public static final char EOT = '\u0000';
|
||||||
|
|
||||||
java.io.File sourceFile;
|
java.io.File sourceFile;
|
||||||
java.io.InputStream source;
|
java.io.FileInputStream source;
|
||||||
int currentLine;
|
int currentLine;
|
||||||
|
|
||||||
public static SourceFile ofPath(String pathname) {
|
public static SourceFile ofPath(String pathname) {
|
||||||
try {
|
try {
|
||||||
SourceFile sf = new SourceFile();
|
return new SourceFile(pathname);
|
||||||
sf.sourceFile = new java.io.File(pathname);
|
|
||||||
sf.source = new java.io.FileInputStream(sf.sourceFile);
|
|
||||||
return sf;
|
|
||||||
} catch (java.io.IOException s) {
|
} catch (java.io.IOException s) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SourceFile fromResource(String handle) {
|
|
||||||
SourceFile sf = new SourceFile();
|
|
||||||
//sf.sourceFile = new java.io.File(pathname);
|
|
||||||
sf.source = sf.getClass().getResourceAsStream(handle);
|
|
||||||
return sf;
|
|
||||||
}
|
|
||||||
|
|
||||||
private SourceFile() {
|
private SourceFile(String pathname) throws java.io.FileNotFoundException {
|
||||||
|
sourceFile = new java.io.File(pathname);
|
||||||
|
source = new java.io.FileInputStream(sourceFile);
|
||||||
currentLine = 1;
|
currentLine = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,20 +64,20 @@ final class Token extends Object {
|
|||||||
|
|
||||||
// reserved words - must be in alphabetical order...
|
// 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,
|
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, REPEAT = 17, THEN = 18, TYPE = 19, UNTIL = 20, VAR = 21, WHILE = 22,
|
PROC = 15, RECORD = 16, THEN = 17, TYPE = 18, VAR = 19, WHILE = 20,
|
||||||
|
|
||||||
// punctuation...
|
// punctuation...
|
||||||
DOT = 23, COLON = 24, SEMICOLON = 25, COMMA = 26, BECOMES = 27, IS = 28,
|
DOT = 21, COLON = 22, SEMICOLON = 23, COMMA = 24, BECOMES = 25, IS = 26,
|
||||||
|
|
||||||
// brackets...
|
// brackets...
|
||||||
LPAREN = 29, RPAREN = 30, LBRACKET = 31, RBRACKET = 32, LCURLY = 33, RCURLY = 34,
|
LPAREN = 27, RPAREN = 28, LBRACKET = 29, RBRACKET = 30, LCURLY = 31, RCURLY = 32,
|
||||||
|
|
||||||
// special tokens...
|
// special tokens...
|
||||||
EOT = 35, ERROR = 36;
|
EOT = 33, ERROR = 34;
|
||||||
|
|
||||||
private static String[] tokenTable = new String[] { "<int>", "<char>", "<identifier>", "<operator>", "array",
|
private static String[] tokenTable = new String[] { "<int>", "<char>", "<identifier>", "<operator>", "array",
|
||||||
"begin", "const", "do", "else", "end", "func", "if", "in", "let", "of", "proc", "record", "repeat", "then", "type",
|
"begin", "const", "do", "else", "end", "func", "if", "in", "let", "of", "proc", "record", "then", "type",
|
||||||
"until", "var", "while", ".", ":", ";", ",", ":=", "~", "(", ")", "[", "]", "{", "}", "", "<error>" };
|
"var", "while", ".", ":", ";", ",", ":=", "~", "(", ")", "[", "]", "{", "}", "", "<error>" };
|
||||||
|
|
||||||
private final static int firstReservedWord = Token.ARRAY, lastReservedWord = Token.WHILE;
|
private final static int firstReservedWord = Token.ARRAY, lastReservedWord = Token.WHILE;
|
||||||
|
|
||||||
|
|||||||
@@ -42,13 +42,6 @@ public class Drawer {
|
|||||||
|
|
||||||
FontMetrics fontMetrics = frame.getFontMetrics(font);
|
FontMetrics fontMetrics = frame.getFontMetrics(font);
|
||||||
|
|
||||||
// another class of visitor is used for drawing the tree: LayoutVisitor
|
|
||||||
// LayoutVisitor is passed to the AST which, in turn, calls visitProgram
|
|
||||||
// and then each AST node is visited. This ultimately constructs a
|
|
||||||
// DrawingTree, which is structurally the same as the AST but is decorated
|
|
||||||
// with coordinates (and has only DrawingTree objects as nodes)
|
|
||||||
// Each DrawingTree object knows how to paint itself, so it's passed to a
|
|
||||||
// DrawerPanel and DrawerFrame for display
|
|
||||||
LayoutVisitor layout = new LayoutVisitor(fontMetrics);
|
LayoutVisitor layout = new LayoutVisitor(fontMetrics);
|
||||||
theDrawing = (DrawingTree) theAST.visit(layout, null);
|
theDrawing = (DrawingTree) theAST.visit(layout, null);
|
||||||
theDrawing.position(new Point(2048, 10));
|
theDrawing.position(new Point(2048, 10));
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import triangle.abstractSyntaxTrees.commands.CallCommand;
|
|||||||
import triangle.abstractSyntaxTrees.commands.EmptyCommand;
|
import triangle.abstractSyntaxTrees.commands.EmptyCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.IfCommand;
|
import triangle.abstractSyntaxTrees.commands.IfCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.LetCommand;
|
import triangle.abstractSyntaxTrees.commands.LetCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.RepeatCommand;
|
|
||||||
import triangle.abstractSyntaxTrees.commands.SequentialCommand;
|
import triangle.abstractSyntaxTrees.commands.SequentialCommand;
|
||||||
import triangle.abstractSyntaxTrees.commands.WhileCommand;
|
import triangle.abstractSyntaxTrees.commands.WhileCommand;
|
||||||
import triangle.abstractSyntaxTrees.declarations.BinaryOperatorDeclaration;
|
import triangle.abstractSyntaxTrees.declarations.BinaryOperatorDeclaration;
|
||||||
@@ -159,14 +158,6 @@ public class LayoutVisitor implements ActualParameterVisitor<Void, DrawingTree>,
|
|||||||
var d2 = ast.C.visit(this);
|
var d2 = ast.C.visit(this);
|
||||||
return layoutBinary("WhileCom.", d1, d2);
|
return layoutBinary("WhileCom.", d1, d2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public DrawingTree visitRepeatCommand(RepeatCommand ast, Void obj) {
|
|
||||||
//very similar to the while cmd, just reverse!
|
|
||||||
var d1 = ast.C.visit(this);
|
|
||||||
var d2 = ast.E.visit(this);
|
|
||||||
return layoutBinary("Repeat.Com.", d1, d2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expressions
|
// Expressions
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -14,9 +14,6 @@
|
|||||||
|
|
||||||
package triangle.treeDrawer;
|
package triangle.treeDrawer;
|
||||||
|
|
||||||
/**
|
|
||||||
* used to keep track of the position for components in the tree to be drawn
|
|
||||||
*/
|
|
||||||
class Polyline {
|
class Polyline {
|
||||||
int dx, dy;
|
int dx, dy;
|
||||||
Polyline link;
|
Polyline link;
|
||||||
|
|||||||
@@ -1,90 +0,0 @@
|
|||||||
package triangle.syntacticAnalyser;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotEquals;
|
|
||||||
import static org.junit.Assert.assertThrows;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.function.ThrowingRunnable;
|
|
||||||
|
|
||||||
import triangle.ErrorReporter;
|
|
||||||
import triangle.syntacticAnalyzer.Parser;
|
|
||||||
import triangle.syntacticAnalyzer.Scanner;
|
|
||||||
import triangle.syntacticAnalyzer.SourceFile;
|
|
||||||
|
|
||||||
public class TestScanner {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHi() {
|
|
||||||
compileExpectSuccess("/hi.tri");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHiNewComment() {
|
|
||||||
compileExpectSuccess("/hi-newcomment.tri");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHiNewComment2() {
|
|
||||||
compileExpectSuccess("/hi-newcomment2.tri");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBarDemo() {
|
|
||||||
compileExpectSuccess("/bardemo.tri"); //TODO: Change this to failure
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRepeatUntil() {
|
|
||||||
compileExpectSuccess("/repeatuntil.tri");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAdd() {
|
|
||||||
//compileExpectFailure("/addd.tri"); //fail here!
|
|
||||||
compileExpectFailure("/add.tri");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void compileExpectSuccess(String filename) {
|
|
||||||
// build.gradle has a line sourceSets.test.resources.srcDir file("$rootDir/programs")
|
|
||||||
// which adds the programs directory to the list of places Java can easily find files
|
|
||||||
// getResource() below searches for a file, which is in /programs
|
|
||||||
//SourceFile source = SourceFile.ofPath(this.getClass().getResource(filename).getFile().toString());
|
|
||||||
SourceFile source = SourceFile.fromResource(filename);
|
|
||||||
|
|
||||||
Scanner scanner = new Scanner(source);
|
|
||||||
ErrorReporter reporter = new ErrorReporter(true);
|
|
||||||
Parser parser = new Parser(scanner, reporter);
|
|
||||||
|
|
||||||
parser.parseProgram();
|
|
||||||
|
|
||||||
// we should get to here with no exceptions
|
|
||||||
|
|
||||||
assertEquals("Problem compiling " + filename, 0, reporter.getNumErrors());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void compileExpectFailure(String filename) {
|
|
||||||
//SourceFile source = SourceFile.ofPath(this.getClass().getResource(filename).getFile().toString());
|
|
||||||
SourceFile source = SourceFile.fromResource(filename);
|
|
||||||
Scanner scanner = new Scanner(source);
|
|
||||||
ErrorReporter reporter = new ErrorReporter(true);
|
|
||||||
Parser parser = new Parser(scanner, reporter);
|
|
||||||
|
|
||||||
// we expect an exception here as the program has invalid syntax
|
|
||||||
assertThrows(RuntimeException.class, new ThrowingRunnable() {
|
|
||||||
public void run(){
|
|
||||||
parser.parseProgram();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// currently this program will fail
|
|
||||||
assertNotEquals("Problem compiling " + filename, 0, reporter.getNumErrors());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
apply plugin: 'java'
|
|
||||||
|
|
||||||
sourceCompatibility = 11
|
|
||||||
|
|
||||||
subprojects.each { subproject ->
|
|
||||||
evaluationDependsOn(subproject.path)
|
|
||||||
}
|
|
||||||
|
|
||||||
jar {
|
|
||||||
from subprojects.sourceSets.main.output
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -1,46 +0,0 @@
|
|||||||
! Program that will: read two ints, print their sum and their product. If they are the same, print "Same"
|
|
||||||
|
|
||||||
! Global Consts, Funcs.
|
|
||||||
let
|
|
||||||
type String ~ array 6 of Char; ! String type implemented, not used yet
|
|
||||||
|
|
||||||
var num1 : Integer;
|
|
||||||
var num2 : Integer;
|
|
||||||
|
|
||||||
|
|
||||||
func sum(x : Integer, y : Integer) : Integer ~
|
|
||||||
x + y; ! Return x + y
|
|
||||||
|
|
||||||
func product(x : Integer, y : Integer) : Integer ~
|
|
||||||
x * y; ! Return x * y
|
|
||||||
|
|
||||||
func isSame(x : Integer, y : Integer) : Boolean ~
|
|
||||||
if x = y then true else false
|
|
||||||
|
|
||||||
! Main Loop
|
|
||||||
in
|
|
||||||
begin
|
|
||||||
num1 := 0;
|
|
||||||
num2 := 0; ! Init. values to 0
|
|
||||||
|
|
||||||
getint(var num1);
|
|
||||||
getint(var num2); ! Get user input
|
|
||||||
|
|
||||||
|
|
||||||
! Sum
|
|
||||||
putint(num1); put('+'); put(' '); putint(num2); put(' '); put('='); put(' ');
|
|
||||||
putint(sum(num1, num2)); puteol();
|
|
||||||
|
|
||||||
puteol();
|
|
||||||
|
|
||||||
! Product
|
|
||||||
putint(num1); put(' '); put('*'); put(' '); putint(num2); put(' '); put('='); put(' ');
|
|
||||||
putint(product(num1, num2)); puteol();
|
|
||||||
|
|
||||||
|
|
||||||
if isSame(num1, num2) = true then
|
|
||||||
put('S'); put('a'); put('m'); put('e'); puteol();
|
|
||||||
else
|
|
||||||
puteol();
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
let
|
|
||||||
var a: Integer
|
|
||||||
in
|
|
||||||
begin
|
|
||||||
a := 10 + 20 * 2 / 3;
|
|
||||||
putint(a);
|
|
||||||
|
|
||||||
puteol();
|
|
||||||
|
|
||||||
a := 5 + 8;
|
|
||||||
putint(a)
|
|
||||||
end
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
! this won't work until after some work in the practicals
|
|
||||||
let
|
|
||||||
var a : Integer;
|
|
||||||
var b : Integer
|
|
||||||
|
|
||||||
in
|
|
||||||
begin
|
|
||||||
a := 1;
|
|
||||||
b := 2;
|
|
||||||
|
|
||||||
putint(a);
|
|
||||||
<<<<<<< HEAD
|
|
||||||
puteol();
|
|
||||||
=======
|
|
||||||
puteol();
|
|
||||||
>>>>>>> ce307a11a6c71de9c69bd0a4c91205bb6437f6e9
|
|
||||||
putint(b);
|
|
||||||
puteol();
|
|
||||||
putint(|a);
|
|
||||||
puteol();
|
|
||||||
putint(|b);
|
|
||||||
puteol()
|
|
||||||
<<<<<<< HEAD
|
|
||||||
|
|
||||||
=======
|
|
||||||
>>>>>>> ce307a11a6c71de9c69bd0a4c91205bb6437f6e9
|
|
||||||
end
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
! Program with a variety of contextual errors.
|
|
||||||
|
|
||||||
let
|
|
||||||
type String ~ array 4 of Char;
|
|
||||||
type Name ~ array 3 of String;
|
|
||||||
type Rec ~ record x: Integer, x: Integer end;
|
|
||||||
|
|
||||||
var me: Name;
|
|
||||||
var silly : maxint;
|
|
||||||
var silly: Rec;
|
|
||||||
|
|
||||||
proc putstr (s: String) ~
|
|
||||||
let var i: Integer
|
|
||||||
in
|
|
||||||
begin
|
|
||||||
s[4] := ' ';
|
|
||||||
i := 0;
|
|
||||||
while i do
|
|
||||||
begin i := i+true;
|
|
||||||
put (s[\i])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
in
|
|
||||||
begin
|
|
||||||
me[true] := ['T','i','n','y'];
|
|
||||||
me[2][2] := 0;
|
|
||||||
put (me[1]); put (4); put ();
|
|
||||||
putstr (initials (me)); puteol ()
|
|
||||||
end
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
! this won't work until after some work in the practicals
|
|
||||||
|
|
||||||
# new comment
|
|
||||||
|
|
||||||
begin
|
|
||||||
put('H'); put('i'); put('!')
|
|
||||||
end
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
! this won't work until after some work in the practicals
|
|
||||||
|
|
||||||
# new comment
|
|
||||||
|
|
||||||
$
|
|
||||||
another new comment
|
|
||||||
another new comment
|
|
||||||
another new comment
|
|
||||||
another new comment
|
|
||||||
$
|
|
||||||
|
|
||||||
begin
|
|
||||||
put('H'); put('i'); put('!')
|
|
||||||
end
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
! this won't compile without implementing the bonus material in Practical 3
|
|
||||||
|
|
||||||
let
|
|
||||||
var a: Integer
|
|
||||||
in
|
|
||||||
begin
|
|
||||||
getint(var a);
|
|
||||||
a++;
|
|
||||||
putint(a);
|
|
||||||
puteol();
|
|
||||||
a++;
|
|
||||||
putint(a);
|
|
||||||
puteol();
|
|
||||||
end
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
! this won't work until after some lab work
|
|
||||||
|
|
||||||
let
|
|
||||||
var a : Integer
|
|
||||||
in
|
|
||||||
begin
|
|
||||||
a := 0;
|
|
||||||
repeat
|
|
||||||
begin
|
|
||||||
put('a');
|
|
||||||
a := a + 1;
|
|
||||||
end
|
|
||||||
until a >= 5
|
|
||||||
end
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
let
|
|
||||||
var a : Integer;
|
|
||||||
var b : Integer;
|
|
||||||
var c : Integer
|
|
||||||
in
|
|
||||||
begin
|
|
||||||
put('1');
|
|
||||||
puteol();
|
|
||||||
a := 0;
|
|
||||||
while a < 5000 do
|
|
||||||
begin
|
|
||||||
b := 0;
|
|
||||||
while b < 3000 do
|
|
||||||
begin
|
|
||||||
c := c + a;
|
|
||||||
c := c / (1 + b);
|
|
||||||
b := b + 1;
|
|
||||||
end;
|
|
||||||
a := a + 1;
|
|
||||||
end;
|
|
||||||
putint(c);
|
|
||||||
end
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
let
|
|
||||||
var a : Integer
|
|
||||||
in
|
|
||||||
begin
|
|
||||||
a := 0;
|
|
||||||
while a < 5 do
|
|
||||||
begin
|
|
||||||
put('a');
|
|
||||||
a := a + 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
RED='\033[0;31m' # Red
|
|
||||||
GRN='\033[0;32m' # Green
|
|
||||||
NC='\033[0m' # No Color
|
|
||||||
|
|
||||||
file=""
|
|
||||||
|
|
||||||
if [ -z "$1" ]
|
|
||||||
then
|
|
||||||
printf "${RED}Usage: $0 file${NC}"
|
|
||||||
exit 1 # Exit with code 1, failure
|
|
||||||
else
|
|
||||||
file=$1
|
|
||||||
fi
|
|
||||||
|
|
||||||
printf "${GRN}[INFO] Compiling file: $1.tri to $1.tam ...${NC}\n"
|
|
||||||
|
|
||||||
# Compile to tam
|
|
||||||
if java -cp build/libs/Triangle-Tools.jar triangle.Compiler programs/$1.tri -o=$1.tam &> /dev/null #quiet
|
|
||||||
then
|
|
||||||
printf "${GRN}[INFO] Running file: $1.tam ...${NC}\n"
|
|
||||||
java -cp build/libs/Triangle-Tools.jar triangle.abstractMachine.Interpreter $1.tam
|
|
||||||
else
|
|
||||||
printf "${RED}[ERROR] Could not complie $1.tri ...${NC}"
|
|
||||||
err=$(java -cp build/libs/Triangle-Tools.jar triangle.Compiler programs/$1.tri -o=$1.tam)
|
|
||||||
printf "${RED}\n$err\n${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
Reference in New Issue
Block a user