From 1da8cabdf7885c01ac8032773109559c4aa7f3d1 Mon Sep 17 00:00:00 2001 From: Sandy Brownlee Date: Wed, 21 Sep 2022 13:35:56 +0100 Subject: [PATCH 1/8] minor fix to repeatuntil --- programs/repeatuntil.tri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From f5951671b9c5dbbf14b26b251108f896b536995a Mon Sep 17 00:00:00 2001 From: Sandy Brownlee Date: Wed, 21 Sep 2022 16:49:53 +0100 Subject: [PATCH 2/8] Added increment demo program --- programs/increment.tri | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 programs/increment.tri 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 From 0c1b2530fa35bd0607656adc7a233fdf67560826 Mon Sep 17 00:00:00 2001 From: Sandy Brownlee Date: Thu, 22 Sep 2022 17:37:52 +0100 Subject: [PATCH 3/8] Amended comments in Encoder --- .../src/main/java/triangle/codeGenerator/Encoder.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Triangle.Compiler/src/main/java/triangle/codeGenerator/Encoder.java b/Triangle.Compiler/src/main/java/triangle/codeGenerator/Encoder.java index 3066815..2224aa6 100644 --- a/Triangle.Compiler/src/main/java/triangle/codeGenerator/Encoder.java +++ b/Triangle.Compiler/src/main/java/triangle/codeGenerator/Encoder.java @@ -741,10 +741,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. From 461749e44a11bcad458cfc91b7a73fe01d0e189d Mon Sep 17 00:00:00 2001 From: Sandy Brownlee Date: Fri, 23 Sep 2022 17:21:03 +0100 Subject: [PATCH 4/8] Added timing to interpreter --- .../src/main/java/triangle/abstractMachine/Interpreter.java | 4 ++++ 1 file changed, 4 insertions(+) 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(); } From 6a30c4db8bbd6d54c308a385b9e1675f44858f66 Mon Sep 17 00:00:00 2001 From: Sandy Brownlee Date: Tue, 27 Sep 2022 21:41:24 +0100 Subject: [PATCH 5/8] Updated examples --- programs/bardemo.tri | 8 ++++++-- programs/while-longloop.tri | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 programs/while-longloop.tri diff --git a/programs/bardemo.tri b/programs/bardemo.tri index 4e792cc..f730f74 100644 --- a/programs/bardemo.tri +++ b/programs/bardemo.tri @@ -9,7 +9,11 @@ in b := 2; putint(a); + puteol(); putint(b); + puteol(); putint(|a); - putint(|b) - end \ No newline at end of file + puteol(); + putint(|b); + puteol() + 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 From 7a8fb2564c30a167e74c8f30fa115a1d4fd6e033 Mon Sep 17 00:00:00 2001 From: Sandy Brownlee Date: Wed, 28 Sep 2022 10:44:30 +0100 Subject: [PATCH 6/8] Added NOP to opcodes so ordinals match the book --- .../src/main/java/triangle/abstractMachine/OpCode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 } From 55fdd944fa3dacd71e8a0290e785bfeba33dec52 Mon Sep 17 00:00:00 2001 From: Sandy Brownlee Date: Fri, 30 Sep 2022 00:10:27 +0100 Subject: [PATCH 7/8] Changes for constant folding --- .../src/main/java/triangle/Compiler.java | 10 +- .../actuals/ConstActualParameter.java | 2 +- .../aggregates/MultipleArrayAggregate.java | 2 +- .../aggregates/MultipleRecordAggregate.java | 2 +- .../aggregates/SingleArrayAggregate.java | 2 +- .../aggregates/SingleRecordAggregate.java | 2 +- .../commands/AssignCommand.java | 2 +- .../commands/IfCommand.java | 2 +- .../commands/WhileCommand.java | 2 +- .../declarations/ConstDeclaration.java | 2 +- .../declarations/FuncDeclaration.java | 2 +- .../expressions/BinaryExpression.java | 3 +- .../expressions/IfExpression.java | 4 +- .../expressions/LetExpression.java | 2 +- .../expressions/UnaryExpression.java | 2 +- .../vnames/SubscriptVname.java | 2 +- .../triangle/optimiser/ConstantFolder.java | 600 ++++++++++++++++++ programs/adddeep.tri | 12 + 18 files changed, 639 insertions(+), 16 deletions(-) create mode 100644 Triangle.Compiler/src/main/java/triangle/optimiser/ConstantFolder.java create mode 100644 programs/adddeep.tri 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/optimiser/ConstantFolder.java b/Triangle.Compiler/src/main/java/triangle/optimiser/ConstantFolder.java new file mode 100644 index 0000000..904a0f2 --- /dev/null +++ b/Triangle.Compiler/src/main/java/triangle/optimiser/ConstantFolder.java @@ -0,0 +1,600 @@ +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.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; + } + +} \ No newline at end of file diff --git a/programs/adddeep.tri b/programs/adddeep.tri new file mode 100644 index 0000000..5f33bc1 --- /dev/null +++ b/programs/adddeep.tri @@ -0,0 +1,12 @@ +let + var a: Integer +in +begin + a := 10 + 20 * 2 / 3; + putint(a); + + puteol(); + + a := 5 + 8; + putint(a) +end From ce307a11a6c71de9c69bd0a4c91205bb6437f6e9 Mon Sep 17 00:00:00 2001 From: Sandy Brownlee Date: Thu, 6 Oct 2022 17:20:59 +0100 Subject: [PATCH 8/8] Update ConstantFolder.java --- .../src/main/java/triangle/optimiser/ConstantFolder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Triangle.Compiler/src/main/java/triangle/optimiser/ConstantFolder.java b/Triangle.Compiler/src/main/java/triangle/optimiser/ConstantFolder.java index 904a0f2..5a9da87 100644 --- a/Triangle.Compiler/src/main/java/triangle/optimiser/ConstantFolder.java +++ b/Triangle.Compiler/src/main/java/triangle/optimiser/ConstantFolder.java @@ -19,6 +19,7 @@ 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; @@ -597,4 +598,4 @@ public class ConstantFolder implements ActualParameterVisitor