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