diff --git a/Triangle.AbstractMachine.Interpreter/src/main/java/triangle/abstractMachine/Interpreter.java b/Triangle.AbstractMachine.Interpreter/src/main/java/triangle/abstractMachine/Interpreter.java
index 97e4f0e..96b10c5 100644
--- a/Triangle.AbstractMachine.Interpreter/src/main/java/triangle/abstractMachine/Interpreter.java
+++ b/Triangle.AbstractMachine.Interpreter/src/main/java/triangle/abstractMachine/Interpreter.java
@@ -21,6 +21,8 @@ import java.io.IOException;
public class Interpreter {
+ static long startTimeNanos = 0;
+
static String objectName;
// DATA STORE
@@ -183,6 +185,7 @@ public class Interpreter {
break;
case halted:
System.out.println("Program has halted normally.");
+ System.out.println("Total execution time (ns): " + (System.nanoTime() - startTimeNanos));
break;
case failedDataStoreFull:
System.out.println("Program has failed due to exhaustion of Data Store.");
@@ -634,6 +637,7 @@ public class Interpreter {
loadObjectProgram(objectName);
if (CT != CB) {
+ startTimeNanos = System.nanoTime();
interpretProgram();
showStatus();
}
diff --git a/Triangle.AbstractMachine/src/main/java/triangle/abstractMachine/OpCode.java b/Triangle.AbstractMachine/src/main/java/triangle/abstractMachine/OpCode.java
index 1d82e34..23ca257 100644
--- a/Triangle.AbstractMachine/src/main/java/triangle/abstractMachine/OpCode.java
+++ b/Triangle.AbstractMachine/src/main/java/triangle/abstractMachine/OpCode.java
@@ -1,5 +1,5 @@
package triangle.abstractMachine;
public enum OpCode {
- LOAD, LOADA, LOADI, LOADL, STORE, STOREI, CALL, CALLI, RETURN, PUSH, POP, JUMP, JUMPI, JUMPIF, HALT
+ LOAD, LOADA, LOADI, LOADL, STORE, STOREI, CALL, CALLI, RETURN, NOP, PUSH, POP, JUMP, JUMPI, JUMPIF, HALT
}
diff --git a/Triangle.Compiler/src/main/java/triangle/Compiler.java b/Triangle.Compiler/src/main/java/triangle/Compiler.java
index 90fb3c1..1a49778 100644
--- a/Triangle.Compiler/src/main/java/triangle/Compiler.java
+++ b/Triangle.Compiler/src/main/java/triangle/Compiler.java
@@ -18,6 +18,7 @@ import triangle.abstractSyntaxTrees.Program;
import triangle.codeGenerator.Emitter;
import triangle.codeGenerator.Encoder;
import triangle.contextualAnalyzer.Checker;
+import triangle.optimiser.ConstantFolder;
import triangle.syntacticAnalyzer.Parser;
import triangle.syntacticAnalyzer.Scanner;
import triangle.syntacticAnalyzer.SourceFile;
@@ -35,6 +36,7 @@ public class Compiler {
static String objectName = "obj.tam";
static boolean showTree = false;
+ static boolean folding = false;
private static Scanner scanner;
private static Parser parser;
@@ -91,6 +93,10 @@ public class Compiler {
if (showingAST) {
drawer.draw(theAST);
}
+ if (folding) {
+ theAST.visit(new ConstantFolder());
+ }
+
if (reporter.getNumErrors() == 0) {
System.out.println("Code Generation ...");
encoder.encodeRun(theAST, showingTable); // 3rd pass
@@ -116,7 +122,7 @@ public class Compiler {
public static void main(String[] args) {
if (args.length < 1) {
- System.out.println("Usage: tc filename [-o=outputfilename] [tree]");
+ System.out.println("Usage: tc filename [-o=outputfilename] [tree] [folding]");
System.exit(1);
}
@@ -138,6 +144,8 @@ public class Compiler {
showTree = true;
} else if (sl.startsWith("-o=")) {
objectName = s.substring(3);
+ } else if (sl.equals("folding")) {
+ folding = true;
}
}
}
diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/actuals/ConstActualParameter.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/actuals/ConstActualParameter.java
index 7dfe2ba..ad469dc 100644
--- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/actuals/ConstActualParameter.java
+++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/actuals/ConstActualParameter.java
@@ -29,5 +29,5 @@ public class ConstActualParameter extends ActualParameter {
return v.visitConstActualParameter(this, arg);
}
- public final Expression E;
+ public Expression E;
}
diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/aggregates/MultipleArrayAggregate.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/aggregates/MultipleArrayAggregate.java
index 930534c..5b616e1 100644
--- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/aggregates/MultipleArrayAggregate.java
+++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/aggregates/MultipleArrayAggregate.java
@@ -30,6 +30,6 @@ public class MultipleArrayAggregate extends ArrayAggregate {
return v.visitMultipleArrayAggregate(this, arg);
}
- public final Expression E;
+ public Expression E;
public final ArrayAggregate AA;
}
diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/aggregates/MultipleRecordAggregate.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/aggregates/MultipleRecordAggregate.java
index c2ada71..1715b2e 100644
--- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/aggregates/MultipleRecordAggregate.java
+++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/aggregates/MultipleRecordAggregate.java
@@ -33,6 +33,6 @@ public class MultipleRecordAggregate extends RecordAggregate {
}
public final Identifier I;
- public final Expression E;
+ public Expression E;
public final RecordAggregate RA;
}
diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/aggregates/SingleArrayAggregate.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/aggregates/SingleArrayAggregate.java
index 8ae2213..4d5c624 100644
--- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/aggregates/SingleArrayAggregate.java
+++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/aggregates/SingleArrayAggregate.java
@@ -29,5 +29,5 @@ public class SingleArrayAggregate extends ArrayAggregate {
return v.visitSingleArrayAggregate(this, arg);
}
- public final Expression E;
+ public Expression E;
}
diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/aggregates/SingleRecordAggregate.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/aggregates/SingleRecordAggregate.java
index 9e91b53..14510c9 100644
--- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/aggregates/SingleRecordAggregate.java
+++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/aggregates/SingleRecordAggregate.java
@@ -32,5 +32,5 @@ public class SingleRecordAggregate extends RecordAggregate {
}
public final Identifier I;
- public final Expression E;
+ public Expression E;
}
diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/commands/AssignCommand.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/commands/AssignCommand.java
index 6c509b0..66906ae 100644
--- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/commands/AssignCommand.java
+++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/commands/AssignCommand.java
@@ -32,5 +32,5 @@ public class AssignCommand extends Command {
}
public final Vname V;
- public final Expression E;
+ public Expression E;
}
diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/commands/IfCommand.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/commands/IfCommand.java
index c353edf..e57d560 100644
--- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/commands/IfCommand.java
+++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/commands/IfCommand.java
@@ -31,6 +31,6 @@ public class IfCommand extends Command {
return v.visitIfCommand(this, arg);
}
- public final Expression E;
+ public Expression E;
public final Command C1, C2;
}
diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/commands/WhileCommand.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/commands/WhileCommand.java
index 0b18fe7..af21fde 100644
--- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/commands/WhileCommand.java
+++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/commands/WhileCommand.java
@@ -30,6 +30,6 @@ public class WhileCommand extends Command {
return v.visitWhileCommand(this, arg);
}
- public final Expression E;
+ public Expression E;
public final Command C;
}
diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/declarations/ConstDeclaration.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/declarations/ConstDeclaration.java
index 4cca112..86bb95a 100644
--- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/declarations/ConstDeclaration.java
+++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/declarations/ConstDeclaration.java
@@ -38,5 +38,5 @@ public class ConstDeclaration extends Declaration implements ConstantDeclaration
}
public final Identifier I;
- public final Expression E;
+ public Expression E;
}
diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/declarations/FuncDeclaration.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/declarations/FuncDeclaration.java
index cc49eb5..55272bb 100644
--- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/declarations/FuncDeclaration.java
+++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/declarations/FuncDeclaration.java
@@ -49,5 +49,5 @@ public class FuncDeclaration extends Declaration implements FunctionDeclaration
public final Identifier I;
public final FormalParameterSequence FPS;
public TypeDenoter T;
- public final Expression E;
+ public Expression E;
}
diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/BinaryExpression.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/BinaryExpression.java
index 2fcc530..f5a992a 100644
--- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/BinaryExpression.java
+++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/BinaryExpression.java
@@ -31,6 +31,7 @@ public class BinaryExpression extends Expression {
return v.visitBinaryExpression(this, arg);
}
- public final Expression E1, E2;
+ public Expression E1;
+ public Expression E2;
public final Operator O;
}
diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/IfExpression.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/IfExpression.java
index 099140a..0bd208d 100644
--- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/IfExpression.java
+++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/IfExpression.java
@@ -30,5 +30,7 @@ public class IfExpression extends Expression {
return v.visitIfExpression(this, arg);
}
- public final Expression E1, E2, E3;
+ public Expression E1;
+ public Expression E2;
+ public Expression E3;
}
diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/LetExpression.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/LetExpression.java
index f27edc2..1bfef81 100644
--- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/LetExpression.java
+++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/LetExpression.java
@@ -31,5 +31,5 @@ public class LetExpression extends Expression {
}
public final Declaration D;
- public final Expression E;
+ public Expression E;
}
diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/UnaryExpression.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/UnaryExpression.java
index 492e086..22199b9 100644
--- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/UnaryExpression.java
+++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/UnaryExpression.java
@@ -30,6 +30,6 @@ public class UnaryExpression extends Expression {
return v.visitUnaryExpression(this, arg);
}
- public final Expression E;
+ public Expression E;
public final Operator O;
}
diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/vnames/SubscriptVname.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/vnames/SubscriptVname.java
index d6e08b8..a95d1f4 100644
--- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/vnames/SubscriptVname.java
+++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/vnames/SubscriptVname.java
@@ -30,6 +30,6 @@ public class SubscriptVname extends Vname {
return v.visitSubscriptVname(this, arg);
}
- public final Expression E;
+ public Expression E;
public final Vname V;
}
diff --git a/Triangle.Compiler/src/main/java/triangle/codeGenerator/Encoder.java b/Triangle.Compiler/src/main/java/triangle/codeGenerator/Encoder.java
index 6ff9b84..7364cfb 100644
--- a/Triangle.Compiler/src/main/java/triangle/codeGenerator/Encoder.java
+++ b/Triangle.Compiler/src/main/java/triangle/codeGenerator/Encoder.java
@@ -755,10 +755,9 @@ public final class Encoder implements ActualParameterVisitor,
public static void writeTableDetails(AbstractSyntaxTree ast) {
}
- // Generates code to fetch the value of a named constant or variable
- // and push it on to the stack.
- // currentLevel is the routine level where the vname occurs.
- // frameSize is the anticipated size of the local stack frame when
+ // Generates code to pop the top off the stack
+ // and store the value in a named constant or variable
+ // frame the local stack frame when
// the constant or variable is fetched at run-time.
// valSize is the size of the constant or variable's value.
diff --git a/Triangle.Compiler/src/main/java/triangle/optimiser/ConstantFolder.java b/Triangle.Compiler/src/main/java/triangle/optimiser/ConstantFolder.java
new file mode 100644
index 0000000..5a9da87
--- /dev/null
+++ b/Triangle.Compiler/src/main/java/triangle/optimiser/ConstantFolder.java
@@ -0,0 +1,601 @@
+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,
+ ActualParameterSequenceVisitor, ArrayAggregateVisitor,
+ CommandVisitor, DeclarationVisitor,
+ ExpressionVisitor, FormalParameterSequenceVisitor,
+ IdentifierVisitor, LiteralVisitor,
+ OperatorVisitor, ProgramVisitor,
+ RecordAggregateVisitor, TypeDenoterVisitor,
+ VnameVisitor {
+ {
+
+ }
+
+ @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;
+ }
+
+}
diff --git a/programs/bardemo.tri b/programs/bardemo.tri
index 6746fc8..de6fc4c 100644
--- a/programs/bardemo.tri
+++ b/programs/bardemo.tri
@@ -9,12 +9,19 @@ in
b := 2;
putint(a);
+<<<<<<< HEAD
puteol();
+=======
+ puteol();
+>>>>>>> ce307a11a6c71de9c69bd0a4c91205bb6437f6e9
putint(b);
puteol();
putint(|a);
puteol();
putint(|b);
puteol()
+<<<<<<< HEAD
+=======
+>>>>>>> ce307a11a6c71de9c69bd0a4c91205bb6437f6e9
end
diff --git a/programs/increment.tri b/programs/increment.tri
new file mode 100644
index 0000000..11358a5
--- /dev/null
+++ b/programs/increment.tri
@@ -0,0 +1,14 @@
+! 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
diff --git a/programs/repeatuntil.tri b/programs/repeatuntil.tri
index 316493f..c2518de 100644
--- a/programs/repeatuntil.tri
+++ b/programs/repeatuntil.tri
@@ -10,5 +10,5 @@ begin
put('a');
a := a + 1;
end
- until a < 5
+ until a >= 5
end
diff --git a/programs/while-longloop.tri b/programs/while-longloop.tri
new file mode 100644
index 0000000..75b1088
--- /dev/null
+++ b/programs/while-longloop.tri
@@ -0,0 +1,22 @@
+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