From baf478a7a7bdf514165e1b8f9cfe7ad4cfbc0ece Mon Sep 17 00:00:00 2001 From: Deryck Brown Date: Wed, 11 May 2022 21:29:12 +0100 Subject: [PATCH] Initial commit of version 2.1. --- .vscode/settings.json | 18 + Triangle.AbstractMachine.Disassembler/pom.xml | 20 + .../AbstractMachine/Disassembler.java | 398 +++++++ Triangle.AbstractMachine.Interpreter/pom.xml | 20 + .../Triangle/AbstractMachine/Interpreter.java | 620 +++++++++++ Triangle.AbstractMachine/pom.xml | 14 + .../Triangle/AbstractMachine/Instruction.java | 64 ++ .../Triangle/AbstractMachine/Machine.java | 125 +++ .../compile/default-compile/inputFiles.lst | 2 + Triangle.Compiler/.editorconfig | 17 + Triangle.Compiler/pom.xml | 20 + .../Triangle/AbstractSyntaxTrees/AST.java | 35 + .../AbstractSyntaxTrees/ActualParameter.java | 24 + .../ActualParameterSequence.java | 24 + .../AbstractSyntaxTrees/AnyTypeDenoter.java | 32 + .../AbstractSyntaxTrees/ArrayAggregate.java | 27 + .../AbstractSyntaxTrees/ArrayExpression.java | 32 + .../AbstractSyntaxTrees/ArrayTypeDenoter.java | 44 + .../AbstractSyntaxTrees/AssignCommand.java | 33 + .../AbstractSyntaxTrees/BinaryExpression.java | 35 + .../BinaryOperatorDeclaration.java | 37 + .../AbstractSyntaxTrees/BoolTypeDenoter.java | 35 + .../AbstractSyntaxTrees/CallCommand.java | 34 + .../AbstractSyntaxTrees/CallExpression.java | 34 + .../AbstractSyntaxTrees/CharTypeDenoter.java | 35 + .../CharacterExpression.java | 31 + .../AbstractSyntaxTrees/CharacterLiteral.java | 29 + .../Triangle/AbstractSyntaxTrees/Command.java | 24 + .../ConstActualParameter.java | 31 + .../AbstractSyntaxTrees/ConstDeclaration.java | 34 + .../ConstFormalParameter.java | 42 + .../AbstractSyntaxTrees/Declaration.java | 27 + .../AbstractSyntaxTrees/DotVname.java | 33 + .../EmptyActualParameterSequence.java | 28 + .../AbstractSyntaxTrees/EmptyCommand.java | 28 + .../AbstractSyntaxTrees/EmptyExpression.java | 28 + .../EmptyFormalParameterSequence.java | 32 + .../AbstractSyntaxTrees/ErrorTypeDenoter.java | 32 + .../AbstractSyntaxTrees/Expression.java | 27 + .../AbstractSyntaxTrees/FieldTypeDenoter.java | 26 + .../AbstractSyntaxTrees/FormalParameter.java | 27 + .../FormalParameterSequence.java | 26 + .../FuncActualParameter.java | 31 + .../AbstractSyntaxTrees/FuncDeclaration.java | 39 + .../FuncFormalParameter.java | 44 + .../AbstractSyntaxTrees/Identifier.java | 33 + .../AbstractSyntaxTrees/IfCommand.java | 35 + .../AbstractSyntaxTrees/IfExpression.java | 34 + .../AbstractSyntaxTrees/IntTypeDenoter.java | 35 + .../IntegerExpression.java | 31 + .../AbstractSyntaxTrees/IntegerLiteral.java | 29 + .../AbstractSyntaxTrees/LetCommand.java | 33 + .../AbstractSyntaxTrees/LetExpression.java | 33 + .../MultipleActualParameterSequence.java | 34 + .../MultipleArrayAggregate.java | 34 + .../MultipleFieldTypeDenoter.java | 46 + .../MultipleFormalParameterSequence.java | 42 + .../MultipleRecordAggregate.java | 36 + .../AbstractSyntaxTrees/Operator.java | 31 + .../ProcActualParameter.java | 31 + .../AbstractSyntaxTrees/ProcDeclaration.java | 36 + .../ProcFormalParameter.java | 42 + .../Triangle/AbstractSyntaxTrees/Program.java | 31 + .../AbstractSyntaxTrees/RecordAggregate.java | 27 + .../AbstractSyntaxTrees/RecordExpression.java | 31 + .../RecordTypeDenoter.java | 40 + .../SequentialCommand.java | 32 + .../SequentialDeclaration.java | 33 + .../SimpleTypeDenoter.java | 35 + .../AbstractSyntaxTrees/SimpleVname.java | 31 + .../SingleActualParameterSequence.java | 32 + .../SingleArrayAggregate.java | 32 + .../SingleFieldTypeDenoter.java | 43 + .../SingleFormalParameterSequence.java | 40 + .../SingleRecordAggregate.java | 34 + .../AbstractSyntaxTrees/SubscriptVname.java | 33 + .../AbstractSyntaxTrees/Terminal.java | 27 + .../AbstractSyntaxTrees/TypeDeclaration.java | 34 + .../AbstractSyntaxTrees/TypeDenoter.java | 27 + .../AbstractSyntaxTrees/UnaryExpression.java | 34 + .../UnaryOperatorDeclaration.java | 35 + .../VarActualParameter.java | 31 + .../AbstractSyntaxTrees/VarDeclaration.java | 34 + .../VarFormalParameter.java | 42 + .../Triangle/AbstractSyntaxTrees/Visitor.java | 154 +++ .../Triangle/AbstractSyntaxTrees/Vname.java | 30 + .../AbstractSyntaxTrees/VnameExpression.java | 31 + .../AbstractSyntaxTrees/WhileCommand.java | 33 + .../java/Triangle/CodeGenerator/Encoder.java | 983 ++++++++++++++++++ .../CodeGenerator/EqualityRoutine.java | 30 + .../java/Triangle/CodeGenerator/Field.java | 31 + .../java/Triangle/CodeGenerator/Frame.java | 46 + .../Triangle/CodeGenerator/KnownAddress.java | 31 + .../Triangle/CodeGenerator/KnownRoutine.java | 31 + .../Triangle/CodeGenerator/KnownValue.java | 31 + .../Triangle/CodeGenerator/ObjectAddress.java | 26 + .../CodeGenerator/PrimitiveRoutine.java | 31 + .../Triangle/CodeGenerator/RuntimeEntity.java | 33 + .../CodeGenerator/TypeRepresentation.java | 23 + .../CodeGenerator/UnknownAddress.java | 31 + .../CodeGenerator/UnknownRoutine.java | 31 + .../Triangle/CodeGenerator/UnknownValue.java | 31 + .../src/main/java/Triangle/Compiler.java | 127 +++ .../Triangle/ContextualAnalyzer/Checker.java | 951 +++++++++++++++++ .../Triangle/ContextualAnalyzer/IdEntry.java | 33 + .../IdentificationTable.java | 108 ++ .../src/main/java/Triangle/ErrorReporter.java | 42 + .../main/java/Triangle/StdEnvironment.java | 47 + .../Triangle/SyntacticAnalyzer/Parser.java | 933 +++++++++++++++++ .../Triangle/SyntacticAnalyzer/Scanner.java | 273 +++++ .../SyntacticAnalyzer/SourceFile.java | 56 + .../SyntacticAnalyzer/SourcePosition.java | 34 + .../SyntacticAnalyzer/SyntaxError.java | 27 + .../Triangle/SyntacticAnalyzer/Token.java | 148 +++ .../main/java/Triangle/TreeDrawer/Drawer.java | 61 ++ .../java/Triangle/TreeDrawer/DrawerFrame.java | 49 + .../java/Triangle/TreeDrawer/DrawerPanel.java | 34 + .../java/Triangle/TreeDrawer/DrawingTree.java | 88 ++ .../Triangle/TreeDrawer/LayoutVisitor.java | 533 ++++++++++ .../java/Triangle/TreeDrawer/Polygon.java | 20 + .../java/Triangle/TreeDrawer/Polyline.java | 26 + pom.xml | 19 + 122 files changed, 8977 insertions(+) create mode 100644 .vscode/settings.json create mode 100644 Triangle.AbstractMachine.Disassembler/pom.xml create mode 100644 Triangle.AbstractMachine.Disassembler/src/main/java/Triangle/AbstractMachine/Disassembler.java create mode 100644 Triangle.AbstractMachine.Interpreter/pom.xml create mode 100644 Triangle.AbstractMachine.Interpreter/src/main/java/Triangle/AbstractMachine/Interpreter.java create mode 100644 Triangle.AbstractMachine/pom.xml create mode 100644 Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Instruction.java create mode 100644 Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Machine.java create mode 100644 Triangle.AbstractMachine/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst create mode 100644 Triangle.Compiler/.editorconfig create mode 100644 Triangle.Compiler/pom.xml create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AST.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ActualParameter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ActualParameterSequence.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AnyTypeDenoter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayAggregate.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayExpression.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayTypeDenoter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AssignCommand.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BinaryExpression.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BinaryOperatorDeclaration.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BoolTypeDenoter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CallCommand.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CallExpression.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharTypeDenoter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharacterExpression.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharacterLiteral.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Command.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstActualParameter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstDeclaration.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstFormalParameter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Declaration.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/DotVname.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyActualParameterSequence.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyCommand.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyExpression.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyFormalParameterSequence.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ErrorTypeDenoter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Expression.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FieldTypeDenoter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FormalParameter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FormalParameterSequence.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncActualParameter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncDeclaration.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncFormalParameter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Identifier.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IfCommand.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IfExpression.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntTypeDenoter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntegerExpression.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntegerLiteral.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/LetCommand.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/LetExpression.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleActualParameterSequence.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleArrayAggregate.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFieldTypeDenoter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFormalParameterSequence.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleRecordAggregate.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Operator.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcActualParameter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcDeclaration.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcFormalParameter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Program.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordAggregate.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordExpression.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordTypeDenoter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialCommand.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialDeclaration.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SimpleTypeDenoter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SimpleVname.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleActualParameterSequence.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleArrayAggregate.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFieldTypeDenoter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFormalParameterSequence.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleRecordAggregate.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SubscriptVname.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Terminal.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/TypeDeclaration.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/TypeDenoter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/UnaryExpression.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/UnaryOperatorDeclaration.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarActualParameter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarDeclaration.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarFormalParameter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Visitor.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Vname.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VnameExpression.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/WhileCommand.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Encoder.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/CodeGenerator/EqualityRoutine.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Field.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Frame.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownAddress.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownRoutine.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownValue.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/CodeGenerator/ObjectAddress.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/CodeGenerator/PrimitiveRoutine.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/CodeGenerator/RuntimeEntity.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/CodeGenerator/TypeRepresentation.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownAddress.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownRoutine.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownValue.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/Compiler.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/Checker.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdEntry.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdentificationTable.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/ErrorReporter.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/StdEnvironment.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Parser.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Scanner.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourceFile.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourcePosition.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SyntaxError.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Token.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Drawer.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerFrame.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerPanel.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawingTree.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/TreeDrawer/LayoutVisitor.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Polygon.java create mode 100644 Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Polyline.java create mode 100644 pom.xml diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c4abd8b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,18 @@ +{ + "cSpell.words": [ + "actuals", + "Analyser", + "Denoter", + "DENOTERS", + "Deryck", + "geteol", + "getint", + "maxint", + "notgreater", + "notless", + "puteol", + "putint", + "Vname" + ], + "java.configuration.updateBuildConfiguration": "automatic" +} \ No newline at end of file diff --git a/Triangle.AbstractMachine.Disassembler/pom.xml b/Triangle.AbstractMachine.Disassembler/pom.xml new file mode 100644 index 0000000..0b94ffb --- /dev/null +++ b/Triangle.AbstractMachine.Disassembler/pom.xml @@ -0,0 +1,20 @@ + + 4.0.0 + triangle.tools + triangle-disassembler + 2.1 + + triangle.tools + triangle-tools + 2.1 + ../ + + + + triangle.tools + triangle-abstractmachine + 2.1 + + + diff --git a/Triangle.AbstractMachine.Disassembler/src/main/java/Triangle/AbstractMachine/Disassembler.java b/Triangle.AbstractMachine.Disassembler/src/main/java/Triangle/AbstractMachine/Disassembler.java new file mode 100644 index 0000000..8bda415 --- /dev/null +++ b/Triangle.AbstractMachine.Disassembler/src/main/java/Triangle/AbstractMachine/Disassembler.java @@ -0,0 +1,398 @@ +/* + * @(#)Disassembler.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractMachine; + +import java.io.DataInputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; + +/** + * Disassembles the TAM code in the given file, and displays the + * instructions on standard output. + * + * For example: + * + *
+ *   java TAM.Disassembler obj.tam
+ * 
+ * + *

+ * Copyright 1991 David A. Watt, University of Glasgow
+ * Copyright 1998 Deryck F. Brown, The Robert Gordon University
+ *

+ * + */ + +public class Disassembler { + + static String objectName; + + static int CT; + + /** + * Writes the r-field of an instruction in the form "lregr", where + * l and r are the bracket characters to use. + * + * @param leftbracket the character to print before the register. + * @param r the number of the register. + * @param rightbracket the character to print after the register. + */ + private static void writeR(char leftbracket, int r, char rightbracket) { + + System.out.print(leftbracket); + switch (r) { + case Machine.CBr: + System.out.print("CB"); + break; + case Machine.CTr: + System.out.print("CT"); + break; + case Machine.PBr: + System.out.print("PB"); + break; + case Machine.PTr: + System.out.print("PT"); + break; + case Machine.SBr: + System.out.print("SB"); + break; + case Machine.STr: + System.out.print("ST"); + break; + case Machine.HBr: + System.out.print("HB"); + break; + case Machine.HTr: + System.out.print("HT"); + break; + case Machine.LBr: + System.out.print("LB"); + break; + case Machine.L1r: + System.out.print("L1"); + break; + case Machine.L2r: + System.out.print("L2"); + break; + case Machine.L3r: + System.out.print("L3"); + break; + case Machine.L4r: + System.out.print("L4"); + break; + case Machine.L5r: + System.out.print("L5"); + break; + case Machine.L6r: + System.out.print("L6"); + break; + case Machine.CPr: + System.out.print("CP"); + break; + } + System.out.print(rightbracket); + } + + /** + * Writes a void n-field of an instruction. + */ + private static void blankN() { + System.out.print(" "); + } + + // Writes the n-field of an instruction. + /** + * Writes the n-field of an instruction in the form "(n)". + * + * @param n the integer to write. + */ + private static void writeN(int n) { + System.out.print("(" + n + ") "); + if (n < 10) + System.out.print(" "); + else if (n < 100) + System.out.print(" "); + } + + /** + * Writes the d-field of an instruction. + * + * @param d the integer to write. + */ + private static void writeD(int d) { + System.out.print(d); + } + + /** + * Writes the name of primitive routine with relative address d. + * + * @param d the displacment of the primitive routine. + */ + private static void writePrimitive(int d) { + switch (d) { + case Machine.idDisplacement: + System.out.print("id "); + break; + case Machine.notDisplacement: + System.out.print("not "); + break; + case Machine.andDisplacement: + System.out.print("and "); + break; + case Machine.orDisplacement: + System.out.print("or "); + break; + case Machine.succDisplacement: + System.out.print("succ "); + break; + case Machine.predDisplacement: + System.out.print("pred "); + break; + case Machine.negDisplacement: + System.out.print("neg "); + break; + case Machine.addDisplacement: + System.out.print("add "); + break; + case Machine.subDisplacement: + System.out.print("sub "); + break; + case Machine.multDisplacement: + System.out.print("mult "); + break; + case Machine.divDisplacement: + System.out.print("div "); + break; + case Machine.modDisplacement: + System.out.print("mod "); + break; + case Machine.ltDisplacement: + System.out.print("lt "); + break; + case Machine.leDisplacement: + System.out.print("le "); + break; + case Machine.geDisplacement: + System.out.print("ge "); + break; + case Machine.gtDisplacement: + System.out.print("gt "); + break; + case Machine.eqDisplacement: + System.out.print("eq "); + break; + case Machine.neDisplacement: + System.out.print("ne "); + break; + case Machine.eolDisplacement: + System.out.print("eol "); + break; + case Machine.eofDisplacement: + System.out.print("eof "); + break; + case Machine.getDisplacement: + System.out.print("get "); + break; + case Machine.putDisplacement: + System.out.print("put "); + break; + case Machine.geteolDisplacement: + System.out.print("geteol "); + break; + case Machine.puteolDisplacement: + System.out.print("puteol "); + break; + case Machine.getintDisplacement: + System.out.print("getint "); + break; + case Machine.putintDisplacement: + System.out.print("putint "); + break; + case Machine.newDisplacement: + System.out.print("new "); + break; + case Machine.disposeDisplacement: + System.out.print("dispose "); + break; + } + } + + /** + * Writes the given instruction in assembly-code format. + * + * @param instr the instruction to display. + */ + private static void writeInstruction(Instruction instr) { + + switch (instr.op) { + case Machine.LOADop: + System.out.print("LOAD "); + writeN(instr.n); + writeD(instr.d); + writeR('[', instr.r, ']'); + break; + + case Machine.LOADAop: + System.out.print("LOADA "); + blankN(); + writeD(instr.d); + writeR('[', instr.r, ']'); + break; + + case Machine.LOADIop: + System.out.print("LOADI "); + writeN(instr.n); + break; + + case Machine.LOADLop: + System.out.print("LOADL "); + blankN(); + writeD(instr.d); + break; + + case Machine.STOREop: + System.out.print("STORE "); + writeN(instr.n); + writeD(instr.d); + writeR('[', instr.r, ']'); + break; + + case Machine.STOREIop: + System.out.print("STOREI"); + writeN(instr.n); + break; + + case Machine.CALLop: + System.out.print("CALL "); + if (instr.r == Machine.PBr) { + blankN(); + writePrimitive(instr.d); + } else { + writeR('(', instr.n, ')'); + System.out.print(" "); + writeD(instr.d); + writeR('[', instr.r, ']'); + } + break; + + case Machine.CALLIop: + System.out.print("CALLI "); + break; + + case Machine.RETURNop: + System.out.print("RETURN"); + writeN(instr.n); + writeD(instr.d); + break; + + case Machine.PUSHop: + System.out.print("PUSH "); + blankN(); + writeD(instr.d); + break; + + case Machine.POPop: + System.out.print("POP "); + writeN(instr.n); + writeD(instr.d); + break; + + case Machine.JUMPop: + System.out.print("JUMP "); + blankN(); + writeD(instr.d); + writeR('[', instr.r, ']'); + break; + + case Machine.JUMPIop: + System.out.print("JUMPI "); + break; + + case Machine.JUMPIFop: + System.out.print("JUMPIF"); + writeN(instr.n); + writeD(instr.d); + writeR('[', instr.r, ']'); + break; + + case Machine.HALTop: + System.out.print("HALT "); + } + } + + /** + * Writes all instructions of the program in code store. + */ + private static void disassembleProgram() { + for (int addr = Machine.CB; addr < CT; addr++) { + System.out.print(addr + ": "); + writeInstruction(Machine.code[addr]); + System.out.println(); + } + } + + // LOADING + + /** + * Loads the TAM object program into code store from the named file. + * + * @param objectName the name of the file containing the program. + */ + static void loadObjectProgram(String objectName) { + + FileInputStream objectFile = null; + DataInputStream objectStream = null; + + int addr; + boolean finished = false; + + try { + objectFile = new FileInputStream(objectName); + objectStream = new DataInputStream(objectFile); + + addr = Machine.CB; + while (!finished) { + Machine.code[addr] = Instruction.read(objectStream); + if (Machine.code[addr] == null) + finished = true; + else + addr = addr + 1; + } + CT = addr; + objectFile.close(); + } catch (FileNotFoundException s) { + CT = Machine.CB; + System.err.println("Error opening object file: " + s); + } catch (IOException s) { + CT = Machine.CB; + System.err.println("Error reading object file: " + s); + } + } + + // DISASSEMBLE + + public static void main(String[] args) { + System.out.println("********** TAM Disassembler (Sun Version 2.1) **********"); + + if (args.length == 1) + objectName = args[0]; + else + objectName = "obj.tam"; + + loadObjectProgram(objectName); + disassembleProgram(); + } +} diff --git a/Triangle.AbstractMachine.Interpreter/pom.xml b/Triangle.AbstractMachine.Interpreter/pom.xml new file mode 100644 index 0000000..70dc42c --- /dev/null +++ b/Triangle.AbstractMachine.Interpreter/pom.xml @@ -0,0 +1,20 @@ + + 4.0.0 + triangle.tools + triangle-interpreter + 2.1 + + triangle.tools + triangle-tools + 2.1 + ../ + + + + triangle.tools + triangle-abstractmachine + 2.1 + + + diff --git a/Triangle.AbstractMachine.Interpreter/src/main/java/Triangle/AbstractMachine/Interpreter.java b/Triangle.AbstractMachine.Interpreter/src/main/java/Triangle/AbstractMachine/Interpreter.java new file mode 100644 index 0000000..1adbb4c --- /dev/null +++ b/Triangle.AbstractMachine.Interpreter/src/main/java/Triangle/AbstractMachine/Interpreter.java @@ -0,0 +1,620 @@ +/* + * @(#)Interpreter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractMachine; + +import java.io.DataInputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; + +public class Interpreter { + + static String objectName; + + // DATA STORE + + static int[] data = new int[1024]; + + // DATA STORE REGISTERS AND OTHER REGISTERS + + final static int CB = 0, + SB = 0, + HB = 1024; // = upper bound of data array + 1 + + static int CT, CP, ST, HT, LB, status; + + // status values + final static int running = 0, halted = 1, failedDataStoreFull = 2, failedInvalidCodeAddress = 3, + failedInvalidInstruction = 4, failedOverflow = 5, failedZeroDivide = 6, + failedIOError = 7; + + static long accumulator; + + static int content(int r) { + // Returns the current content of register r, + // even if r is one of the pseudo-registers L1..L6. + + switch (r) { + case Machine.CBr: + return CB; + case Machine.CTr: + return CT; + case Machine.PBr: + return Machine.PB; + case Machine.PTr: + return Machine.PT; + case Machine.SBr: + return SB; + case Machine.STr: + return ST; + case Machine.HBr: + return HB; + case Machine.HTr: + return HT; + case Machine.LBr: + return LB; + case Machine.L1r: + return data[LB]; + case Machine.L2r: + return data[data[LB]]; + case Machine.L3r: + return data[data[data[LB]]]; + case Machine.L4r: + return data[data[data[data[LB]]]]; + case Machine.L5r: + return data[data[data[data[data[LB]]]]]; + case Machine.L6r: + return data[data[data[data[data[data[LB]]]]]]; + case Machine.CPr: + return CP; + default: + return 0; + } + } + + // PROGRAM STATUS + + static void dump() { + // Writes a summary of the machine state. + int addr, staticLink, dynamicLink, + localRegNum; + + System.out.println(""); + System.out.println("State of data store and registers:"); + System.out.println(""); + if (HT == HB) + System.out.println(" |--------| (heap is empty)"); + else { + System.out.println(" HB-->"); + System.out.println(" |--------|"); + for (addr = HB - 1; addr >= HT; addr--) { + System.out.print(addr + ":"); + if (addr == HT) + System.out.print(" HT-->"); + else + System.out.print(" "); + System.out.println("|" + data[addr] + "|"); + } + System.out.println(" |--------|"); + } + System.out.println(" |////////|"); + System.out.println(" |////////|"); + if (ST == SB) + System.out.println(" |--------| (stack is empty)"); + else { + dynamicLink = LB; + staticLink = LB; + localRegNum = Machine.LBr; + System.out.println(" ST--> |////////|"); + System.out.println(" |--------|"); + for (addr = ST - 1; addr >= SB; addr--) { + System.out.print(addr + ":"); + if (addr == SB) + System.out.print(" SB-->"); + else if (addr == staticLink) { + switch (localRegNum) { + case Machine.LBr: + System.out.print(" LB-->"); + break; + case Machine.L1r: + System.out.print(" L1-->"); + break; + case Machine.L2r: + System.out.print(" L2-->"); + break; + case Machine.L3r: + System.out.print(" L3-->"); + break; + case Machine.L4r: + System.out.print(" L4-->"); + break; + case Machine.L5r: + System.out.print(" L5-->"); + break; + case Machine.L6r: + System.out.print(" L6-->"); + break; + } + staticLink = data[addr]; + localRegNum = localRegNum + 1; + } else + System.out.print(" "); + if ((addr == dynamicLink) && (dynamicLink != SB)) + System.out.print("|SL=" + data[addr] + "|"); + else if ((addr == dynamicLink + 1) && (dynamicLink != SB)) + System.out.print("|DL=" + data[addr] + "|"); + else if ((addr == dynamicLink + 2) && (dynamicLink != SB)) + System.out.print("|RA=" + data[addr] + "|"); + else + System.out.print("|" + data[addr] + "|"); + System.out.println(""); + if (addr == dynamicLink) { + System.out.println(" |--------|"); + dynamicLink = data[addr + 1]; + } + } + } + System.out.println(""); + } + + static void showStatus() { + // Writes an indication of whether and why the program has terminated. + System.out.println(""); + switch (status) { + case running: + System.out.println("Program is running."); + break; + case halted: + System.out.println("Program has halted normally."); + break; + case failedDataStoreFull: + System.out.println("Program has failed due to exhaustion of Data Store."); + break; + case failedInvalidCodeAddress: + System.out.println("Program has failed due to an invalid code address."); + break; + case failedInvalidInstruction: + System.out.println("Program has failed due to an invalid instruction."); + break; + case failedOverflow: + System.out.println("Program has failed due to overflow."); + break; + case failedZeroDivide: + System.out.println("Program has failed due to division by zero."); + break; + case failedIOError: + System.out.println("Program has failed due to an IO error."); + break; + } + if (status != halted) + dump(); + } + + // INTERPRETATION + + static void checkSpace(int spaceNeeded) { + // Signals failure if there is not enough space to expand the stack or + // heap by spaceNeeded. + + if (HT - ST < spaceNeeded) + status = failedDataStoreFull; + } + + static boolean isTrue(int datum) { + // Tests whether the given datum represents true. + return (datum == Machine.trueRep); + } + + static boolean equal(int size, int addr1, int addr2) { + // Tests whether two multi-word objects are equal, given their common + // size and their base addresses. + + boolean eq; + int index; + + eq = true; + index = 0; + while (eq && (index < size)) + if (data[addr1 + index] == data[addr2 + index]) + index = index + 1; + else + eq = false; + return eq; + } + + static int overflowChecked(long datum) { + // Signals failure if the datum is too large to fit into a single word, + // otherwise returns the datum as a single word. + + if ((-Machine.maxintRep <= datum) && (datum <= Machine.maxintRep)) + return (int) datum; + else { + status = failedOverflow; + return 0; + } + } + + static int toInt(boolean b) { + return b ? Machine.trueRep : Machine.falseRep; + } + + static int currentChar; + + static int readInt() throws java.io.IOException { + int temp = 0; + int sign = 1; + + do { + currentChar = System.in.read(); + } while (Character.isWhitespace((char) currentChar)); + + if ((currentChar == '-') || (currentChar == '+')) + do { + sign = (currentChar == '-') ? -1 : 1; + currentChar = System.in.read(); + } while ((currentChar == '-') || currentChar == '+'); + + if (Character.isDigit((char) currentChar)) + do { + temp = temp * 10 + (currentChar - '0'); + currentChar = System.in.read(); + } while (Character.isDigit((char) currentChar)); + + return sign * temp; + } + + static void callPrimitive(int primitiveDisplacement) { + // Invokes the given primitive routine. + + int addr, size; + char ch; + + switch (primitiveDisplacement) { + case Machine.idDisplacement: + break; // nothing to be done + case Machine.notDisplacement: + data[ST - 1] = toInt(!isTrue(data[ST - 1])); + break; + case Machine.andDisplacement: + ST = ST - 1; + data[ST - 1] = toInt(isTrue(data[ST - 1]) & isTrue(data[ST])); + break; + case Machine.orDisplacement: + ST = ST - 1; + data[ST - 1] = toInt(isTrue(data[ST - 1]) | isTrue(data[ST])); + break; + case Machine.succDisplacement: + data[ST - 1] = overflowChecked(data[ST - 1] + 1); + break; + case Machine.predDisplacement: + data[ST - 1] = overflowChecked(data[ST - 1] - 1); + break; + case Machine.negDisplacement: + data[ST - 1] = -data[ST - 1]; + break; + case Machine.addDisplacement: + ST = ST - 1; + accumulator = data[ST - 1]; + data[ST - 1] = overflowChecked(accumulator + data[ST]); + break; + case Machine.subDisplacement: + ST = ST - 1; + accumulator = data[ST - 1]; + data[ST - 1] = overflowChecked(accumulator - data[ST]); + break; + case Machine.multDisplacement: + ST = ST - 1; + accumulator = data[ST - 1]; + data[ST - 1] = overflowChecked(accumulator * data[ST]); + break; + case Machine.divDisplacement: + ST = ST - 1; + accumulator = data[ST - 1]; + if (data[ST] != 0) + data[ST - 1] = (int) (accumulator / data[ST]); + else + status = failedZeroDivide; + break; + case Machine.modDisplacement: + ST = ST - 1; + accumulator = data[ST - 1]; + if (data[ST] != 0) + data[ST - 1] = (int) (accumulator % data[ST]); + else + status = failedZeroDivide; + break; + case Machine.ltDisplacement: + ST = ST - 1; + data[ST - 1] = toInt(data[ST - 1] < data[ST]); + break; + case Machine.leDisplacement: + ST = ST - 1; + data[ST - 1] = toInt(data[ST - 1] <= data[ST]); + break; + case Machine.geDisplacement: + ST = ST - 1; + data[ST - 1] = toInt(data[ST - 1] >= data[ST]); + break; + case Machine.gtDisplacement: + ST = ST - 1; + data[ST - 1] = toInt(data[ST - 1] > data[ST]); + break; + case Machine.eqDisplacement: + size = data[ST - 1]; // size of each comparand + ST = ST - 2 * size; + data[ST - 1] = toInt(equal(size, ST - 1, ST - 1 + size)); + break; + case Machine.neDisplacement: + size = data[ST - 1]; // size of each comparand + ST = ST - 2 * size; + data[ST - 1] = toInt(!equal(size, ST - 1, ST - 1 + size)); + break; + case Machine.eolDisplacement: + data[ST] = toInt(currentChar == '\n'); + ST = ST + 1; + break; + case Machine.eofDisplacement: + data[ST] = toInt(currentChar == -1); + ST = ST + 1; + break; + case Machine.getDisplacement: + ST = ST - 1; + addr = data[ST]; + try { + currentChar = System.in.read(); + } catch (java.io.IOException s) { + status = failedIOError; + } + data[addr] = (int) currentChar; + break; + case Machine.putDisplacement: + ST = ST - 1; + ch = (char) data[ST]; + System.out.print(ch); + break; + case Machine.geteolDisplacement: + try { + while ((currentChar = System.in.read()) != '\n') + ; + } catch (java.io.IOException s) { + status = failedIOError; + } + break; + case Machine.puteolDisplacement: + System.out.println(""); + break; + case Machine.getintDisplacement: + ST = ST - 1; + addr = data[ST]; + try { + accumulator = readInt(); + } catch (java.io.IOException s) { + status = failedIOError; + } + data[addr] = (int) accumulator; + break; + case Machine.putintDisplacement: + ST = ST - 1; + accumulator = data[ST]; + System.out.print(accumulator); + break; + case Machine.newDisplacement: + size = data[ST - 1]; + checkSpace(size); + HT = HT - size; + data[ST - 1] = HT; + break; + case Machine.disposeDisplacement: + ST = ST - 1; // no action taken at present + break; + } + } + + static void interpretProgram() { + // Runs the program in code store. + + Instruction currentInstr; + int op, r, n, d, addr, index; + + // Initialize registers ... + ST = SB; + HT = HB; + LB = SB; + CP = CB; + status = running; + do { + // Fetch instruction ... + currentInstr = Machine.code[CP]; + // Decode instruction ... + op = currentInstr.op; + r = currentInstr.r; + n = currentInstr.n; + d = currentInstr.d; + // Execute instruction ... + switch (op) { + case Machine.LOADop: + addr = d + content(r); + checkSpace(n); + for (index = 0; index < n; index++) + data[ST + index] = data[addr + index]; + ST = ST + n; + CP = CP + 1; + break; + case Machine.LOADAop: + addr = d + content(r); + checkSpace(1); + data[ST] = addr; + ST = ST + 1; + CP = CP + 1; + break; + case Machine.LOADIop: + ST = ST - 1; + addr = data[ST]; + checkSpace(n); + for (index = 0; index < n; index++) + data[ST + index] = data[addr + index]; + ST = ST + n; + CP = CP + 1; + break; + case Machine.LOADLop: + checkSpace(1); + data[ST] = d; + ST = ST + 1; + CP = CP + 1; + break; + case Machine.STOREop: + addr = d + content(r); + ST = ST - n; + for (index = 0; index < n; index++) + data[addr + index] = data[ST + index]; + CP = CP + 1; + break; + case Machine.STOREIop: + ST = ST - 1; + addr = data[ST]; + ST = ST - n; + for (index = 0; index < n; index++) + data[addr + index] = data[ST + index]; + CP = CP + 1; + break; + case Machine.CALLop: + addr = d + content(r); + if (addr >= Machine.PB) { + callPrimitive(addr - Machine.PB); + CP = CP + 1; + } else { + checkSpace(3); + if ((0 <= n) && (n <= 15)) + data[ST] = content(n); // static link + else + status = failedInvalidInstruction; + data[ST + 1] = LB; // dynamic link + data[ST + 2] = CP + 1; // return address + LB = ST; + ST = ST + 3; + CP = addr; + } + break; + case Machine.CALLIop: + ST = ST - 2; + addr = data[ST + 1]; + if (addr >= Machine.PB) { + callPrimitive(addr - Machine.PB); + CP = CP + 1; + } else { + // data[ST] = static link already + data[ST + 1] = LB; // dynamic link + data[ST + 2] = CP + 1; // return address + LB = ST; + ST = ST + 3; + CP = addr; + } + break; + case Machine.RETURNop: + addr = LB - d; + CP = data[LB + 2]; + LB = data[LB + 1]; + ST = ST - n; + for (index = 0; index < n; index++) + data[addr + index] = data[ST + index]; + ST = addr + n; + break; + case Machine.PUSHop: + checkSpace(d); + ST = ST + d; + CP = CP + 1; + break; + case Machine.POPop: + addr = ST - n - d; + ST = ST - n; + for (index = 0; index < n; index++) + data[addr + index] = data[ST + index]; + ST = addr + n; + CP = CP + 1; + break; + case Machine.JUMPop: + CP = d + content(r); + break; + case Machine.JUMPIop: + ST = ST - 1; + CP = data[ST]; + break; + case Machine.JUMPIFop: + ST = ST - 1; + if (data[ST] == n) + CP = d + content(r); + else + CP = CP + 1; + break; + case Machine.HALTop: + status = halted; + break; + } + if ((CP < CB) || (CP >= CT)) + status = failedInvalidCodeAddress; + } while (status == running); + } + + // LOADING + + static void loadObjectProgram(String objectName) { + // Loads the TAM object program into code store from the named file. + + FileInputStream objectFile = null; + DataInputStream objectStream = null; + + int addr; + boolean finished = false; + + try { + objectFile = new FileInputStream(objectName); + objectStream = new DataInputStream(objectFile); + + addr = Machine.CB; + while (!finished) { + Machine.code[addr] = Instruction.read(objectStream); + if (Machine.code[addr] == null) + finished = true; + else + addr = addr + 1; + } + CT = addr; + objectFile.close(); + } catch (FileNotFoundException s) { + CT = CB; + System.err.println("Error opening object file: " + s); + } catch (IOException s) { + CT = CB; + System.err.println("Error reading object file: " + s); + } + } + + // RUNNING + + public static void main(String[] args) { + System.out.println("********** TAM Interpreter (Java Version 2.1) **********"); + + if (args.length == 1) + objectName = args[0]; + else + objectName = "obj.tam"; + + loadObjectProgram(objectName); + if (CT != CB) { + interpretProgram(); + showStatus(); + } + } +} diff --git a/Triangle.AbstractMachine/pom.xml b/Triangle.AbstractMachine/pom.xml new file mode 100644 index 0000000..c2d2726 --- /dev/null +++ b/Triangle.AbstractMachine/pom.xml @@ -0,0 +1,14 @@ + + 4.0.0 + triangle.tools + triangle-abstractmachine + 2.1 + jar + + triangle.tools + triangle-tools + 2.1 + ../ + + \ No newline at end of file diff --git a/Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Instruction.java b/Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Instruction.java new file mode 100644 index 0000000..785583a --- /dev/null +++ b/Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Instruction.java @@ -0,0 +1,64 @@ +/* + * @(#)Instruction.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractMachine; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.EOFException; +import java.io.IOException; + +public class Instruction { + + public Instruction() { + op = 0; + r = 0; + n = 0; + d = 0; + } + + // Java has no type synonyms, so the following representations are + // assumed: + // + // type + // OpCode = 0..15; {4 bits unsigned} + // Length = 0..255; {8 bits unsigned} + // Operand = -32767..+32767; {16 bits signed} + + // Represents TAM instructions. + public int op; // OpCode + public int r; // RegisterNumber + public int n; // Length + public int d; // Operand + + public void write(DataOutputStream output) throws IOException { + output.writeInt(op); + output.writeInt(r); + output.writeInt(n); + output.writeInt(d); + } + + public static Instruction read(DataInputStream input) throws IOException { + Instruction inst = new Instruction(); + try { + inst.op = input.readInt(); + inst.r = input.readInt(); + inst.n = input.readInt(); + inst.d = input.readInt(); + return inst; + } catch (EOFException s) { + return null; + } + } +} diff --git a/Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Machine.java b/Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Machine.java new file mode 100644 index 0000000..65e13a3 --- /dev/null +++ b/Triangle.AbstractMachine/src/main/java/Triangle/AbstractMachine/Machine.java @@ -0,0 +1,125 @@ +/* + * @(#)Machine.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractMachine; + +public final class Machine { + + public final static int maxRoutineLevel = 7; + + // WORDS AND ADDRESSES + + // Java has no type synonyms, so the following representations are + // assumed: + // + // type + // Word = -32767..+32767; {16 bits signed} + // DoubleWord = -2147483648..+2147483647; {32 bits signed} + // CodeAddress = 0..+32767; {15 bits unsigned} + // DataAddress = 0..+32767; {15 bits unsigned} + + // INSTRUCTIONS + + // Operation codes + public final static int LOADop = 0, + LOADAop = 1, + LOADIop = 2, + LOADLop = 3, + STOREop = 4, + STOREIop = 5, + CALLop = 6, + CALLIop = 7, + RETURNop = 8, + PUSHop = 10, + POPop = 11, + JUMPop = 12, + JUMPIop = 13, + JUMPIFop = 14, + HALTop = 15; + + // CODE STORE + + public static Instruction[] code = new Instruction[1024]; + + // CODE STORE REGISTERS + + public final static int CB = 0, + PB = 1024, // = upper bound of code array + 1 + PT = 1052; // = PB + 28 + + // REGISTER NUMBERS + + public final static int CBr = 0, + CTr = 1, + PBr = 2, + PTr = 3, + SBr = 4, + STr = 5, + HBr = 6, + HTr = 7, + LBr = 8, + L1r = LBr + 1, + L2r = LBr + 2, + L3r = LBr + 3, + L4r = LBr + 4, + L5r = LBr + 5, + L6r = LBr + 6, + CPr = 15; + + // DATA REPRESENTATION + + public final static int booleanSize = 1, + characterSize = 1, + integerSize = 1, + addressSize = 1, + closureSize = 2 * addressSize, + + linkDataSize = 3 * addressSize, + + falseRep = 0, + trueRep = 1, + maxintRep = 32767; + + // ADDRESSES OF PRIMITIVE ROUTINES + + public final static int idDisplacement = 1, + notDisplacement = 2, + andDisplacement = 3, + orDisplacement = 4, + succDisplacement = 5, + predDisplacement = 6, + negDisplacement = 7, + addDisplacement = 8, + subDisplacement = 9, + multDisplacement = 10, + divDisplacement = 11, + modDisplacement = 12, + ltDisplacement = 13, + leDisplacement = 14, + geDisplacement = 15, + gtDisplacement = 16, + eqDisplacement = 17, + neDisplacement = 18, + eolDisplacement = 19, + eofDisplacement = 20, + getDisplacement = 21, + putDisplacement = 22, + geteolDisplacement = 23, + puteolDisplacement = 24, + getintDisplacement = 25, + putintDisplacement = 26, + newDisplacement = 27, + disposeDisplacement = 28; + +} diff --git a/Triangle.AbstractMachine/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/Triangle.AbstractMachine/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..4de6135 --- /dev/null +++ b/Triangle.AbstractMachine/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,2 @@ +c:\Java\Repos\Triangle-Tools\Triangle.AbstractMachine\src\main\java\Triangle\AbstractMachine\Machine.java +c:\Java\Repos\Triangle-Tools\Triangle.AbstractMachine\src\main\java\Triangle\AbstractMachine\Instruction.java diff --git a/Triangle.Compiler/.editorconfig b/Triangle.Compiler/.editorconfig new file mode 100644 index 0000000..1f494b0 --- /dev/null +++ b/Triangle.Compiler/.editorconfig @@ -0,0 +1,17 @@ +# Editor configuration, see http://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true +max_line_length = 80 + +[*.sh] +end_of_line = lf + +[*.java] +indent_size = 4 +max_line_length = 120 diff --git a/Triangle.Compiler/pom.xml b/Triangle.Compiler/pom.xml new file mode 100644 index 0000000..c0828ab --- /dev/null +++ b/Triangle.Compiler/pom.xml @@ -0,0 +1,20 @@ + + 4.0.0 + triangle.tools + triangle-compiler + 2.1 + + triangle.tools + triangle-tools + 2.1 + ../ + + + + triangle.tools + triangle-abstractmachine + 2.1 + + + diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AST.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AST.java new file mode 100644 index 0000000..6f3857c --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AST.java @@ -0,0 +1,35 @@ +/* + * @(#)AST.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.CodeGenerator.RuntimeEntity; +import Triangle.SyntacticAnalyzer.SourcePosition; + +public abstract class AST { + + public AST(SourcePosition thePosition) { + position = thePosition; + entity = null; + } + + public SourcePosition getPosition() { + return position; + } + + public abstract Object visit(Visitor v, Object o); + + public SourcePosition position; + public RuntimeEntity entity; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ActualParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ActualParameter.java new file mode 100644 index 0000000..34cae48 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ActualParameter.java @@ -0,0 +1,24 @@ +/* + * @(#)ActualParameter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public abstract class ActualParameter extends AST { + + public ActualParameter(SourcePosition thePosition) { + super(thePosition); + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ActualParameterSequence.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ActualParameterSequence.java new file mode 100644 index 0000000..d99a36d --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ActualParameterSequence.java @@ -0,0 +1,24 @@ +/* + * @(#)ActualParameterSequence.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public abstract class ActualParameterSequence extends AST { + + public ActualParameterSequence(SourcePosition thePosition) { + super(thePosition); + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AnyTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AnyTypeDenoter.java new file mode 100644 index 0000000..72d719a --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AnyTypeDenoter.java @@ -0,0 +1,32 @@ +/* + * @(#)AnyTypeDenoter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class AnyTypeDenoter extends TypeDenoter { + + public AnyTypeDenoter(SourcePosition thePosition) { + super(thePosition); + } + + public Object visit(Visitor v, Object o) { + return v.visitAnyTypeDenoter(this, o); + } + + public boolean equals(Object obj) { + return false; + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayAggregate.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayAggregate.java new file mode 100644 index 0000000..811a35a --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayAggregate.java @@ -0,0 +1,27 @@ +/* + * @(#)ArrayAggregate.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public abstract class ArrayAggregate extends AST { + + public ArrayAggregate(SourcePosition thePosition) { + super(thePosition); + elemCount = 0; + } + + public int elemCount; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayExpression.java new file mode 100644 index 0000000..f2412dc --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayExpression.java @@ -0,0 +1,32 @@ +/* + * @(#)ArrayExpression.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class ArrayExpression extends Expression { + + public ArrayExpression(ArrayAggregate aaAST, + SourcePosition thePosition) { + super(thePosition); + AA = aaAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitArrayExpression(this, o); + } + + public ArrayAggregate AA; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayTypeDenoter.java new file mode 100644 index 0000000..5d08f5a --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ArrayTypeDenoter.java @@ -0,0 +1,44 @@ +/* + * @(#)ArrayTypeDenoter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class ArrayTypeDenoter extends TypeDenoter { + + public ArrayTypeDenoter(IntegerLiteral ilAST, TypeDenoter tAST, + SourcePosition thePosition) { + super(thePosition); + IL = ilAST; + T = tAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitArrayTypeDenoter(this, o); + } + + public boolean equals(Object obj) { + if (obj != null && obj instanceof ErrorTypeDenoter) + return true; + else if (obj != null && obj instanceof ArrayTypeDenoter) + return this.IL.spelling.compareTo(((ArrayTypeDenoter) obj).IL.spelling) == 0 && + this.T.equals(((ArrayTypeDenoter) obj).T); + else + return false; + } + + public IntegerLiteral IL; + public TypeDenoter T; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AssignCommand.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AssignCommand.java new file mode 100644 index 0000000..cf5ebe6 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/AssignCommand.java @@ -0,0 +1,33 @@ +/* + * @(#)AssignCommand.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class AssignCommand extends Command { + + public AssignCommand(Vname vAST, Expression eAST, SourcePosition thePosition) { + super(thePosition); + V = vAST; + E = eAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitAssignCommand(this, o); + } + + public Vname V; + public Expression E; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BinaryExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BinaryExpression.java new file mode 100644 index 0000000..bd39acc --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BinaryExpression.java @@ -0,0 +1,35 @@ +/* + * @(#)BinaryExpression.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class BinaryExpression extends Expression { + + public BinaryExpression(Expression e1AST, Operator oAST, Expression e2AST, + SourcePosition thePosition) { + super(thePosition); + O = oAST; + E1 = e1AST; + E2 = e2AST; + } + + public Object visit(Visitor v, Object o) { + return v.visitBinaryExpression(this, o); + } + + public Expression E1, E2; + public Operator O; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BinaryOperatorDeclaration.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BinaryOperatorDeclaration.java new file mode 100644 index 0000000..9f1dcbd --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BinaryOperatorDeclaration.java @@ -0,0 +1,37 @@ +/* + * @(#)BinaryOperatorDeclaration.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class BinaryOperatorDeclaration extends Declaration { + + public BinaryOperatorDeclaration(Operator oAST, TypeDenoter arg1AST, + TypeDenoter arg2AST, TypeDenoter resultAST, + SourcePosition thePosition) { + super(thePosition); + O = oAST; + ARG1 = arg1AST; + ARG2 = arg2AST; + RES = resultAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitBinaryOperatorDeclaration(this, o); + } + + public Operator O; + public TypeDenoter ARG1, ARG2, RES; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BoolTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BoolTypeDenoter.java new file mode 100644 index 0000000..2bb7846 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/BoolTypeDenoter.java @@ -0,0 +1,35 @@ +/* + * @(#)BoolTypeDenoter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class BoolTypeDenoter extends TypeDenoter { + + public BoolTypeDenoter(SourcePosition thePosition) { + super(thePosition); + } + + public Object visit(Visitor v, Object o) { + return v.visitBoolTypeDenoter(this, o); + } + + public boolean equals(Object obj) { + if ((obj != null) && (obj instanceof ErrorTypeDenoter)) + return true; + else + return ((obj != null) && (obj instanceof BoolTypeDenoter)); + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CallCommand.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CallCommand.java new file mode 100644 index 0000000..d0131d1 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CallCommand.java @@ -0,0 +1,34 @@ +/* + * @(#)CallCommand.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class CallCommand extends Command { + + public CallCommand(Identifier iAST, ActualParameterSequence apsAST, + SourcePosition thePosition) { + super(thePosition); + I = iAST; + APS = apsAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitCallCommand(this, o); + } + + public Identifier I; + public ActualParameterSequence APS; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CallExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CallExpression.java new file mode 100644 index 0000000..03d144c --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CallExpression.java @@ -0,0 +1,34 @@ +/* + * @(#)CallExpression.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class CallExpression extends Expression { + + public CallExpression(Identifier iAST, ActualParameterSequence apsAST, + SourcePosition thePosition) { + super(thePosition); + I = iAST; + APS = apsAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitCallExpression(this, o); + } + + public Identifier I; + public ActualParameterSequence APS; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharTypeDenoter.java new file mode 100644 index 0000000..147f68a --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharTypeDenoter.java @@ -0,0 +1,35 @@ +/* + * @(#)CharTypeDenoter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class CharTypeDenoter extends TypeDenoter { + + public CharTypeDenoter(SourcePosition thePosition) { + super(thePosition); + } + + public Object visit(Visitor v, Object o) { + return v.visitCharTypeDenoter(this, o); + } + + public boolean equals(Object obj) { + if (obj != null && obj instanceof ErrorTypeDenoter) + return true; + else + return (obj != null && obj instanceof CharTypeDenoter); + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharacterExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharacterExpression.java new file mode 100644 index 0000000..af34f81 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharacterExpression.java @@ -0,0 +1,31 @@ +/* + * @(#)CharacterExpression.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class CharacterExpression extends Expression { + + public CharacterExpression(CharacterLiteral clAST, SourcePosition thePosition) { + super(thePosition); + CL = clAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitCharacterExpression(this, o); + } + + public CharacterLiteral CL; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharacterLiteral.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharacterLiteral.java new file mode 100644 index 0000000..f586479 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/CharacterLiteral.java @@ -0,0 +1,29 @@ +/* + * @(#)CharacterLiteral.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class CharacterLiteral extends Terminal { + + public CharacterLiteral(String theSpelling, SourcePosition thePosition) { + super(theSpelling, thePosition); + } + + public Object visit(Visitor v, Object o) { + return v.visitCharacterLiteral(this, o); + } + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Command.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Command.java new file mode 100644 index 0000000..69acee0 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Command.java @@ -0,0 +1,24 @@ +/* + * @(#)Command.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public abstract class Command extends AST { + + public Command(SourcePosition thePosition) { + super(thePosition); + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstActualParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstActualParameter.java new file mode 100644 index 0000000..35d7f62 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstActualParameter.java @@ -0,0 +1,31 @@ +/* + * @(#)ConstActualParameter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class ConstActualParameter extends ActualParameter { + + public ConstActualParameter(Expression eAST, SourcePosition thePosition) { + super(thePosition); + E = eAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitConstActualParameter(this, o); + } + + public Expression E; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstDeclaration.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstDeclaration.java new file mode 100644 index 0000000..0081d10 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstDeclaration.java @@ -0,0 +1,34 @@ +/* + * @(#)ConstDeclaration.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class ConstDeclaration extends Declaration { + + public ConstDeclaration(Identifier iAST, Expression eAST, + SourcePosition thePosition) { + super(thePosition); + I = iAST; + E = eAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitConstDeclaration(this, o); + } + + public Identifier I; + public Expression E; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstFormalParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstFormalParameter.java new file mode 100644 index 0000000..ea3e170 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ConstFormalParameter.java @@ -0,0 +1,42 @@ +/* + * @(#)ConstFormalParameter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class ConstFormalParameter extends FormalParameter { + + public ConstFormalParameter(Identifier iAST, TypeDenoter tAST, + SourcePosition thePosition) { + super(thePosition); + I = iAST; + T = tAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitConstFormalParameter(this, o); + } + + public Identifier I; + public TypeDenoter T; + + public boolean equals(Object fpAST) { + if (fpAST instanceof ConstFormalParameter) { + ConstFormalParameter cfpAST = (ConstFormalParameter) fpAST; + return T.equals(cfpAST.T); + } else + return false; + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Declaration.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Declaration.java new file mode 100644 index 0000000..586293b --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Declaration.java @@ -0,0 +1,27 @@ +/* + * @(#)Declaration.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public abstract class Declaration extends AST { + + public Declaration(SourcePosition thePosition) { + super(thePosition); + duplicated = false; + } + + public boolean duplicated; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/DotVname.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/DotVname.java new file mode 100644 index 0000000..26456b8 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/DotVname.java @@ -0,0 +1,33 @@ +/* + * @(#)DotVname.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class DotVname extends Vname { + + public DotVname(Vname vAST, Identifier iAST, SourcePosition thePosition) { + super(thePosition); + V = vAST; + I = iAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitDotVname(this, o); + } + + public Identifier I; + public Vname V; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyActualParameterSequence.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyActualParameterSequence.java new file mode 100644 index 0000000..3a0370d --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyActualParameterSequence.java @@ -0,0 +1,28 @@ +/* + * @(#)EmptyActualParameterSequence.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class EmptyActualParameterSequence extends ActualParameterSequence { + + public EmptyActualParameterSequence(SourcePosition thePosition) { + super(thePosition); + } + + public Object visit(Visitor v, Object o) { + return v.visitEmptyActualParameterSequence(this, o); + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyCommand.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyCommand.java new file mode 100644 index 0000000..2dd7249 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyCommand.java @@ -0,0 +1,28 @@ +/* + * @(#)EmptyCommand.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class EmptyCommand extends Command { + + public EmptyCommand(SourcePosition thePosition) { + super(thePosition); + } + + public Object visit(Visitor v, Object o) { + return v.visitEmptyCommand(this, o); + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyExpression.java new file mode 100644 index 0000000..169c89c --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyExpression.java @@ -0,0 +1,28 @@ +/* + * @(#)EmptyExpression.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class EmptyExpression extends Expression { + + public EmptyExpression(SourcePosition thePosition) { + super(thePosition); + } + + public Object visit(Visitor v, Object o) { + return v.visitEmptyExpression(this, o); + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyFormalParameterSequence.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyFormalParameterSequence.java new file mode 100644 index 0000000..74581ec --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/EmptyFormalParameterSequence.java @@ -0,0 +1,32 @@ +/* + * @(#)EmptyFormalParameterSequence.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class EmptyFormalParameterSequence extends FormalParameterSequence { + + public EmptyFormalParameterSequence(SourcePosition thePosition) { + super(thePosition); + } + + public Object visit(Visitor v, Object o) { + return v.visitEmptyFormalParameterSequence(this, o); + } + + public boolean equals(Object fpsAST) { + return (fpsAST instanceof EmptyFormalParameterSequence); + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ErrorTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ErrorTypeDenoter.java new file mode 100644 index 0000000..5171dc9 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ErrorTypeDenoter.java @@ -0,0 +1,32 @@ +/* + * @(#)ErrorTypeDenoter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class ErrorTypeDenoter extends TypeDenoter { + + public ErrorTypeDenoter(SourcePosition thePosition) { + super(thePosition); + } + + public Object visit(Visitor v, Object o) { + return v.visitErrorTypeDenoter(this, o); + } + + public boolean equals(Object obj) { + return true; + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Expression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Expression.java new file mode 100644 index 0000000..682d314 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Expression.java @@ -0,0 +1,27 @@ +/* + * @(#)Expression.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public abstract class Expression extends AST { + + public Expression(SourcePosition thePosition) { + super(thePosition); + type = null; + } + + public TypeDenoter type; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FieldTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FieldTypeDenoter.java new file mode 100644 index 0000000..d618d08 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FieldTypeDenoter.java @@ -0,0 +1,26 @@ +/* + * @(#)FieldTypeDenoter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public abstract class FieldTypeDenoter extends TypeDenoter { + + public FieldTypeDenoter(SourcePosition thePosition) { + super(thePosition); + } + + public abstract boolean equals(Object obj); +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FormalParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FormalParameter.java new file mode 100644 index 0000000..c3b8505 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FormalParameter.java @@ -0,0 +1,27 @@ +/* + * @(#)FormalParameter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public abstract class FormalParameter extends Declaration { + + public FormalParameter(SourcePosition thePosition) { + super(thePosition); + } + + public abstract boolean equals(Object fpAST); + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FormalParameterSequence.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FormalParameterSequence.java new file mode 100644 index 0000000..b6abc62 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FormalParameterSequence.java @@ -0,0 +1,26 @@ +/* + * @(#)FormalParameterSequence.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public abstract class FormalParameterSequence extends AST { + + public FormalParameterSequence(SourcePosition thePosition) { + super(thePosition); + } + + public abstract boolean equals(Object fpsAST); +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncActualParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncActualParameter.java new file mode 100644 index 0000000..6f9360c --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncActualParameter.java @@ -0,0 +1,31 @@ +/* + * @(#)FuncActualParameter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class FuncActualParameter extends ActualParameter { + + public FuncActualParameter(Identifier iAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitFuncActualParameter(this, o); + } + + public Identifier I; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncDeclaration.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncDeclaration.java new file mode 100644 index 0000000..bf7de92 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncDeclaration.java @@ -0,0 +1,39 @@ +/* + * @(#)FuncDeclaration.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class FuncDeclaration extends Declaration { + + public FuncDeclaration(Identifier iAST, FormalParameterSequence fpsAST, + TypeDenoter tAST, Expression eAST, + SourcePosition thePosition) { + super(thePosition); + I = iAST; + FPS = fpsAST; + T = tAST; + E = eAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitFuncDeclaration(this, o); + } + + public Identifier I; + public FormalParameterSequence FPS; + public TypeDenoter T; + public Expression E; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncFormalParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncFormalParameter.java new file mode 100644 index 0000000..fe101bd --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/FuncFormalParameter.java @@ -0,0 +1,44 @@ +/* + * @(#)FuncFormalParameter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class FuncFormalParameter extends FormalParameter { + + public FuncFormalParameter(Identifier iAST, FormalParameterSequence fpsAST, + TypeDenoter tAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + FPS = fpsAST; + T = tAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitFuncFormalParameter(this, o); + } + + public boolean equals(Object fpAST) { + if (fpAST instanceof FuncFormalParameter) { + FuncFormalParameter ffpAST = (FuncFormalParameter) fpAST; + return FPS.equals(ffpAST.FPS) && T.equals(ffpAST.T); + } else + return false; + } + + public Identifier I; + public FormalParameterSequence FPS; + public TypeDenoter T; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Identifier.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Identifier.java new file mode 100644 index 0000000..a24ced6 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Identifier.java @@ -0,0 +1,33 @@ +/* + * @(#)Identifier.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class Identifier extends Terminal { + + public Identifier(String theSpelling, SourcePosition thePosition) { + super(theSpelling, thePosition); + type = null; + decl = null; + } + + public Object visit(Visitor v, Object o) { + return v.visitIdentifier(this, o); + } + + public TypeDenoter type; + public AST decl; // Either a Declaration or a FieldTypeDenoter +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IfCommand.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IfCommand.java new file mode 100644 index 0000000..438c224 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IfCommand.java @@ -0,0 +1,35 @@ +/* + * @(#)IfCommand.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class IfCommand extends Command { + + public IfCommand(Expression eAST, Command c1AST, Command c2AST, + SourcePosition thePosition) { + super(thePosition); + E = eAST; + C1 = c1AST; + C2 = c2AST; + } + + public Object visit(Visitor v, Object o) { + return v.visitIfCommand(this, o); + } + + public Expression E; + public Command C1, C2; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IfExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IfExpression.java new file mode 100644 index 0000000..5714ad9 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IfExpression.java @@ -0,0 +1,34 @@ +/* + * @(#)IfExpression.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class IfExpression extends Expression { + + public IfExpression(Expression e1AST, Expression e2AST, Expression e3AST, + SourcePosition thePosition) { + super(thePosition); + E1 = e1AST; + E2 = e2AST; + E3 = e3AST; + } + + public Object visit(Visitor v, Object o) { + return v.visitIfExpression(this, o); + } + + public Expression E1, E2, E3; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntTypeDenoter.java new file mode 100644 index 0000000..cf40f6a --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntTypeDenoter.java @@ -0,0 +1,35 @@ +/* + * @(#)IntTypeDenoter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class IntTypeDenoter extends TypeDenoter { + + public IntTypeDenoter(SourcePosition thePosition) { + super(thePosition); + } + + public Object visit(Visitor v, Object o) { + return v.visitIntTypeDenoter(this, o); + } + + public boolean equals(Object obj) { + if (obj != null && obj instanceof ErrorTypeDenoter) + return true; + else + return (obj != null && obj instanceof IntTypeDenoter); + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntegerExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntegerExpression.java new file mode 100644 index 0000000..8d2e1e8 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntegerExpression.java @@ -0,0 +1,31 @@ +/* + * @(#)IntegerExpression.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class IntegerExpression extends Expression { + + public IntegerExpression(IntegerLiteral ilAST, SourcePosition thePosition) { + super(thePosition); + IL = ilAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitIntegerExpression(this, o); + } + + public IntegerLiteral IL; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntegerLiteral.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntegerLiteral.java new file mode 100644 index 0000000..0565b16 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/IntegerLiteral.java @@ -0,0 +1,29 @@ +/* + * @(#)IntegerLiteral.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class IntegerLiteral extends Terminal { + + public IntegerLiteral(String theSpelling, SourcePosition thePosition) { + super(theSpelling, thePosition); + } + + public Object visit(Visitor v, Object o) { + return v.visitIntegerLiteral(this, o); + } + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/LetCommand.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/LetCommand.java new file mode 100644 index 0000000..126a9f4 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/LetCommand.java @@ -0,0 +1,33 @@ +/* + * @(#)LetCommand.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class LetCommand extends Command { + + public LetCommand(Declaration dAST, Command cAST, SourcePosition thePosition) { + super(thePosition); + D = dAST; + C = cAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitLetCommand(this, o); + } + + public Declaration D; + public Command C; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/LetExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/LetExpression.java new file mode 100644 index 0000000..e954f28 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/LetExpression.java @@ -0,0 +1,33 @@ +/* + * @(#)LetExpression.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class LetExpression extends Expression { + + public LetExpression(Declaration dAST, Expression eAST, SourcePosition thePosition) { + super(thePosition); + D = dAST; + E = eAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitLetExpression(this, o); + } + + public Declaration D; + public Expression E; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleActualParameterSequence.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleActualParameterSequence.java new file mode 100644 index 0000000..949fa55 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleActualParameterSequence.java @@ -0,0 +1,34 @@ +/* + * @(#)MultipleActualParameterSequence.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class MultipleActualParameterSequence extends ActualParameterSequence { + + public MultipleActualParameterSequence(ActualParameter apAST, ActualParameterSequence apsAST, + SourcePosition thePosition) { + super(thePosition); + AP = apAST; + APS = apsAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitMultipleActualParameterSequence(this, o); + } + + public ActualParameter AP; + public ActualParameterSequence APS; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleArrayAggregate.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleArrayAggregate.java new file mode 100644 index 0000000..6a3fede --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleArrayAggregate.java @@ -0,0 +1,34 @@ +/* + * @(#)MultipleArrayAggregate.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class MultipleArrayAggregate extends ArrayAggregate { + + public MultipleArrayAggregate(Expression eAST, ArrayAggregate aaAST, + SourcePosition thePosition) { + super(thePosition); + E = eAST; + AA = aaAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitMultipleArrayAggregate(this, o); + } + + public Expression E; + public ArrayAggregate AA; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFieldTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFieldTypeDenoter.java new file mode 100644 index 0000000..71a077f --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFieldTypeDenoter.java @@ -0,0 +1,46 @@ +/* + * @(#)MultipleFieldTypeDenoter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class MultipleFieldTypeDenoter extends FieldTypeDenoter { + + public MultipleFieldTypeDenoter(Identifier iAST, TypeDenoter tAST, FieldTypeDenoter ftAST, + SourcePosition thePosition) { + super(thePosition); + I = iAST; + T = tAST; + FT = ftAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitMultipleFieldTypeDenoter(this, o); + } + + public boolean equals(Object obj) { + if (obj != null && obj instanceof MultipleFieldTypeDenoter) { + MultipleFieldTypeDenoter ft = (MultipleFieldTypeDenoter) obj; + return (this.I.spelling.compareTo(ft.I.spelling) == 0) && + this.T.equals(ft.T) && + this.FT.equals(ft.FT); + } else + return false; + } + + public Identifier I; + public TypeDenoter T; + public FieldTypeDenoter FT; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFormalParameterSequence.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFormalParameterSequence.java new file mode 100644 index 0000000..ced0581 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleFormalParameterSequence.java @@ -0,0 +1,42 @@ +/* + * @(#)MultipleFormalParameterSequence.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class MultipleFormalParameterSequence extends FormalParameterSequence { + + public MultipleFormalParameterSequence(FormalParameter fpAST, FormalParameterSequence fpsAST, + SourcePosition thePosition) { + super(thePosition); + FP = fpAST; + FPS = fpsAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitMultipleFormalParameterSequence(this, o); + } + + public boolean equals(Object fpsAST) { + if (fpsAST instanceof MultipleFormalParameterSequence) { + MultipleFormalParameterSequence mfpsAST = (MultipleFormalParameterSequence) fpsAST; + return FP.equals(mfpsAST.FP) && FPS.equals(mfpsAST.FPS); + } else + return false; + } + + public FormalParameter FP; + public FormalParameterSequence FPS; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleRecordAggregate.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleRecordAggregate.java new file mode 100644 index 0000000..0e7c3d5 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/MultipleRecordAggregate.java @@ -0,0 +1,36 @@ +/* + * @(#)MultipleRecordAggregate.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class MultipleRecordAggregate extends RecordAggregate { + + public MultipleRecordAggregate(Identifier iAST, Expression eAST, RecordAggregate raAST, + SourcePosition thePosition) { + super(thePosition); + I = iAST; + E = eAST; + RA = raAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitMultipleRecordAggregate(this, o); + } + + public Identifier I; + public Expression E; + public RecordAggregate RA; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Operator.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Operator.java new file mode 100644 index 0000000..5fb379a --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Operator.java @@ -0,0 +1,31 @@ +/* + * @(#)Operator.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class Operator extends Terminal { + + public Operator(String theSpelling, SourcePosition thePosition) { + super(theSpelling, thePosition); + decl = null; + } + + public Object visit(Visitor v, Object o) { + return v.visitOperator(this, o); + } + + public Declaration decl; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcActualParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcActualParameter.java new file mode 100644 index 0000000..9b926dc --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcActualParameter.java @@ -0,0 +1,31 @@ +/* + * @(#)ProcActualParameter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class ProcActualParameter extends ActualParameter { + + public ProcActualParameter(Identifier iAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitProcActualParameter(this, o); + } + + public Identifier I; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcDeclaration.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcDeclaration.java new file mode 100644 index 0000000..1fc4223 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcDeclaration.java @@ -0,0 +1,36 @@ +/* + * @(#)ProcDeclaration.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class ProcDeclaration extends Declaration { + + public ProcDeclaration(Identifier iAST, FormalParameterSequence fpsAST, + Command cAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + FPS = fpsAST; + C = cAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitProcDeclaration(this, o); + } + + public Identifier I; + public FormalParameterSequence FPS; + public Command C; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcFormalParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcFormalParameter.java new file mode 100644 index 0000000..d6a6bc8 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/ProcFormalParameter.java @@ -0,0 +1,42 @@ +/* + * @(#)ProcFormalParameter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class ProcFormalParameter extends FormalParameter { + + public ProcFormalParameter(Identifier iAST, FormalParameterSequence fpsAST, + SourcePosition thePosition) { + super(thePosition); + I = iAST; + FPS = fpsAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitProcFormalParameter(this, o); + } + + public Identifier I; + public FormalParameterSequence FPS; + + public boolean equals(Object fpAST) { + if (fpAST instanceof ProcFormalParameter) { + ProcFormalParameter pfpAST = (ProcFormalParameter) fpAST; + return FPS.equals(pfpAST.FPS); + } else + return false; + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Program.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Program.java new file mode 100644 index 0000000..b2a513a --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Program.java @@ -0,0 +1,31 @@ +/* + * @(#)Program.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class Program extends AST { + + public Program(Command cAST, SourcePosition thePosition) { + super(thePosition); + C = cAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitProgram(this, o); + } + + public Command C; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordAggregate.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordAggregate.java new file mode 100644 index 0000000..9f2d923 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordAggregate.java @@ -0,0 +1,27 @@ +/* + * @(#)RecordAggregate.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public abstract class RecordAggregate extends AST { + + public RecordAggregate(SourcePosition thePosition) { + super(thePosition); + type = null; + } + + public FieldTypeDenoter type; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordExpression.java new file mode 100644 index 0000000..c96ad96 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordExpression.java @@ -0,0 +1,31 @@ +/* + * @(#)RecordExpression.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class RecordExpression extends Expression { + + public RecordExpression(RecordAggregate raAST, SourcePosition thePosition) { + super(thePosition); + RA = raAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitRecordExpression(this, o); + } + + public RecordAggregate RA; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordTypeDenoter.java new file mode 100644 index 0000000..979c90d --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/RecordTypeDenoter.java @@ -0,0 +1,40 @@ +/* + * @(#)RecordTypeDenoter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class RecordTypeDenoter extends TypeDenoter { + + public RecordTypeDenoter(FieldTypeDenoter ftAST, SourcePosition thePosition) { + super(thePosition); + FT = ftAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitRecordTypeDenoter(this, o); + } + + public boolean equals(Object obj) { + if (obj != null && obj instanceof ErrorTypeDenoter) + return true; + else if (obj != null && obj instanceof RecordTypeDenoter) + return this.FT.equals(((RecordTypeDenoter) obj).FT); + else + return false; + } + + public FieldTypeDenoter FT; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialCommand.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialCommand.java new file mode 100644 index 0000000..37a8a7a --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialCommand.java @@ -0,0 +1,32 @@ +/* + * @(#)SequentialCommand.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class SequentialCommand extends Command { + + public SequentialCommand(Command c1AST, Command c2AST, SourcePosition thePosition) { + super(thePosition); + C1 = c1AST; + C2 = c2AST; + } + + public Object visit(Visitor v, Object o) { + return v.visitSequentialCommand(this, o); + } + + public Command C1, C2; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialDeclaration.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialDeclaration.java new file mode 100644 index 0000000..e899258 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SequentialDeclaration.java @@ -0,0 +1,33 @@ +/* + * @(#)SequentialDeclaration.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class SequentialDeclaration extends Declaration { + + public SequentialDeclaration(Declaration d1AST, Declaration d2AST, + SourcePosition thePosition) { + super(thePosition); + D1 = d1AST; + D2 = d2AST; + } + + public Object visit(Visitor v, Object o) { + return v.visitSequentialDeclaration(this, o); + } + + public Declaration D1, D2; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SimpleTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SimpleTypeDenoter.java new file mode 100644 index 0000000..d540f14 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SimpleTypeDenoter.java @@ -0,0 +1,35 @@ +/* + * @(#)SimpleTypeDenoter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class SimpleTypeDenoter extends TypeDenoter { + + public SimpleTypeDenoter(Identifier iAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitSimpleTypeDenoter(this, o); + } + + public boolean equals(Object obj) { + return false; // should not happen + } + + public Identifier I; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SimpleVname.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SimpleVname.java new file mode 100644 index 0000000..94734e4 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SimpleVname.java @@ -0,0 +1,31 @@ +/* + * @(#)SimpleVname.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class SimpleVname extends Vname { + + public SimpleVname(Identifier iAST, SourcePosition thePosition) { + super(thePosition); + I = iAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitSimpleVname(this, o); + } + + public Identifier I; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleActualParameterSequence.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleActualParameterSequence.java new file mode 100644 index 0000000..b9548ec --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleActualParameterSequence.java @@ -0,0 +1,32 @@ +/* + * @(#)SingleActualParameterSequence.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class SingleActualParameterSequence extends ActualParameterSequence { + + public SingleActualParameterSequence(ActualParameter apAST, + SourcePosition thePosition) { + super(thePosition); + AP = apAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitSingleActualParameterSequence(this, o); + } + + public ActualParameter AP; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleArrayAggregate.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleArrayAggregate.java new file mode 100644 index 0000000..92420d8 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleArrayAggregate.java @@ -0,0 +1,32 @@ +/* + * @(#)SingleArrayAggregate.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class SingleArrayAggregate extends ArrayAggregate { + + public SingleArrayAggregate(Expression eAST, + SourcePosition thePosition) { + super(thePosition); + E = eAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitSingleArrayAggregate(this, o); + } + + public Expression E; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFieldTypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFieldTypeDenoter.java new file mode 100644 index 0000000..e35eb95 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFieldTypeDenoter.java @@ -0,0 +1,43 @@ +/* + * @(#)SingleFieldTypeDenoter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class SingleFieldTypeDenoter extends FieldTypeDenoter { + + public SingleFieldTypeDenoter(Identifier iAST, TypeDenoter tAST, + SourcePosition thePosition) { + super(thePosition); + I = iAST; + T = tAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitSingleFieldTypeDenoter(this, o); + } + + public boolean equals(Object obj) { + if (obj != null && obj instanceof SingleFieldTypeDenoter) { + SingleFieldTypeDenoter ft = (SingleFieldTypeDenoter) obj; + return (this.I.spelling.compareTo(ft.I.spelling) == 0) && + this.T.equals(ft.T); + } else + return false; + } + + public Identifier I; + public TypeDenoter T; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFormalParameterSequence.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFormalParameterSequence.java new file mode 100644 index 0000000..b905bde --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleFormalParameterSequence.java @@ -0,0 +1,40 @@ +/* + * @(#)SingleFormalParameterSequence.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class SingleFormalParameterSequence extends FormalParameterSequence { + + public SingleFormalParameterSequence(FormalParameter fpAST, + SourcePosition thePosition) { + super(thePosition); + FP = fpAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitSingleFormalParameterSequence(this, o); + } + + public boolean equals(Object fpsAST) { + if (fpsAST instanceof SingleFormalParameterSequence) { + SingleFormalParameterSequence sfpsAST = (SingleFormalParameterSequence) fpsAST; + return FP.equals(sfpsAST.FP); + } else + return false; + } + + public FormalParameter FP; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleRecordAggregate.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleRecordAggregate.java new file mode 100644 index 0000000..211988a --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SingleRecordAggregate.java @@ -0,0 +1,34 @@ +/* + * @(#)SingleRecordAggregate.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class SingleRecordAggregate extends RecordAggregate { + + public SingleRecordAggregate(Identifier iAST, Expression eAST, + SourcePosition thePosition) { + super(thePosition); + I = iAST; + E = eAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitSingleRecordAggregate(this, o); + } + + public Identifier I; + public Expression E; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SubscriptVname.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SubscriptVname.java new file mode 100644 index 0000000..1b90ac5 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/SubscriptVname.java @@ -0,0 +1,33 @@ +/* + * @(#)SubscriptVname.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class SubscriptVname extends Vname { + + public SubscriptVname(Vname vAST, Expression eAST, SourcePosition thePosition) { + super(thePosition); + V = vAST; + E = eAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitSubscriptVname(this, o); + } + + public Expression E; + public Vname V; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Terminal.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Terminal.java new file mode 100644 index 0000000..f14d753 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Terminal.java @@ -0,0 +1,27 @@ +/* + * @(#)Terminal.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +abstract public class Terminal extends AST { + + public Terminal(String theSpelling, SourcePosition thePosition) { + super(thePosition); + spelling = theSpelling; + } + + public String spelling; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/TypeDeclaration.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/TypeDeclaration.java new file mode 100644 index 0000000..bf8a910 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/TypeDeclaration.java @@ -0,0 +1,34 @@ +/* + * @(#)TypeDeclaration.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class TypeDeclaration extends Declaration { + + public TypeDeclaration(Identifier iAST, TypeDenoter tAST, + SourcePosition thePosition) { + super(thePosition); + I = iAST; + T = tAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitTypeDeclaration(this, o); + } + + public Identifier I; + public TypeDenoter T; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/TypeDenoter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/TypeDenoter.java new file mode 100644 index 0000000..ee8af46 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/TypeDenoter.java @@ -0,0 +1,27 @@ +/* + * @(#)TypeDenoter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public abstract class TypeDenoter extends AST { + + public TypeDenoter(SourcePosition thePosition) { + super(thePosition); + } + + public abstract boolean equals(Object obj); + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/UnaryExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/UnaryExpression.java new file mode 100644 index 0000000..b7a4f04 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/UnaryExpression.java @@ -0,0 +1,34 @@ +/* + * @(#)UnaryExpression.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class UnaryExpression extends Expression { + + public UnaryExpression(Operator oAST, Expression eAST, + SourcePosition thePosition) { + super(thePosition); + O = oAST; + E = eAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitUnaryExpression(this, o); + } + + public Expression E; + public Operator O; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/UnaryOperatorDeclaration.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/UnaryOperatorDeclaration.java new file mode 100644 index 0000000..152eb09 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/UnaryOperatorDeclaration.java @@ -0,0 +1,35 @@ +/* + * @(#)UnaryOperatorDeclaration.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class UnaryOperatorDeclaration extends Declaration { + + public UnaryOperatorDeclaration(Operator oAST, TypeDenoter argAST, + TypeDenoter resultAST, SourcePosition thePosition) { + super(thePosition); + O = oAST; + ARG = argAST; + RES = resultAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitUnaryOperatorDeclaration(this, o); + } + + public Operator O; + public TypeDenoter ARG, RES; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarActualParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarActualParameter.java new file mode 100644 index 0000000..a4bdbbf --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarActualParameter.java @@ -0,0 +1,31 @@ +/* + * @(#)VarActualParameter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class VarActualParameter extends ActualParameter { + + public VarActualParameter(Vname vAST, SourcePosition thePosition) { + super(thePosition); + V = vAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitVarActualParameter(this, o); + } + + public Vname V; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarDeclaration.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarDeclaration.java new file mode 100644 index 0000000..0486a75 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarDeclaration.java @@ -0,0 +1,34 @@ +/* + * @(#)VarDeclaration.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class VarDeclaration extends Declaration { + + public VarDeclaration(Identifier iAST, TypeDenoter tAST, + SourcePosition thePosition) { + super(thePosition); + I = iAST; + T = tAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitVarDeclaration(this, o); + } + + public Identifier I; + public TypeDenoter T; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarFormalParameter.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarFormalParameter.java new file mode 100644 index 0000000..62b7cc2 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VarFormalParameter.java @@ -0,0 +1,42 @@ +/* + * @(#)ValFormalParameter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class VarFormalParameter extends FormalParameter { + + public VarFormalParameter(Identifier iAST, TypeDenoter tAST, + SourcePosition thePosition) { + super(thePosition); + I = iAST; + T = tAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitVarFormalParameter(this, o); + } + + public Identifier I; + public TypeDenoter T; + + public boolean equals(Object fpAST) { + if (fpAST instanceof VarFormalParameter) { + VarFormalParameter vfpAST = (VarFormalParameter) fpAST; + return T.equals(vfpAST.T); + } else + return false; + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Visitor.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Visitor.java new file mode 100644 index 0000000..b1be8a1 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Visitor.java @@ -0,0 +1,154 @@ +/* + * @(#)Visitor.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +public interface Visitor { + + // Commands + public abstract Object visitAssignCommand(AssignCommand ast, Object o); + + public abstract Object visitCallCommand(CallCommand ast, Object o); + + public abstract Object visitEmptyCommand(EmptyCommand ast, Object o); + + public abstract Object visitIfCommand(IfCommand ast, Object o); + + public abstract Object visitLetCommand(LetCommand ast, Object o); + + public abstract Object visitSequentialCommand(SequentialCommand ast, Object o); + + public abstract Object visitWhileCommand(WhileCommand ast, Object o); + + // Expressions + public abstract Object visitArrayExpression(ArrayExpression ast, Object o); + + public abstract Object visitBinaryExpression(BinaryExpression ast, Object o); + + public abstract Object visitCallExpression(CallExpression ast, Object o); + + public abstract Object visitCharacterExpression(CharacterExpression ast, Object o); + + public abstract Object visitEmptyExpression(EmptyExpression ast, Object o); + + public abstract Object visitIfExpression(IfExpression ast, Object o); + + public abstract Object visitIntegerExpression(IntegerExpression ast, Object o); + + public abstract Object visitLetExpression(LetExpression ast, Object o); + + public abstract Object visitRecordExpression(RecordExpression ast, Object o); + + public abstract Object visitUnaryExpression(UnaryExpression ast, Object o); + + public abstract Object visitVnameExpression(VnameExpression ast, Object o); + + // Declarations + public abstract Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Object o); + + public abstract Object visitConstDeclaration(ConstDeclaration ast, Object o); + + public abstract Object visitFuncDeclaration(FuncDeclaration ast, Object o); + + public abstract Object visitProcDeclaration(ProcDeclaration ast, Object o); + + public abstract Object visitSequentialDeclaration(SequentialDeclaration ast, Object o); + + public abstract Object visitTypeDeclaration(TypeDeclaration ast, Object o); + + public abstract Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Object o); + + public abstract Object visitVarDeclaration(VarDeclaration ast, Object o); + + // Array Aggregates + public abstract Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, Object o); + + public abstract Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object o); + + // Record Aggregates + public abstract Object visitMultipleRecordAggregate(MultipleRecordAggregate ast, Object o); + + public abstract Object visitSingleRecordAggregate(SingleRecordAggregate ast, Object o); + + // Formal Parameters + public abstract Object visitConstFormalParameter(ConstFormalParameter ast, Object o); + + public abstract Object visitFuncFormalParameter(FuncFormalParameter ast, Object o); + + public abstract Object visitProcFormalParameter(ProcFormalParameter ast, Object o); + + public abstract Object visitVarFormalParameter(VarFormalParameter ast, Object o); + + public abstract Object visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Object o); + + public abstract Object visitMultipleFormalParameterSequence(MultipleFormalParameterSequence ast, Object o); + + public abstract Object visitSingleFormalParameterSequence(SingleFormalParameterSequence ast, Object o); + + // Actual Parameters + public abstract Object visitConstActualParameter(ConstActualParameter ast, Object o); + + public abstract Object visitFuncActualParameter(FuncActualParameter ast, Object o); + + public abstract Object visitProcActualParameter(ProcActualParameter ast, Object o); + + public abstract Object visitVarActualParameter(VarActualParameter ast, Object o); + + public abstract Object visitEmptyActualParameterSequence(EmptyActualParameterSequence ast, Object o); + + public abstract Object visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, Object o); + + public abstract Object visitSingleActualParameterSequence(SingleActualParameterSequence ast, Object o); + + // Type Denoters + public abstract Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object o); + + public abstract Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object o); + + public abstract Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object o); + + public abstract Object visitCharTypeDenoter(CharTypeDenoter ast, Object o); + + public abstract Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object o); + + public abstract Object visitSimpleTypeDenoter(SimpleTypeDenoter ast, Object o); + + public abstract Object visitIntTypeDenoter(IntTypeDenoter ast, Object o); + + public abstract Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object o); + + public abstract Object visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, Object o); + + public abstract Object visitSingleFieldTypeDenoter(SingleFieldTypeDenoter ast, Object o); + + // Literals, Identifiers and Operators + public abstract Object visitCharacterLiteral(CharacterLiteral ast, Object o); + + public abstract Object visitIdentifier(Identifier ast, Object o); + + public abstract Object visitIntegerLiteral(IntegerLiteral ast, Object o); + + public abstract Object visitOperator(Operator ast, Object o); + + // Value-or-variable names + public abstract Object visitDotVname(DotVname ast, Object o); + + public abstract Object visitSimpleVname(SimpleVname ast, Object o); + + public abstract Object visitSubscriptVname(SubscriptVname ast, Object o); + + // Programs + public abstract Object visitProgram(Program ast, Object o); + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Vname.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Vname.java new file mode 100644 index 0000000..9c00d53 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/Vname.java @@ -0,0 +1,30 @@ +/* + * @(#)Vname.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public abstract class Vname extends AST { + + public Vname(SourcePosition thePosition) { + super(thePosition); + variable = false; + type = null; + } + + public boolean variable, indexed; + public int offset; + public TypeDenoter type; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VnameExpression.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VnameExpression.java new file mode 100644 index 0000000..49f23d3 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/VnameExpression.java @@ -0,0 +1,31 @@ +/* + * @(#)VnameExpression.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class VnameExpression extends Expression { + + public VnameExpression(Vname vAST, SourcePosition thePosition) { + super(thePosition); + V = vAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitVnameExpression(this, o); + } + + public Vname V; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/WhileCommand.java b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/WhileCommand.java new file mode 100644 index 0000000..6862e68 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/AbstractSyntaxTrees/WhileCommand.java @@ -0,0 +1,33 @@ +/* + * @(#)WhileCommand.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.AbstractSyntaxTrees; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class WhileCommand extends Command { + + public WhileCommand(Expression eAST, Command cAST, SourcePosition thePosition) { + super(thePosition); + E = eAST; + C = cAST; + } + + public Object visit(Visitor v, Object o) { + return v.visitWhileCommand(this, o); + } + + public Expression E; + public Command C; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Encoder.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Encoder.java new file mode 100644 index 0000000..254a6ab --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Encoder.java @@ -0,0 +1,983 @@ +/* + * @(#)Encoder.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.CodeGenerator; + +import java.io.DataOutputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +import Triangle.ErrorReporter; +import Triangle.StdEnvironment; +import Triangle.AbstractMachine.Instruction; +import Triangle.AbstractMachine.Machine; +import Triangle.AbstractSyntaxTrees.AST; +import Triangle.AbstractSyntaxTrees.AnyTypeDenoter; +import Triangle.AbstractSyntaxTrees.ArrayExpression; +import Triangle.AbstractSyntaxTrees.ArrayTypeDenoter; +import Triangle.AbstractSyntaxTrees.AssignCommand; +import Triangle.AbstractSyntaxTrees.BinaryExpression; +import Triangle.AbstractSyntaxTrees.BinaryOperatorDeclaration; +import Triangle.AbstractSyntaxTrees.BoolTypeDenoter; +import Triangle.AbstractSyntaxTrees.CallCommand; +import Triangle.AbstractSyntaxTrees.CallExpression; +import Triangle.AbstractSyntaxTrees.CharTypeDenoter; +import Triangle.AbstractSyntaxTrees.CharacterExpression; +import Triangle.AbstractSyntaxTrees.CharacterLiteral; +import Triangle.AbstractSyntaxTrees.ConstActualParameter; +import Triangle.AbstractSyntaxTrees.ConstDeclaration; +import Triangle.AbstractSyntaxTrees.ConstFormalParameter; +import Triangle.AbstractSyntaxTrees.Declaration; +import Triangle.AbstractSyntaxTrees.DotVname; +import Triangle.AbstractSyntaxTrees.EmptyActualParameterSequence; +import Triangle.AbstractSyntaxTrees.EmptyCommand; +import Triangle.AbstractSyntaxTrees.EmptyExpression; +import Triangle.AbstractSyntaxTrees.EmptyFormalParameterSequence; +import Triangle.AbstractSyntaxTrees.ErrorTypeDenoter; +import Triangle.AbstractSyntaxTrees.FuncActualParameter; +import Triangle.AbstractSyntaxTrees.FuncDeclaration; +import Triangle.AbstractSyntaxTrees.FuncFormalParameter; +import Triangle.AbstractSyntaxTrees.Identifier; +import Triangle.AbstractSyntaxTrees.IfCommand; +import Triangle.AbstractSyntaxTrees.IfExpression; +import Triangle.AbstractSyntaxTrees.IntTypeDenoter; +import Triangle.AbstractSyntaxTrees.IntegerExpression; +import Triangle.AbstractSyntaxTrees.IntegerLiteral; +import Triangle.AbstractSyntaxTrees.LetCommand; +import Triangle.AbstractSyntaxTrees.LetExpression; +import Triangle.AbstractSyntaxTrees.MultipleActualParameterSequence; +import Triangle.AbstractSyntaxTrees.MultipleArrayAggregate; +import Triangle.AbstractSyntaxTrees.MultipleFieldTypeDenoter; +import Triangle.AbstractSyntaxTrees.MultipleFormalParameterSequence; +import Triangle.AbstractSyntaxTrees.MultipleRecordAggregate; +import Triangle.AbstractSyntaxTrees.Operator; +import Triangle.AbstractSyntaxTrees.ProcActualParameter; +import Triangle.AbstractSyntaxTrees.ProcDeclaration; +import Triangle.AbstractSyntaxTrees.ProcFormalParameter; +import Triangle.AbstractSyntaxTrees.Program; +import Triangle.AbstractSyntaxTrees.RecordExpression; +import Triangle.AbstractSyntaxTrees.RecordTypeDenoter; +import Triangle.AbstractSyntaxTrees.SequentialCommand; +import Triangle.AbstractSyntaxTrees.SequentialDeclaration; +import Triangle.AbstractSyntaxTrees.SimpleTypeDenoter; +import Triangle.AbstractSyntaxTrees.SimpleVname; +import Triangle.AbstractSyntaxTrees.SingleActualParameterSequence; +import Triangle.AbstractSyntaxTrees.SingleArrayAggregate; +import Triangle.AbstractSyntaxTrees.SingleFieldTypeDenoter; +import Triangle.AbstractSyntaxTrees.SingleFormalParameterSequence; +import Triangle.AbstractSyntaxTrees.SingleRecordAggregate; +import Triangle.AbstractSyntaxTrees.SubscriptVname; +import Triangle.AbstractSyntaxTrees.TypeDeclaration; +import Triangle.AbstractSyntaxTrees.UnaryExpression; +import Triangle.AbstractSyntaxTrees.UnaryOperatorDeclaration; +import Triangle.AbstractSyntaxTrees.VarActualParameter; +import Triangle.AbstractSyntaxTrees.VarDeclaration; +import Triangle.AbstractSyntaxTrees.VarFormalParameter; +import Triangle.AbstractSyntaxTrees.Visitor; +import Triangle.AbstractSyntaxTrees.Vname; +import Triangle.AbstractSyntaxTrees.VnameExpression; +import Triangle.AbstractSyntaxTrees.WhileCommand; + +public final class Encoder implements Visitor { + + // Commands + public Object visitAssignCommand(AssignCommand ast, Object o) { + Frame frame = (Frame) o; + Integer valSize = (Integer) ast.E.visit(this, frame); + encodeStore(ast.V, new Frame(frame, valSize.intValue()), + valSize.intValue()); + return null; + } + + public Object visitCallCommand(CallCommand ast, Object o) { + Frame frame = (Frame) o; + Integer argsSize = (Integer) ast.APS.visit(this, frame); + ast.I.visit(this, new Frame(frame.level, argsSize)); + return null; + } + + public Object visitEmptyCommand(EmptyCommand ast, Object o) { + return null; + } + + public Object visitIfCommand(IfCommand ast, Object o) { + Frame frame = (Frame) o; + int jumpifAddr, jumpAddr; + + Integer valSize = (Integer) ast.E.visit(this, frame); + jumpifAddr = nextInstrAddr; + emit(Machine.JUMPIFop, Machine.falseRep, Machine.CBr, 0); + ast.C1.visit(this, frame); + jumpAddr = nextInstrAddr; + emit(Machine.JUMPop, 0, Machine.CBr, 0); + patch(jumpifAddr, nextInstrAddr); + ast.C2.visit(this, frame); + patch(jumpAddr, nextInstrAddr); + return null; + } + + public Object visitLetCommand(LetCommand ast, Object o) { + Frame frame = (Frame) o; + int extraSize = ((Integer) ast.D.visit(this, frame)).intValue(); + ast.C.visit(this, new Frame(frame, extraSize)); + if (extraSize > 0) + emit(Machine.POPop, 0, 0, extraSize); + return null; + } + + public Object visitSequentialCommand(SequentialCommand ast, Object o) { + ast.C1.visit(this, o); + ast.C2.visit(this, o); + return null; + } + + public Object visitWhileCommand(WhileCommand ast, Object o) { + Frame frame = (Frame) o; + int jumpAddr, loopAddr; + + jumpAddr = nextInstrAddr; + emit(Machine.JUMPop, 0, Machine.CBr, 0); + loopAddr = nextInstrAddr; + ast.C.visit(this, frame); + patch(jumpAddr, nextInstrAddr); + ast.E.visit(this, frame); + emit(Machine.JUMPIFop, Machine.trueRep, Machine.CBr, loopAddr); + return null; + } + + // Expressions + public Object visitArrayExpression(ArrayExpression ast, Object o) { + ast.type.visit(this, null); + return ast.AA.visit(this, o); + } + + public Object visitBinaryExpression(BinaryExpression ast, Object o) { + Frame frame = (Frame) o; + Integer valSize = (Integer) ast.type.visit(this, null); + int valSize1 = ((Integer) ast.E1.visit(this, frame)).intValue(); + Frame frame1 = new Frame(frame, valSize1); + int valSize2 = ((Integer) ast.E2.visit(this, frame1)).intValue(); + Frame frame2 = new Frame(frame.level, valSize1 + valSize2); + ast.O.visit(this, frame2); + return valSize; + } + + public Object visitCallExpression(CallExpression ast, Object o) { + Frame frame = (Frame) o; + Integer valSize = (Integer) ast.type.visit(this, null); + Integer argsSize = (Integer) ast.APS.visit(this, frame); + ast.I.visit(this, new Frame(frame.level, argsSize)); + return valSize; + } + + public Object visitCharacterExpression(CharacterExpression ast, + Object o) { + Frame frame = (Frame) o; + Integer valSize = (Integer) ast.type.visit(this, null); + emit(Machine.LOADLop, 0, 0, ast.CL.spelling.charAt(1)); + return valSize; + } + + public Object visitEmptyExpression(EmptyExpression ast, Object o) { + return new Integer(0); + } + + public Object visitIfExpression(IfExpression ast, Object o) { + Frame frame = (Frame) o; + Integer valSize; + int jumpifAddr, jumpAddr; + + ast.type.visit(this, null); + ast.E1.visit(this, frame); + jumpifAddr = nextInstrAddr; + emit(Machine.JUMPIFop, Machine.falseRep, Machine.CBr, 0); + valSize = (Integer) ast.E2.visit(this, frame); + jumpAddr = nextInstrAddr; + emit(Machine.JUMPop, 0, Machine.CBr, 0); + patch(jumpifAddr, nextInstrAddr); + valSize = (Integer) ast.E3.visit(this, frame); + patch(jumpAddr, nextInstrAddr); + return valSize; + } + + public Object visitIntegerExpression(IntegerExpression ast, Object o) { + Frame frame = (Frame) o; + Integer valSize = (Integer) ast.type.visit(this, null); + emit(Machine.LOADLop, 0, 0, Integer.parseInt(ast.IL.spelling)); + return valSize; + } + + public Object visitLetExpression(LetExpression ast, Object o) { + Frame frame = (Frame) o; + ast.type.visit(this, null); + int extraSize = ((Integer) ast.D.visit(this, frame)).intValue(); + Frame frame1 = new Frame(frame, extraSize); + Integer valSize = (Integer) ast.E.visit(this, frame1); + if (extraSize > 0) + emit(Machine.POPop, valSize.intValue(), 0, extraSize); + return valSize; + } + + public Object visitRecordExpression(RecordExpression ast, Object o) { + ast.type.visit(this, null); + return ast.RA.visit(this, o); + } + + public Object visitUnaryExpression(UnaryExpression ast, Object o) { + Frame frame = (Frame) o; + Integer valSize = (Integer) ast.type.visit(this, null); + ast.E.visit(this, frame); + ast.O.visit(this, new Frame(frame.level, valSize.intValue())); + return valSize; + } + + public Object visitVnameExpression(VnameExpression ast, Object o) { + Frame frame = (Frame) o; + Integer valSize = (Integer) ast.type.visit(this, null); + encodeFetch(ast.V, frame, valSize.intValue()); + return valSize; + } + + // Declarations + public Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, + Object o) { + return new Integer(0); + } + + public Object visitConstDeclaration(ConstDeclaration ast, Object o) { + Frame frame = (Frame) o; + int extraSize = 0; + + if (ast.E instanceof CharacterExpression) { + CharacterLiteral CL = ((CharacterExpression) ast.E).CL; + ast.entity = new KnownValue(Machine.characterSize, + characterValuation(CL.spelling)); + } else if (ast.E instanceof IntegerExpression) { + IntegerLiteral IL = ((IntegerExpression) ast.E).IL; + ast.entity = new KnownValue(Machine.integerSize, + Integer.parseInt(IL.spelling)); + } else { + int valSize = ((Integer) ast.E.visit(this, frame)).intValue(); + ast.entity = new UnknownValue(valSize, frame.level, frame.size); + extraSize = valSize; + } + writeTableDetails(ast); + return new Integer(extraSize); + } + + public Object visitFuncDeclaration(FuncDeclaration ast, Object o) { + Frame frame = (Frame) o; + int jumpAddr = nextInstrAddr; + int argsSize = 0, valSize = 0; + + emit(Machine.JUMPop, 0, Machine.CBr, 0); + ast.entity = new KnownRoutine(Machine.closureSize, frame.level, nextInstrAddr); + writeTableDetails(ast); + if (frame.level == Machine.maxRoutineLevel) + reporter.reportRestriction("can't nest routines more than 7 deep"); + else { + Frame frame1 = new Frame(frame.level + 1, 0); + argsSize = ((Integer) ast.FPS.visit(this, frame1)).intValue(); + Frame frame2 = new Frame(frame.level + 1, Machine.linkDataSize); + valSize = ((Integer) ast.E.visit(this, frame2)).intValue(); + } + emit(Machine.RETURNop, valSize, 0, argsSize); + patch(jumpAddr, nextInstrAddr); + return new Integer(0); + } + + public Object visitProcDeclaration(ProcDeclaration ast, Object o) { + Frame frame = (Frame) o; + int jumpAddr = nextInstrAddr; + int argsSize = 0; + + emit(Machine.JUMPop, 0, Machine.CBr, 0); + ast.entity = new KnownRoutine(Machine.closureSize, frame.level, + nextInstrAddr); + writeTableDetails(ast); + if (frame.level == Machine.maxRoutineLevel) + reporter.reportRestriction("can't nest routines so deeply"); + else { + Frame frame1 = new Frame(frame.level + 1, 0); + argsSize = ((Integer) ast.FPS.visit(this, frame1)).intValue(); + Frame frame2 = new Frame(frame.level + 1, Machine.linkDataSize); + ast.C.visit(this, frame2); + } + emit(Machine.RETURNop, 0, 0, argsSize); + patch(jumpAddr, nextInstrAddr); + return new Integer(0); + } + + public Object visitSequentialDeclaration(SequentialDeclaration ast, Object o) { + Frame frame = (Frame) o; + int extraSize1, extraSize2; + + extraSize1 = ((Integer) ast.D1.visit(this, frame)).intValue(); + Frame frame1 = new Frame(frame, extraSize1); + extraSize2 = ((Integer) ast.D2.visit(this, frame1)).intValue(); + return new Integer(extraSize1 + extraSize2); + } + + public Object visitTypeDeclaration(TypeDeclaration ast, Object o) { + // just to ensure the type's representation is decided + ast.T.visit(this, null); + return new Integer(0); + } + + public Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, + Object o) { + return new Integer(0); + } + + public Object visitVarDeclaration(VarDeclaration ast, Object o) { + Frame frame = (Frame) o; + int extraSize; + + extraSize = ((Integer) ast.T.visit(this, null)).intValue(); + emit(Machine.PUSHop, 0, 0, extraSize); + ast.entity = new KnownAddress(Machine.addressSize, frame.level, frame.size); + writeTableDetails(ast); + return new Integer(extraSize); + } + + // Array Aggregates + public Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, + Object o) { + Frame frame = (Frame) o; + int elemSize = ((Integer) ast.E.visit(this, frame)).intValue(); + Frame frame1 = new Frame(frame, elemSize); + int arraySize = ((Integer) ast.AA.visit(this, frame1)).intValue(); + return new Integer(elemSize + arraySize); + } + + public Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object o) { + return ast.E.visit(this, o); + } + + // Record Aggregates + public Object visitMultipleRecordAggregate(MultipleRecordAggregate ast, + Object o) { + Frame frame = (Frame) o; + int fieldSize = ((Integer) ast.E.visit(this, frame)).intValue(); + Frame frame1 = new Frame(frame, fieldSize); + int recordSize = ((Integer) ast.RA.visit(this, frame1)).intValue(); + return new Integer(fieldSize + recordSize); + } + + public Object visitSingleRecordAggregate(SingleRecordAggregate ast, + Object o) { + return ast.E.visit(this, o); + } + + // Formal Parameters + public Object visitConstFormalParameter(ConstFormalParameter ast, Object o) { + Frame frame = (Frame) o; + int valSize = ((Integer) ast.T.visit(this, null)).intValue(); + ast.entity = new UnknownValue(valSize, frame.level, -frame.size - valSize); + writeTableDetails(ast); + return new Integer(valSize); + } + + public Object visitFuncFormalParameter(FuncFormalParameter ast, Object o) { + Frame frame = (Frame) o; + int argsSize = Machine.closureSize; + ast.entity = new UnknownRoutine(Machine.closureSize, frame.level, + -frame.size - argsSize); + writeTableDetails(ast); + return new Integer(argsSize); + } + + public Object visitProcFormalParameter(ProcFormalParameter ast, Object o) { + Frame frame = (Frame) o; + int argsSize = Machine.closureSize; + ast.entity = new UnknownRoutine(Machine.closureSize, frame.level, + -frame.size - argsSize); + writeTableDetails(ast); + return new Integer(argsSize); + } + + public Object visitVarFormalParameter(VarFormalParameter ast, Object o) { + Frame frame = (Frame) o; + ast.T.visit(this, null); + ast.entity = new UnknownAddress(Machine.addressSize, frame.level, + -frame.size - Machine.addressSize); + writeTableDetails(ast); + return new Integer(Machine.addressSize); + } + + public Object visitEmptyFormalParameterSequence( + EmptyFormalParameterSequence ast, Object o) { + return new Integer(0); + } + + public Object visitMultipleFormalParameterSequence( + MultipleFormalParameterSequence ast, Object o) { + Frame frame = (Frame) o; + int argsSize1 = ((Integer) ast.FPS.visit(this, frame)).intValue(); + Frame frame1 = new Frame(frame, argsSize1); + int argsSize2 = ((Integer) ast.FP.visit(this, frame1)).intValue(); + return new Integer(argsSize1 + argsSize2); + } + + public Object visitSingleFormalParameterSequence( + SingleFormalParameterSequence ast, Object o) { + return ast.FP.visit(this, o); + } + + // Actual Parameters + public Object visitConstActualParameter(ConstActualParameter ast, Object o) { + return ast.E.visit(this, o); + } + + public Object visitFuncActualParameter(FuncActualParameter ast, Object o) { + Frame frame = (Frame) o; + if (ast.I.decl.entity instanceof KnownRoutine) { + ObjectAddress address = ((KnownRoutine) ast.I.decl.entity).address; + // static link, code address + emit(Machine.LOADAop, 0, displayRegister(frame.level, address.level), 0); + emit(Machine.LOADAop, 0, Machine.CBr, address.displacement); + } else if (ast.I.decl.entity instanceof UnknownRoutine) { + ObjectAddress address = ((UnknownRoutine) ast.I.decl.entity).address; + emit(Machine.LOADop, Machine.closureSize, displayRegister(frame.level, + address.level), address.displacement); + } else if (ast.I.decl.entity instanceof PrimitiveRoutine) { + int displacement = ((PrimitiveRoutine) ast.I.decl.entity).displacement; + // static link, code address + emit(Machine.LOADAop, 0, Machine.SBr, 0); + emit(Machine.LOADAop, 0, Machine.PBr, displacement); + } + return new Integer(Machine.closureSize); + } + + public Object visitProcActualParameter(ProcActualParameter ast, Object o) { + Frame frame = (Frame) o; + if (ast.I.decl.entity instanceof KnownRoutine) { + ObjectAddress address = ((KnownRoutine) ast.I.decl.entity).address; + // static link, code address + emit(Machine.LOADAop, 0, displayRegister(frame.level, address.level), 0); + emit(Machine.LOADAop, 0, Machine.CBr, address.displacement); + } else if (ast.I.decl.entity instanceof UnknownRoutine) { + ObjectAddress address = ((UnknownRoutine) ast.I.decl.entity).address; + emit(Machine.LOADop, Machine.closureSize, displayRegister(frame.level, + address.level), address.displacement); + } else if (ast.I.decl.entity instanceof PrimitiveRoutine) { + int displacement = ((PrimitiveRoutine) ast.I.decl.entity).displacement; + // static link, code address + emit(Machine.LOADAop, 0, Machine.SBr, 0); + emit(Machine.LOADAop, 0, Machine.PBr, displacement); + } + return new Integer(Machine.closureSize); + } + + public Object visitVarActualParameter(VarActualParameter ast, Object o) { + encodeFetchAddress(ast.V, (Frame) o); + return new Integer(Machine.addressSize); + } + + public Object visitEmptyActualParameterSequence( + EmptyActualParameterSequence ast, Object o) { + return new Integer(0); + } + + public Object visitMultipleActualParameterSequence( + MultipleActualParameterSequence ast, Object o) { + Frame frame = (Frame) o; + int argsSize1 = ((Integer) ast.AP.visit(this, frame)).intValue(); + Frame frame1 = new Frame(frame, argsSize1); + int argsSize2 = ((Integer) ast.APS.visit(this, frame1)).intValue(); + return new Integer(argsSize1 + argsSize2); + } + + public Object visitSingleActualParameterSequence( + SingleActualParameterSequence ast, Object o) { + return ast.AP.visit(this, o); + } + + // Type Denoters + public Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object o) { + return new Integer(0); + } + + public Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object o) { + int typeSize; + if (ast.entity == null) { + int elemSize = ((Integer) ast.T.visit(this, null)).intValue(); + typeSize = Integer.parseInt(ast.IL.spelling) * elemSize; + ast.entity = new TypeRepresentation(typeSize); + writeTableDetails(ast); + } else + typeSize = ast.entity.size; + return new Integer(typeSize); + } + + public Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object o) { + if (ast.entity == null) { + ast.entity = new TypeRepresentation(Machine.booleanSize); + writeTableDetails(ast); + } + return new Integer(Machine.booleanSize); + } + + public Object visitCharTypeDenoter(CharTypeDenoter ast, Object o) { + if (ast.entity == null) { + ast.entity = new TypeRepresentation(Machine.characterSize); + writeTableDetails(ast); + } + return new Integer(Machine.characterSize); + } + + public Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object o) { + return new Integer(0); + } + + public Object visitSimpleTypeDenoter(SimpleTypeDenoter ast, + Object o) { + return new Integer(0); + } + + public Object visitIntTypeDenoter(IntTypeDenoter ast, Object o) { + if (ast.entity == null) { + ast.entity = new TypeRepresentation(Machine.integerSize); + writeTableDetails(ast); + } + return new Integer(Machine.integerSize); + } + + public Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object o) { + int typeSize; + if (ast.entity == null) { + typeSize = ((Integer) ast.FT.visit(this, new Integer(0))).intValue(); + ast.entity = new TypeRepresentation(typeSize); + writeTableDetails(ast); + } else + typeSize = ast.entity.size; + return new Integer(typeSize); + } + + public Object visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, + Object o) { + int offset = ((Integer) o).intValue(); + int fieldSize; + + if (ast.entity == null) { + fieldSize = ((Integer) ast.T.visit(this, null)).intValue(); + ast.entity = new Field(fieldSize, offset); + writeTableDetails(ast); + } else + fieldSize = ast.entity.size; + + Integer offset1 = new Integer(offset + fieldSize); + int recSize = ((Integer) ast.FT.visit(this, offset1)).intValue(); + return new Integer(fieldSize + recSize); + } + + public Object visitSingleFieldTypeDenoter(SingleFieldTypeDenoter ast, + Object o) { + int offset = ((Integer) o).intValue(); + int fieldSize; + + if (ast.entity == null) { + fieldSize = ((Integer) ast.T.visit(this, null)).intValue(); + ast.entity = new Field(fieldSize, offset); + writeTableDetails(ast); + } else + fieldSize = ast.entity.size; + + return new Integer(fieldSize); + } + + // Literals, Identifiers and Operators + public Object visitCharacterLiteral(CharacterLiteral ast, Object o) { + return null; + } + + public Object visitIdentifier(Identifier ast, Object o) { + Frame frame = (Frame) o; + if (ast.decl.entity instanceof KnownRoutine) { + ObjectAddress address = ((KnownRoutine) ast.decl.entity).address; + emit(Machine.CALLop, displayRegister(frame.level, address.level), + Machine.CBr, address.displacement); + } else if (ast.decl.entity instanceof UnknownRoutine) { + ObjectAddress address = ((UnknownRoutine) ast.decl.entity).address; + emit(Machine.LOADop, Machine.closureSize, displayRegister(frame.level, + address.level), address.displacement); + emit(Machine.CALLIop, 0, 0, 0); + } else if (ast.decl.entity instanceof PrimitiveRoutine) { + int displacement = ((PrimitiveRoutine) ast.decl.entity).displacement; + if (displacement != Machine.idDisplacement) + emit(Machine.CALLop, Machine.SBr, Machine.PBr, displacement); + } else if (ast.decl.entity instanceof EqualityRoutine) { // "=" or "\=" + int displacement = ((EqualityRoutine) ast.decl.entity).displacement; + emit(Machine.LOADLop, 0, 0, frame.size / 2); + emit(Machine.CALLop, Machine.SBr, Machine.PBr, displacement); + } + return null; + } + + public Object visitIntegerLiteral(IntegerLiteral ast, Object o) { + return null; + } + + public Object visitOperator(Operator ast, Object o) { + Frame frame = (Frame) o; + if (ast.decl.entity instanceof KnownRoutine) { + ObjectAddress address = ((KnownRoutine) ast.decl.entity).address; + emit(Machine.CALLop, displayRegister(frame.level, address.level), + Machine.CBr, address.displacement); + } else if (ast.decl.entity instanceof UnknownRoutine) { + ObjectAddress address = ((UnknownRoutine) ast.decl.entity).address; + emit(Machine.LOADop, Machine.closureSize, displayRegister(frame.level, + address.level), address.displacement); + emit(Machine.CALLIop, 0, 0, 0); + } else if (ast.decl.entity instanceof PrimitiveRoutine) { + int displacement = ((PrimitiveRoutine) ast.decl.entity).displacement; + if (displacement != Machine.idDisplacement) + emit(Machine.CALLop, Machine.SBr, Machine.PBr, displacement); + } else if (ast.decl.entity instanceof EqualityRoutine) { // "=" or "\=" + int displacement = ((EqualityRoutine) ast.decl.entity).displacement; + emit(Machine.LOADLop, 0, 0, frame.size / 2); + emit(Machine.CALLop, Machine.SBr, Machine.PBr, displacement); + } + return null; + } + + // Value-or-variable names + public Object visitDotVname(DotVname ast, Object o) { + Frame frame = (Frame) o; + RuntimeEntity baseObject = (RuntimeEntity) ast.V.visit(this, frame); + ast.offset = ast.V.offset + ((Field) ast.I.decl.entity).fieldOffset; + // I.decl points to the appropriate record field + ast.indexed = ast.V.indexed; + return baseObject; + } + + public Object visitSimpleVname(SimpleVname ast, Object o) { + ast.offset = 0; + ast.indexed = false; + return ast.I.decl.entity; + } + + public Object visitSubscriptVname(SubscriptVname ast, Object o) { + Frame frame = (Frame) o; + RuntimeEntity baseObject; + int elemSize, indexSize; + + baseObject = (RuntimeEntity) ast.V.visit(this, frame); + ast.offset = ast.V.offset; + ast.indexed = ast.V.indexed; + elemSize = ((Integer) ast.type.visit(this, null)).intValue(); + if (ast.E instanceof IntegerExpression) { + IntegerLiteral IL = ((IntegerExpression) ast.E).IL; + ast.offset = ast.offset + Integer.parseInt(IL.spelling) * elemSize; + } else { + // v-name is indexed by a proper expression, not a literal + if (ast.indexed) + frame.size = frame.size + Machine.integerSize; + indexSize = ((Integer) ast.E.visit(this, frame)).intValue(); + if (elemSize != 1) { + emit(Machine.LOADLop, 0, 0, elemSize); + emit(Machine.CALLop, Machine.SBr, Machine.PBr, + Machine.multDisplacement); + } + if (ast.indexed) + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + else + ast.indexed = true; + } + return baseObject; + } + + // Programs + public Object visitProgram(Program ast, Object o) { + return ast.C.visit(this, o); + } + + public Encoder(ErrorReporter reporter) { + this.reporter = reporter; + nextInstrAddr = Machine.CB; + elaborateStdEnvironment(); + } + + private ErrorReporter reporter; + + // Generates code to run a program. + // showingTable is true iff entity description details + // are to be displayed. + public final void encodeRun(Program theAST, boolean showingTable) { + tableDetailsReqd = showingTable; + // startCodeGeneration(); + theAST.visit(this, new Frame(0, 0)); + emit(Machine.HALTop, 0, 0, 0); + } + + // Decides run-time representation of a standard constant. + private final void elaborateStdConst(Declaration constDeclaration, + int value) { + + if (constDeclaration instanceof ConstDeclaration) { + ConstDeclaration decl = (ConstDeclaration) constDeclaration; + int typeSize = ((Integer) decl.E.type.visit(this, null)).intValue(); + decl.entity = new KnownValue(typeSize, value); + writeTableDetails(constDeclaration); + } + } + + // Decides run-time representation of a standard routine. + private final void elaborateStdPrimRoutine(Declaration routineDeclaration, + int routineOffset) { + routineDeclaration.entity = new PrimitiveRoutine(Machine.closureSize, routineOffset); + writeTableDetails(routineDeclaration); + } + + private final void elaborateStdEqRoutine(Declaration routineDeclaration, + int routineOffset) { + routineDeclaration.entity = new EqualityRoutine(Machine.closureSize, routineOffset); + writeTableDetails(routineDeclaration); + } + + private final void elaborateStdRoutine(Declaration routineDeclaration, + int routineOffset) { + routineDeclaration.entity = new KnownRoutine(Machine.closureSize, 0, routineOffset); + writeTableDetails(routineDeclaration); + } + + private final void elaborateStdEnvironment() { + tableDetailsReqd = false; + elaborateStdConst(StdEnvironment.falseDecl, Machine.falseRep); + elaborateStdConst(StdEnvironment.trueDecl, Machine.trueRep); + elaborateStdPrimRoutine(StdEnvironment.notDecl, Machine.notDisplacement); + elaborateStdPrimRoutine(StdEnvironment.andDecl, Machine.andDisplacement); + elaborateStdPrimRoutine(StdEnvironment.orDecl, Machine.orDisplacement); + elaborateStdConst(StdEnvironment.maxintDecl, Machine.maxintRep); + elaborateStdPrimRoutine(StdEnvironment.addDecl, Machine.addDisplacement); + elaborateStdPrimRoutine(StdEnvironment.subtractDecl, Machine.subDisplacement); + elaborateStdPrimRoutine(StdEnvironment.multiplyDecl, Machine.multDisplacement); + elaborateStdPrimRoutine(StdEnvironment.divideDecl, Machine.divDisplacement); + elaborateStdPrimRoutine(StdEnvironment.moduloDecl, Machine.modDisplacement); + elaborateStdPrimRoutine(StdEnvironment.lessDecl, Machine.ltDisplacement); + elaborateStdPrimRoutine(StdEnvironment.notgreaterDecl, Machine.leDisplacement); + elaborateStdPrimRoutine(StdEnvironment.greaterDecl, Machine.gtDisplacement); + elaborateStdPrimRoutine(StdEnvironment.notlessDecl, Machine.geDisplacement); + elaborateStdPrimRoutine(StdEnvironment.chrDecl, Machine.idDisplacement); + elaborateStdPrimRoutine(StdEnvironment.ordDecl, Machine.idDisplacement); + elaborateStdPrimRoutine(StdEnvironment.eolDecl, Machine.eolDisplacement); + elaborateStdPrimRoutine(StdEnvironment.eofDecl, Machine.eofDisplacement); + elaborateStdPrimRoutine(StdEnvironment.getDecl, Machine.getDisplacement); + elaborateStdPrimRoutine(StdEnvironment.putDecl, Machine.putDisplacement); + elaborateStdPrimRoutine(StdEnvironment.getintDecl, Machine.getintDisplacement); + elaborateStdPrimRoutine(StdEnvironment.putintDecl, Machine.putintDisplacement); + elaborateStdPrimRoutine(StdEnvironment.geteolDecl, Machine.geteolDisplacement); + elaborateStdPrimRoutine(StdEnvironment.puteolDecl, Machine.puteolDisplacement); + elaborateStdEqRoutine(StdEnvironment.equalDecl, Machine.eqDisplacement); + elaborateStdEqRoutine(StdEnvironment.unequalDecl, Machine.neDisplacement); + } + + // Saves the object program in the named file. + + public void saveObjectProgram(String objectName) { + FileOutputStream objectFile = null; + DataOutputStream objectStream = null; + + int addr; + + try { + objectFile = new FileOutputStream(objectName); + objectStream = new DataOutputStream(objectFile); + + addr = Machine.CB; + for (addr = Machine.CB; addr < nextInstrAddr; addr++) + Machine.code[addr].write(objectStream); + objectFile.close(); + } catch (FileNotFoundException s) { + System.err.println("Error opening object file: " + s); + } catch (IOException s) { + System.err.println("Error writing object file: " + s); + } + } + + boolean tableDetailsReqd; + + public static void writeTableDetails(AST ast) { + } + + // OBJECT CODE + + // Implementation notes: + // Object code is generated directly into the TAM Code Store, starting at CB. + // The address of the next instruction is held in nextInstrAddr. + + private int nextInstrAddr; + + // Appends an instruction, with the given fields, to the object code. + private void emit(int op, int n, int r, int d) { + Instruction nextInstr = new Instruction(); + if (n > 255) { + reporter.reportRestriction("length of operand can't exceed 255 words"); + n = 255; // to allow code generation to continue + } + nextInstr.op = op; + nextInstr.n = n; + nextInstr.r = r; + nextInstr.d = d; + if (nextInstrAddr == Machine.PB) + reporter.reportRestriction("too many instructions for code segment"); + else { + Machine.code[nextInstrAddr] = nextInstr; + nextInstrAddr = nextInstrAddr + 1; + } + } + + // Patches the d-field of the instruction at address addr. + private void patch(int addr, int d) { + Machine.code[addr].d = d; + } + + // DATA REPRESENTATION + + public int characterValuation(String spelling) { + // Returns the machine representation of the given character literal. + return spelling.charAt(1); + // since the character literal is of the form 'x'} + } + + // REGISTERS + + // Returns the register number appropriate for object code at currentLevel + // to address a data object at objectLevel. + private int displayRegister(int currentLevel, int objectLevel) { + if (objectLevel == 0) + return Machine.SBr; + else if (currentLevel - objectLevel <= 6) + return Machine.LBr + currentLevel - objectLevel; // LBr|L1r|...|L6r + else { + reporter.reportRestriction("can't access data more than 6 levels out"); + return Machine.L6r; // to allow code generation to continue + } + } + + // 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 + // the constant or variable is fetched at run-time. + // valSize is the size of the constant or variable's value. + + private void encodeStore(Vname V, Frame frame, int valSize) { + + RuntimeEntity baseObject = (RuntimeEntity) V.visit(this, frame); + // If indexed = true, code will have been generated to load an index value. + if (valSize > 255) { + reporter.reportRestriction("can't store values larger than 255 words"); + valSize = 255; // to allow code generation to continue + } + if (baseObject instanceof KnownAddress) { + ObjectAddress address = ((KnownAddress) baseObject).address; + if (V.indexed) { + emit(Machine.LOADAop, 0, displayRegister(frame.level, address.level), + address.displacement + V.offset); + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + emit(Machine.STOREIop, valSize, 0, 0); + } else { + emit(Machine.STOREop, valSize, displayRegister(frame.level, + address.level), address.displacement + V.offset); + } + } else if (baseObject instanceof UnknownAddress) { + ObjectAddress address = ((UnknownAddress) baseObject).address; + emit(Machine.LOADop, Machine.addressSize, displayRegister(frame.level, + address.level), address.displacement); + if (V.indexed) + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + if (V.offset != 0) { + emit(Machine.LOADLop, 0, 0, V.offset); + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + } + emit(Machine.STOREIop, valSize, 0, 0); + } + } + + // 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 + // the constant or variable is fetched at run-time. + // valSize is the size of the constant or variable's value. + + private void encodeFetch(Vname V, Frame frame, int valSize) { + + RuntimeEntity baseObject = (RuntimeEntity) V.visit(this, frame); + // If indexed = true, code will have been generated to load an index value. + if (valSize > 255) { + reporter.reportRestriction("can't load values larger than 255 words"); + valSize = 255; // to allow code generation to continue + } + if (baseObject instanceof KnownValue) { + // presumably offset = 0 and indexed = false + int value = ((KnownValue) baseObject).value; + emit(Machine.LOADLop, 0, 0, value); + } else if ((baseObject instanceof UnknownValue) || + (baseObject instanceof KnownAddress)) { + ObjectAddress address = (baseObject instanceof UnknownValue) ? ((UnknownValue) baseObject).address + : ((KnownAddress) baseObject).address; + if (V.indexed) { + emit(Machine.LOADAop, 0, displayRegister(frame.level, address.level), + address.displacement + V.offset); + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + emit(Machine.LOADIop, valSize, 0, 0); + } else + emit(Machine.LOADop, valSize, displayRegister(frame.level, + address.level), address.displacement + V.offset); + } else if (baseObject instanceof UnknownAddress) { + ObjectAddress address = ((UnknownAddress) baseObject).address; + emit(Machine.LOADop, Machine.addressSize, displayRegister(frame.level, + address.level), address.displacement); + if (V.indexed) + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + if (V.offset != 0) { + emit(Machine.LOADLop, 0, 0, V.offset); + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + } + emit(Machine.LOADIop, valSize, 0, 0); + } + } + + // Generates code to compute and push the address of a named variable. + // vname is the program phrase that names this variable. + // currentLevel is the routine level where the vname occurs. + // frameSize is the anticipated size of the local stack frame when + // the variable is addressed at run-time. + + private void encodeFetchAddress(Vname V, Frame frame) { + + RuntimeEntity baseObject = (RuntimeEntity) V.visit(this, frame); + // If indexed = true, code will have been generated to load an index value. + if (baseObject instanceof KnownAddress) { + ObjectAddress address = ((KnownAddress) baseObject).address; + emit(Machine.LOADAop, 0, displayRegister(frame.level, address.level), + address.displacement + V.offset); + if (V.indexed) + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + } else if (baseObject instanceof UnknownAddress) { + ObjectAddress address = ((UnknownAddress) baseObject).address; + emit(Machine.LOADop, Machine.addressSize, displayRegister(frame.level, + address.level), address.displacement); + if (V.indexed) + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + if (V.offset != 0) { + emit(Machine.LOADLop, 0, 0, V.offset); + emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement); + } + } + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/EqualityRoutine.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/EqualityRoutine.java new file mode 100644 index 0000000..2ae074b --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/EqualityRoutine.java @@ -0,0 +1,30 @@ +/* + * @(#)EqualityRoutine.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.CodeGenerator; + +public class EqualityRoutine extends RuntimeEntity { + + public EqualityRoutine() { + super(); + } + + public EqualityRoutine(int size, int displacement) { + super(size); + this.displacement = displacement; + } + + public int displacement; + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Field.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Field.java new file mode 100644 index 0000000..6697e61 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Field.java @@ -0,0 +1,31 @@ +/* + * @(#)Field.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.CodeGenerator; + +public class Field extends RuntimeEntity { + + public Field() { + super(); + fieldOffset = 0; + } + + public Field(int size, int fieldOffset) { + super(size); + this.fieldOffset = fieldOffset; + } + + public int fieldOffset; + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Frame.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Frame.java new file mode 100644 index 0000000..7b8066f --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/Frame.java @@ -0,0 +1,46 @@ +/* + * @(#)Frame.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.CodeGenerator; + +public class Frame { + + public Frame() { + this.level = 0; + this.size = 0; + } + + public Frame(int level, Integer size) { + this.level = level; + this.size = size.intValue(); + } + + public Frame(int level, int size) { + this.level = level; + this.size = size; + } + + public Frame(Frame frame, int sizeIncrement) { + this.level = frame.level; + this.size = frame.size + sizeIncrement; + } + + public Frame(Frame frame, Integer sizeIncrement) { + this.level = frame.level; + this.size = frame.size + sizeIncrement.intValue(); + } + + protected int level; + protected int size; +} diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownAddress.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownAddress.java new file mode 100644 index 0000000..f36a95b --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownAddress.java @@ -0,0 +1,31 @@ +/* + * @(#)KnownAddress.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.CodeGenerator; + +public class KnownAddress extends RuntimeEntity { + + public KnownAddress() { + super(); + address = null; + } + + public KnownAddress(int size, int level, int displacement) { + super(size); + address = new ObjectAddress(level, displacement); + } + + public ObjectAddress address; + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownRoutine.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownRoutine.java new file mode 100644 index 0000000..3e05661 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownRoutine.java @@ -0,0 +1,31 @@ +/* + * @(#)KnownRoutine.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.CodeGenerator; + +public class KnownRoutine extends RuntimeEntity { + + public KnownRoutine() { + super(); + address = null; + } + + public KnownRoutine(int size, int level, int displacement) { + super(size); + address = new ObjectAddress(level, displacement); + } + + public ObjectAddress address; + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownValue.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownValue.java new file mode 100644 index 0000000..24635f2 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/KnownValue.java @@ -0,0 +1,31 @@ +/* + * @(#)KnownValue.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.CodeGenerator; + +public class KnownValue extends RuntimeEntity { + + public KnownValue() { + super(); + value = 0; + } + + public KnownValue(int size, int value) { + super(size); + this.value = value; + } + + public int value; + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/ObjectAddress.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/ObjectAddress.java new file mode 100644 index 0000000..db1156a --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/ObjectAddress.java @@ -0,0 +1,26 @@ +/* + * @(#)ObjectAddress.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.CodeGenerator; + +public final class ObjectAddress { + + public ObjectAddress(int level, int displacement) { + this.level = level; + this.displacement = displacement; + } + + public int level, displacement; + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/PrimitiveRoutine.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/PrimitiveRoutine.java new file mode 100644 index 0000000..37e6894 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/PrimitiveRoutine.java @@ -0,0 +1,31 @@ +/* + * @(#)PrimitiveRoutine.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.CodeGenerator; + +public class PrimitiveRoutine extends RuntimeEntity { + + public PrimitiveRoutine() { + super(); + displacement = 0; + } + + public PrimitiveRoutine(int size, int displacement) { + super(size); + this.displacement = displacement; + } + + public int displacement; + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/RuntimeEntity.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/RuntimeEntity.java new file mode 100644 index 0000000..40d4d21 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/RuntimeEntity.java @@ -0,0 +1,33 @@ +/* + * @(#)RuntimeEntity.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.CodeGenerator; + +// Run-time object + +public abstract class RuntimeEntity { + + public final static int maxRoutineLevel = 7; + + public RuntimeEntity() { + size = 0; + } + + public RuntimeEntity(int size) { + this.size = size; + } + + public int size; + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/TypeRepresentation.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/TypeRepresentation.java new file mode 100644 index 0000000..a14a087 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/TypeRepresentation.java @@ -0,0 +1,23 @@ +/* + * @(#)TypeRepresentation.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.CodeGenerator; + +public class TypeRepresentation extends RuntimeEntity { + + public TypeRepresentation(int size) { + super(size); + } + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownAddress.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownAddress.java new file mode 100644 index 0000000..f1e7605 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownAddress.java @@ -0,0 +1,31 @@ +/* + * @(#)UnknownAddress.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.CodeGenerator; + +public class UnknownAddress extends RuntimeEntity { + + public UnknownAddress() { + super(); + address = null; + } + + public UnknownAddress(int size, int level, int displacement) { + super(size); + address = new ObjectAddress(level, displacement); + } + + public ObjectAddress address; + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownRoutine.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownRoutine.java new file mode 100644 index 0000000..58df472 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownRoutine.java @@ -0,0 +1,31 @@ +/* + * @(#)UnknownRoutine.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.CodeGenerator; + +public class UnknownRoutine extends RuntimeEntity { + + public UnknownRoutine() { + super(); + address = null; + } + + public UnknownRoutine(int size, int level, int displacement) { + super(size); + address = new ObjectAddress(level, displacement); + } + + public ObjectAddress address; + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownValue.java b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownValue.java new file mode 100644 index 0000000..c5d3085 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/CodeGenerator/UnknownValue.java @@ -0,0 +1,31 @@ +/* + * @(#)UnknownValue.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.CodeGenerator; + +public class UnknownValue extends RuntimeEntity { + + public UnknownValue() { + super(); + address = null; + } + + public UnknownValue(int size, int level, int displacement) { + super(size); + address = new ObjectAddress(level, displacement); + } + + public ObjectAddress address; + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/Compiler.java b/Triangle.Compiler/src/main/java/Triangle/Compiler.java new file mode 100644 index 0000000..6e4be43 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/Compiler.java @@ -0,0 +1,127 @@ +/* + * @(#)Compiler.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle; + +import Triangle.AbstractSyntaxTrees.Program; +import Triangle.CodeGenerator.Encoder; +import Triangle.ContextualAnalyzer.Checker; +import Triangle.SyntacticAnalyzer.Parser; +import Triangle.SyntacticAnalyzer.Scanner; +import Triangle.SyntacticAnalyzer.SourceFile; +import Triangle.TreeDrawer.Drawer; + +/** + * The main driver class for the Triangle compiler. + * + * @version 2.1 7 Oct 2003 + * @author Deryck F. Brown + */ +public class Compiler { + + /** The filename for the object program, normally obj.tam. */ + static String objectName = "obj.tam"; + + private static Scanner scanner; + private static Parser parser; + private static Checker checker; + private static Encoder encoder; + private static ErrorReporter reporter; + private static Drawer drawer; + + /** The AST representing the source program. */ + private static Program theAST; + + /** + * Compile the source program to TAM machine code. + * + * @param sourceName the name of the file containing the + * source program. + * @param objectName the name of the file containing the + * object program. + * @param showingAST true iff the AST is to be displayed after + * contextual analysis (not currently implemented). + * @param showingTable true iff the object description details are to + * be displayed during code generation (not + * currently implemented). + * @return true iff the source program is free of compile-time errors, + * otherwise false. + */ + static boolean compileProgram(String sourceName, String objectName, + boolean showingAST, boolean showingTable) { + + System.out.println("********** " + + "Triangle Compiler (Java Version 2.1)" + + " **********"); + + System.out.println("Syntactic Analysis ..."); + SourceFile source = new SourceFile(sourceName); + + if (source == null) { + System.out.println("Can't access source file " + sourceName); + System.exit(1); + } + + scanner = new Scanner(source); + reporter = new ErrorReporter(); + parser = new Parser(scanner, reporter); + checker = new Checker(reporter); + encoder = new Encoder(reporter); + drawer = new Drawer(); + + // scanner.enableDebugging(); + theAST = parser.parseProgram(); // 1st pass + if (reporter.numErrors == 0) { + // if (showingAST) { + // drawer.draw(theAST); + // } + System.out.println("Contextual Analysis ..."); + checker.check(theAST); // 2nd pass + if (showingAST) { + drawer.draw(theAST); + } + if (reporter.numErrors == 0) { + System.out.println("Code Generation ..."); + encoder.encodeRun(theAST, showingTable); // 3rd pass + } + } + + boolean successful = (reporter.numErrors == 0); + if (successful) { + encoder.saveObjectProgram(objectName); + System.out.println("Compilation was successful."); + } else { + System.out.println("Compilation was unsuccessful."); + } + return successful; + } + + /** + * Triangle compiler main program. + * + * @param args the only command-line argument to the program specifies + * the source filename. + */ + public static void main(String[] args) { + boolean compiledOK; + + if (args.length != 1) { + System.out.println("Usage: tc filename"); + System.exit(1); + } + + String sourceName = args[0]; + compiledOK = compileProgram(sourceName, objectName, false, false); + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/Checker.java b/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/Checker.java new file mode 100644 index 0000000..fae8e7a --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/Checker.java @@ -0,0 +1,951 @@ +/* + * @(#)Checker.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.ContextualAnalyzer; + +import Triangle.ErrorReporter; +import Triangle.StdEnvironment; +import Triangle.AbstractSyntaxTrees.AnyTypeDenoter; +import Triangle.AbstractSyntaxTrees.ArrayExpression; +import Triangle.AbstractSyntaxTrees.ArrayTypeDenoter; +import Triangle.AbstractSyntaxTrees.AssignCommand; +import Triangle.AbstractSyntaxTrees.BinaryExpression; +import Triangle.AbstractSyntaxTrees.BinaryOperatorDeclaration; +import Triangle.AbstractSyntaxTrees.BoolTypeDenoter; +import Triangle.AbstractSyntaxTrees.CallCommand; +import Triangle.AbstractSyntaxTrees.CallExpression; +import Triangle.AbstractSyntaxTrees.CharTypeDenoter; +import Triangle.AbstractSyntaxTrees.CharacterExpression; +import Triangle.AbstractSyntaxTrees.CharacterLiteral; +import Triangle.AbstractSyntaxTrees.ConstActualParameter; +import Triangle.AbstractSyntaxTrees.ConstDeclaration; +import Triangle.AbstractSyntaxTrees.ConstFormalParameter; +import Triangle.AbstractSyntaxTrees.Declaration; +import Triangle.AbstractSyntaxTrees.DotVname; +import Triangle.AbstractSyntaxTrees.EmptyActualParameterSequence; +import Triangle.AbstractSyntaxTrees.EmptyCommand; +import Triangle.AbstractSyntaxTrees.EmptyExpression; +import Triangle.AbstractSyntaxTrees.EmptyFormalParameterSequence; +import Triangle.AbstractSyntaxTrees.ErrorTypeDenoter; +import Triangle.AbstractSyntaxTrees.FieldTypeDenoter; +import Triangle.AbstractSyntaxTrees.FormalParameter; +import Triangle.AbstractSyntaxTrees.FormalParameterSequence; +import Triangle.AbstractSyntaxTrees.FuncActualParameter; +import Triangle.AbstractSyntaxTrees.FuncDeclaration; +import Triangle.AbstractSyntaxTrees.FuncFormalParameter; +import Triangle.AbstractSyntaxTrees.Identifier; +import Triangle.AbstractSyntaxTrees.IfCommand; +import Triangle.AbstractSyntaxTrees.IfExpression; +import Triangle.AbstractSyntaxTrees.IntTypeDenoter; +import Triangle.AbstractSyntaxTrees.IntegerExpression; +import Triangle.AbstractSyntaxTrees.IntegerLiteral; +import Triangle.AbstractSyntaxTrees.LetCommand; +import Triangle.AbstractSyntaxTrees.LetExpression; +import Triangle.AbstractSyntaxTrees.MultipleActualParameterSequence; +import Triangle.AbstractSyntaxTrees.MultipleArrayAggregate; +import Triangle.AbstractSyntaxTrees.MultipleFieldTypeDenoter; +import Triangle.AbstractSyntaxTrees.MultipleFormalParameterSequence; +import Triangle.AbstractSyntaxTrees.MultipleRecordAggregate; +import Triangle.AbstractSyntaxTrees.Operator; +import Triangle.AbstractSyntaxTrees.ProcActualParameter; +import Triangle.AbstractSyntaxTrees.ProcDeclaration; +import Triangle.AbstractSyntaxTrees.ProcFormalParameter; +import Triangle.AbstractSyntaxTrees.Program; +import Triangle.AbstractSyntaxTrees.RecordExpression; +import Triangle.AbstractSyntaxTrees.RecordTypeDenoter; +import Triangle.AbstractSyntaxTrees.SequentialCommand; +import Triangle.AbstractSyntaxTrees.SequentialDeclaration; +import Triangle.AbstractSyntaxTrees.SimpleTypeDenoter; +import Triangle.AbstractSyntaxTrees.SimpleVname; +import Triangle.AbstractSyntaxTrees.SingleActualParameterSequence; +import Triangle.AbstractSyntaxTrees.SingleArrayAggregate; +import Triangle.AbstractSyntaxTrees.SingleFieldTypeDenoter; +import Triangle.AbstractSyntaxTrees.SingleFormalParameterSequence; +import Triangle.AbstractSyntaxTrees.SingleRecordAggregate; +import Triangle.AbstractSyntaxTrees.SubscriptVname; +import Triangle.AbstractSyntaxTrees.Terminal; +import Triangle.AbstractSyntaxTrees.TypeDeclaration; +import Triangle.AbstractSyntaxTrees.TypeDenoter; +import Triangle.AbstractSyntaxTrees.UnaryExpression; +import Triangle.AbstractSyntaxTrees.UnaryOperatorDeclaration; +import Triangle.AbstractSyntaxTrees.VarActualParameter; +import Triangle.AbstractSyntaxTrees.VarDeclaration; +import Triangle.AbstractSyntaxTrees.VarFormalParameter; +import Triangle.AbstractSyntaxTrees.Visitor; +import Triangle.AbstractSyntaxTrees.VnameExpression; +import Triangle.AbstractSyntaxTrees.WhileCommand; +import Triangle.SyntacticAnalyzer.SourcePosition; + +public final class Checker implements Visitor { + + // Commands + + // Always returns null. Does not use the given object. + + public Object visitAssignCommand(AssignCommand ast, Object o) { + TypeDenoter vType = (TypeDenoter) ast.V.visit(this, null); + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + if (!ast.V.variable) + reporter.reportError("LHS of assignment is not a variable", "", ast.V.position); + if (!eType.equals(vType)) + reporter.reportError("assignment incompatibilty", "", ast.position); + return null; + } + + public Object visitCallCommand(CallCommand ast, Object o) { + + Declaration binding = (Declaration) ast.I.visit(this, null); + if (binding == null) + reportUndeclared(ast.I); + else if (binding instanceof ProcDeclaration) { + ast.APS.visit(this, ((ProcDeclaration) binding).FPS); + } else if (binding instanceof ProcFormalParameter) { + ast.APS.visit(this, ((ProcFormalParameter) binding).FPS); + } else + reporter.reportError("\"%\" is not a procedure identifier", + ast.I.spelling, ast.I.position); + return null; + } + + public Object visitEmptyCommand(EmptyCommand ast, Object o) { + return null; + } + + public Object visitIfCommand(IfCommand ast, Object o) { + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + if (!eType.equals(StdEnvironment.booleanType)) + reporter.reportError("Boolean expression expected here", "", ast.E.position); + ast.C1.visit(this, null); + ast.C2.visit(this, null); + return null; + } + + public Object visitLetCommand(LetCommand ast, Object o) { + idTable.openScope(); + ast.D.visit(this, null); + ast.C.visit(this, null); + idTable.closeScope(); + return null; + } + + public Object visitSequentialCommand(SequentialCommand ast, Object o) { + ast.C1.visit(this, null); + ast.C2.visit(this, null); + return null; + } + + public Object visitWhileCommand(WhileCommand ast, Object o) { + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + if (!eType.equals(StdEnvironment.booleanType)) + reporter.reportError("Boolean expression expected here", "", ast.E.position); + ast.C.visit(this, null); + return null; + } + + // Expressions + + // Returns the TypeDenoter denoting the type of the expression. Does + // not use the given object. + + public Object visitArrayExpression(ArrayExpression ast, Object o) { + TypeDenoter elemType = (TypeDenoter) ast.AA.visit(this, null); + IntegerLiteral il = new IntegerLiteral(new Integer(ast.AA.elemCount).toString(), + ast.position); + ast.type = new ArrayTypeDenoter(il, elemType, ast.position); + return ast.type; + } + + public Object visitBinaryExpression(BinaryExpression ast, Object o) { + + TypeDenoter e1Type = (TypeDenoter) ast.E1.visit(this, null); + TypeDenoter e2Type = (TypeDenoter) ast.E2.visit(this, null); + Declaration binding = (Declaration) ast.O.visit(this, null); + + if (binding == null) + reportUndeclared(ast.O); + else { + if (!(binding instanceof BinaryOperatorDeclaration)) + reporter.reportError("\"%\" is not a binary operator", + ast.O.spelling, ast.O.position); + BinaryOperatorDeclaration bbinding = (BinaryOperatorDeclaration) binding; + if (bbinding.ARG1 == StdEnvironment.anyType) { + // this operator must be "=" or "\=" + if (!e1Type.equals(e2Type)) + reporter.reportError("incompatible argument types for \"%\"", + ast.O.spelling, ast.position); + } else if (!e1Type.equals(bbinding.ARG1)) + reporter.reportError("wrong argument type for \"%\"", + ast.O.spelling, ast.E1.position); + else if (!e2Type.equals(bbinding.ARG2)) + reporter.reportError("wrong argument type for \"%\"", + ast.O.spelling, ast.E2.position); + ast.type = bbinding.RES; + } + return ast.type; + } + + public Object visitCallExpression(CallExpression ast, Object o) { + Declaration binding = (Declaration) ast.I.visit(this, null); + if (binding == null) { + reportUndeclared(ast.I); + ast.type = StdEnvironment.errorType; + } else if (binding instanceof FuncDeclaration) { + ast.APS.visit(this, ((FuncDeclaration) binding).FPS); + ast.type = ((FuncDeclaration) binding).T; + } else if (binding instanceof FuncFormalParameter) { + ast.APS.visit(this, ((FuncFormalParameter) binding).FPS); + ast.type = ((FuncFormalParameter) binding).T; + } else + reporter.reportError("\"%\" is not a function identifier", + ast.I.spelling, ast.I.position); + return ast.type; + } + + public Object visitCharacterExpression(CharacterExpression ast, Object o) { + ast.type = StdEnvironment.charType; + return ast.type; + } + + public Object visitEmptyExpression(EmptyExpression ast, Object o) { + ast.type = null; + return ast.type; + } + + public Object visitIfExpression(IfExpression ast, Object o) { + TypeDenoter e1Type = (TypeDenoter) ast.E1.visit(this, null); + if (!e1Type.equals(StdEnvironment.booleanType)) + reporter.reportError("Boolean expression expected here", "", + ast.E1.position); + TypeDenoter e2Type = (TypeDenoter) ast.E2.visit(this, null); + TypeDenoter e3Type = (TypeDenoter) ast.E3.visit(this, null); + if (!e2Type.equals(e3Type)) + reporter.reportError("incompatible limbs in if-expression", "", ast.position); + ast.type = e2Type; + return ast.type; + } + + public Object visitIntegerExpression(IntegerExpression ast, Object o) { + ast.type = StdEnvironment.integerType; + return ast.type; + } + + public Object visitLetExpression(LetExpression ast, Object o) { + idTable.openScope(); + ast.D.visit(this, null); + ast.type = (TypeDenoter) ast.E.visit(this, null); + idTable.closeScope(); + return ast.type; + } + + public Object visitRecordExpression(RecordExpression ast, Object o) { + FieldTypeDenoter rType = (FieldTypeDenoter) ast.RA.visit(this, null); + ast.type = new RecordTypeDenoter(rType, ast.position); + return ast.type; + } + + public Object visitUnaryExpression(UnaryExpression ast, Object o) { + + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + Declaration binding = (Declaration) ast.O.visit(this, null); + if (binding == null) { + reportUndeclared(ast.O); + ast.type = StdEnvironment.errorType; + } else if (!(binding instanceof UnaryOperatorDeclaration)) + reporter.reportError("\"%\" is not a unary operator", + ast.O.spelling, ast.O.position); + else { + UnaryOperatorDeclaration ubinding = (UnaryOperatorDeclaration) binding; + if (!eType.equals(ubinding.ARG)) + reporter.reportError("wrong argument type for \"%\"", + ast.O.spelling, ast.O.position); + ast.type = ubinding.RES; + } + return ast.type; + } + + public Object visitVnameExpression(VnameExpression ast, Object o) { + ast.type = (TypeDenoter) ast.V.visit(this, null); + return ast.type; + } + + // Declarations + + // Always returns null. Does not use the given object. + public Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Object o) { + return null; + } + + public Object visitConstDeclaration(ConstDeclaration ast, Object o) { + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + idTable.enter(ast.I.spelling, ast); + if (ast.duplicated) + reporter.reportError("identifier \"%\" already declared", + ast.I.spelling, ast.position); + return null; + } + + public Object visitFuncDeclaration(FuncDeclaration ast, Object o) { + ast.T = (TypeDenoter) ast.T.visit(this, null); + idTable.enter(ast.I.spelling, ast); // permits recursion + if (ast.duplicated) + reporter.reportError("identifier \"%\" already declared", + ast.I.spelling, ast.position); + idTable.openScope(); + ast.FPS.visit(this, null); + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + idTable.closeScope(); + if (!ast.T.equals(eType)) + reporter.reportError("body of function \"%\" has wrong type", + ast.I.spelling, ast.E.position); + return null; + } + + public Object visitProcDeclaration(ProcDeclaration ast, Object o) { + idTable.enter(ast.I.spelling, ast); // permits recursion + if (ast.duplicated) + reporter.reportError("identifier \"%\" already declared", + ast.I.spelling, ast.position); + idTable.openScope(); + ast.FPS.visit(this, null); + ast.C.visit(this, null); + idTable.closeScope(); + return null; + } + + public Object visitSequentialDeclaration(SequentialDeclaration ast, Object o) { + ast.D1.visit(this, null); + ast.D2.visit(this, null); + return null; + } + + public Object visitTypeDeclaration(TypeDeclaration ast, Object o) { + ast.T = (TypeDenoter) ast.T.visit(this, null); + idTable.enter(ast.I.spelling, ast); + if (ast.duplicated) + reporter.reportError("identifier \"%\" already declared", + ast.I.spelling, ast.position); + return null; + } + + public Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Object o) { + return null; + } + + public Object visitVarDeclaration(VarDeclaration ast, Object o) { + ast.T = (TypeDenoter) ast.T.visit(this, null); + idTable.enter(ast.I.spelling, ast); + if (ast.duplicated) + reporter.reportError("identifier \"%\" already declared", + ast.I.spelling, ast.position); + + return null; + } + + // Array Aggregates + + // Returns the TypeDenoter for the Array Aggregate. Does not use the + // given object. + + public Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, Object o) { + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + TypeDenoter elemType = (TypeDenoter) ast.AA.visit(this, null); + ast.elemCount = ast.AA.elemCount + 1; + if (!eType.equals(elemType)) + reporter.reportError("incompatible array-aggregate element", "", ast.E.position); + return elemType; + } + + public Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object o) { + TypeDenoter elemType = (TypeDenoter) ast.E.visit(this, null); + ast.elemCount = 1; + return elemType; + } + + // Record Aggregates + + // Returns the TypeDenoter for the Record Aggregate. Does not use the + // given object. + + public Object visitMultipleRecordAggregate(MultipleRecordAggregate ast, Object o) { + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + FieldTypeDenoter rType = (FieldTypeDenoter) ast.RA.visit(this, null); + TypeDenoter fType = checkFieldIdentifier(rType, ast.I); + if (fType != StdEnvironment.errorType) + reporter.reportError("duplicate field \"%\" in record", + ast.I.spelling, ast.I.position); + ast.type = new MultipleFieldTypeDenoter(ast.I, eType, rType, ast.position); + return ast.type; + } + + public Object visitSingleRecordAggregate(SingleRecordAggregate ast, Object o) { + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + ast.type = new SingleFieldTypeDenoter(ast.I, eType, ast.position); + return ast.type; + } + + // Formal Parameters + + // Always returns null. Does not use the given object. + + public Object visitConstFormalParameter(ConstFormalParameter ast, Object o) { + ast.T = (TypeDenoter) ast.T.visit(this, null); + idTable.enter(ast.I.spelling, ast); + if (ast.duplicated) + reporter.reportError("duplicated formal parameter \"%\"", + ast.I.spelling, ast.position); + return null; + } + + public Object visitFuncFormalParameter(FuncFormalParameter ast, Object o) { + idTable.openScope(); + ast.FPS.visit(this, null); + idTable.closeScope(); + ast.T = (TypeDenoter) ast.T.visit(this, null); + idTable.enter(ast.I.spelling, ast); + if (ast.duplicated) + reporter.reportError("duplicated formal parameter \"%\"", + ast.I.spelling, ast.position); + return null; + } + + public Object visitProcFormalParameter(ProcFormalParameter ast, Object o) { + idTable.openScope(); + ast.FPS.visit(this, null); + idTable.closeScope(); + idTable.enter(ast.I.spelling, ast); + if (ast.duplicated) + reporter.reportError("duplicated formal parameter \"%\"", + ast.I.spelling, ast.position); + return null; + } + + public Object visitVarFormalParameter(VarFormalParameter ast, Object o) { + ast.T = (TypeDenoter) ast.T.visit(this, null); + idTable.enter(ast.I.spelling, ast); + if (ast.duplicated) + reporter.reportError("duplicated formal parameter \"%\"", + ast.I.spelling, ast.position); + return null; + } + + public Object visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Object o) { + return null; + } + + public Object visitMultipleFormalParameterSequence(MultipleFormalParameterSequence ast, Object o) { + ast.FP.visit(this, null); + ast.FPS.visit(this, null); + return null; + } + + public Object visitSingleFormalParameterSequence(SingleFormalParameterSequence ast, Object o) { + ast.FP.visit(this, null); + return null; + } + + // Actual Parameters + + // Always returns null. Uses the given FormalParameter. + + public Object visitConstActualParameter(ConstActualParameter ast, Object o) { + FormalParameter fp = (FormalParameter) o; + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + + if (!(fp instanceof ConstFormalParameter)) + reporter.reportError("const actual parameter not expected here", "", + ast.position); + else if (!eType.equals(((ConstFormalParameter) fp).T)) + reporter.reportError("wrong type for const actual parameter", "", + ast.E.position); + return null; + } + + public Object visitFuncActualParameter(FuncActualParameter ast, Object o) { + FormalParameter fp = (FormalParameter) o; + + Declaration binding = (Declaration) ast.I.visit(this, null); + if (binding == null) + reportUndeclared(ast.I); + else if (!(binding instanceof FuncDeclaration || + binding instanceof FuncFormalParameter)) + reporter.reportError("\"%\" is not a function identifier", + ast.I.spelling, ast.I.position); + else if (!(fp instanceof FuncFormalParameter)) + reporter.reportError("func actual parameter not expected here", "", + ast.position); + else { + FormalParameterSequence FPS = null; + TypeDenoter T = null; + if (binding instanceof FuncDeclaration) { + FPS = ((FuncDeclaration) binding).FPS; + T = ((FuncDeclaration) binding).T; + } else { + FPS = ((FuncFormalParameter) binding).FPS; + T = ((FuncFormalParameter) binding).T; + } + if (!FPS.equals(((FuncFormalParameter) fp).FPS)) + reporter.reportError("wrong signature for function \"%\"", + ast.I.spelling, ast.I.position); + else if (!T.equals(((FuncFormalParameter) fp).T)) + reporter.reportError("wrong type for function \"%\"", + ast.I.spelling, ast.I.position); + } + return null; + } + + public Object visitProcActualParameter(ProcActualParameter ast, Object o) { + FormalParameter fp = (FormalParameter) o; + + Declaration binding = (Declaration) ast.I.visit(this, null); + if (binding == null) + reportUndeclared(ast.I); + else if (!(binding instanceof ProcDeclaration || + binding instanceof ProcFormalParameter)) + reporter.reportError("\"%\" is not a procedure identifier", + ast.I.spelling, ast.I.position); + else if (!(fp instanceof ProcFormalParameter)) + reporter.reportError("proc actual parameter not expected here", "", + ast.position); + else { + FormalParameterSequence FPS = null; + if (binding instanceof ProcDeclaration) + FPS = ((ProcDeclaration) binding).FPS; + else + FPS = ((ProcFormalParameter) binding).FPS; + if (!FPS.equals(((ProcFormalParameter) fp).FPS)) + reporter.reportError("wrong signature for procedure \"%\"", + ast.I.spelling, ast.I.position); + } + return null; + } + + public Object visitVarActualParameter(VarActualParameter ast, Object o) { + FormalParameter fp = (FormalParameter) o; + + TypeDenoter vType = (TypeDenoter) ast.V.visit(this, null); + if (!ast.V.variable) + reporter.reportError("actual parameter is not a variable", "", + ast.V.position); + else if (!(fp instanceof VarFormalParameter)) + reporter.reportError("var actual parameter not expected here", "", + ast.V.position); + else if (!vType.equals(((VarFormalParameter) fp).T)) + reporter.reportError("wrong type for var actual parameter", "", + ast.V.position); + return null; + } + + public Object visitEmptyActualParameterSequence(EmptyActualParameterSequence ast, Object o) { + FormalParameterSequence fps = (FormalParameterSequence) o; + if (!(fps instanceof EmptyFormalParameterSequence)) + reporter.reportError("too few actual parameters", "", ast.position); + return null; + } + + public Object visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, Object o) { + FormalParameterSequence fps = (FormalParameterSequence) o; + if (!(fps instanceof MultipleFormalParameterSequence)) + reporter.reportError("too many actual parameters", "", ast.position); + else { + ast.AP.visit(this, ((MultipleFormalParameterSequence) fps).FP); + ast.APS.visit(this, ((MultipleFormalParameterSequence) fps).FPS); + } + return null; + } + + public Object visitSingleActualParameterSequence(SingleActualParameterSequence ast, Object o) { + FormalParameterSequence fps = (FormalParameterSequence) o; + if (!(fps instanceof SingleFormalParameterSequence)) + reporter.reportError("incorrect number of actual parameters", "", ast.position); + else { + ast.AP.visit(this, ((SingleFormalParameterSequence) fps).FP); + } + return null; + } + + // Type Denoters + + // Returns the expanded version of the TypeDenoter. Does not + // use the given object. + + public Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object o) { + return StdEnvironment.anyType; + } + + public Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object o) { + ast.T = (TypeDenoter) ast.T.visit(this, null); + if ((Integer.valueOf(ast.IL.spelling).intValue()) == 0) + reporter.reportError("arrays must not be empty", "", ast.IL.position); + return ast; + } + + public Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object o) { + return StdEnvironment.booleanType; + } + + public Object visitCharTypeDenoter(CharTypeDenoter ast, Object o) { + return StdEnvironment.charType; + } + + public Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object o) { + return StdEnvironment.errorType; + } + + public Object visitSimpleTypeDenoter(SimpleTypeDenoter ast, Object o) { + Declaration binding = (Declaration) ast.I.visit(this, null); + if (binding == null) { + reportUndeclared(ast.I); + return StdEnvironment.errorType; + } else if (!(binding instanceof TypeDeclaration)) { + reporter.reportError("\"%\" is not a type identifier", + ast.I.spelling, ast.I.position); + return StdEnvironment.errorType; + } + return ((TypeDeclaration) binding).T; + } + + public Object visitIntTypeDenoter(IntTypeDenoter ast, Object o) { + return StdEnvironment.integerType; + } + + public Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object o) { + ast.FT = (FieldTypeDenoter) ast.FT.visit(this, null); + return ast; + } + + public Object visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, Object o) { + ast.T = (TypeDenoter) ast.T.visit(this, null); + ast.FT.visit(this, null); + return ast; + } + + public Object visitSingleFieldTypeDenoter(SingleFieldTypeDenoter ast, Object o) { + ast.T = (TypeDenoter) ast.T.visit(this, null); + return ast; + } + + // Literals, Identifiers and Operators + public Object visitCharacterLiteral(CharacterLiteral CL, Object o) { + return StdEnvironment.charType; + } + + public Object visitIdentifier(Identifier I, Object o) { + Declaration binding = idTable.retrieve(I.spelling); + if (binding != null) + I.decl = binding; + return binding; + } + + public Object visitIntegerLiteral(IntegerLiteral IL, Object o) { + return StdEnvironment.integerType; + } + + public Object visitOperator(Operator O, Object o) { + Declaration binding = idTable.retrieve(O.spelling); + if (binding != null) + O.decl = binding; + return binding; + } + + // Value-or-variable names + + // Determines the address of a named object (constant or variable). + // This consists of a base object, to which 0 or more field-selection + // or array-indexing operations may be applied (if it is a record or + // array). As much as possible of the address computation is done at + // compile-time. Code is generated only when necessary to evaluate + // index expressions at run-time. + // currentLevel is the routine level where the v-name occurs. + // frameSize is the anticipated size of the local stack frame when + // the object is addressed at run-time. + // It returns the description of the base object. + // offset is set to the total of any field offsets (plus any offsets + // due to index expressions that happen to be literals). + // indexed is set to true iff there are any index expressions (other + // than literals). In that case code is generated to compute the + // offset due to these indexing operations at run-time. + + // Returns the TypeDenoter of the Vname. Does not use the + // given object. + + public Object visitDotVname(DotVname ast, Object o) { + ast.type = null; + TypeDenoter vType = (TypeDenoter) ast.V.visit(this, null); + ast.variable = ast.V.variable; + if (!(vType instanceof RecordTypeDenoter)) + reporter.reportError("record expected here", "", ast.V.position); + else { + ast.type = checkFieldIdentifier(((RecordTypeDenoter) vType).FT, ast.I); + if (ast.type == StdEnvironment.errorType) + reporter.reportError("no field \"%\" in this record type", + ast.I.spelling, ast.I.position); + } + return ast.type; + } + + public Object visitSimpleVname(SimpleVname ast, Object o) { + ast.variable = false; + ast.type = StdEnvironment.errorType; + Declaration binding = (Declaration) ast.I.visit(this, null); + if (binding == null) + reportUndeclared(ast.I); + else if (binding instanceof ConstDeclaration) { + ast.type = ((ConstDeclaration) binding).E.type; + ast.variable = false; + } else if (binding instanceof VarDeclaration) { + ast.type = ((VarDeclaration) binding).T; + ast.variable = true; + } else if (binding instanceof ConstFormalParameter) { + ast.type = ((ConstFormalParameter) binding).T; + ast.variable = false; + } else if (binding instanceof VarFormalParameter) { + ast.type = ((VarFormalParameter) binding).T; + ast.variable = true; + } else + reporter.reportError("\"%\" is not a const or var identifier", + ast.I.spelling, ast.I.position); + return ast.type; + } + + public Object visitSubscriptVname(SubscriptVname ast, Object o) { + TypeDenoter vType = (TypeDenoter) ast.V.visit(this, null); + ast.variable = ast.V.variable; + TypeDenoter eType = (TypeDenoter) ast.E.visit(this, null); + if (vType != StdEnvironment.errorType) { + if (!(vType instanceof ArrayTypeDenoter)) + reporter.reportError("array expected here", "", ast.V.position); + else { + if (!eType.equals(StdEnvironment.integerType)) + reporter.reportError("Integer expression expected here", "", + ast.E.position); + ast.type = ((ArrayTypeDenoter) vType).T; + } + } + return ast.type; + } + + // Programs + + public Object visitProgram(Program ast, Object o) { + ast.C.visit(this, null); + return null; + } + + // Checks whether the source program, represented by its AST, satisfies the + // language's scope rules and type rules. + // Also decorates the AST as follows: + // (a) Each applied occurrence of an identifier or operator is linked to + // the corresponding declaration of that identifier or operator. + // (b) Each expression and value-or-variable-name is decorated by its type. + // (c) Each type identifier is replaced by the type it denotes. + // Types are represented by small ASTs. + + public void check(Program ast) { + ast.visit(this, null); + } + + ///////////////////////////////////////////////////////////////////////////// + + public Checker(ErrorReporter reporter) { + this.reporter = reporter; + this.idTable = new IdentificationTable(); + establishStdEnvironment(); + } + + private IdentificationTable idTable; + private static SourcePosition dummyPos = new SourcePosition(); + private ErrorReporter reporter; + + // Reports that the identifier or operator used at a leaf of the AST + // has not been declared. + + private void reportUndeclared(Terminal leaf) { + reporter.reportError("\"%\" is not declared", leaf.spelling, leaf.position); + } + + private static TypeDenoter checkFieldIdentifier(FieldTypeDenoter ast, Identifier I) { + if (ast instanceof MultipleFieldTypeDenoter) { + MultipleFieldTypeDenoter ft = (MultipleFieldTypeDenoter) ast; + if (ft.I.spelling.compareTo(I.spelling) == 0) { + I.decl = ast; + return ft.T; + } else { + return checkFieldIdentifier(ft.FT, I); + } + } else if (ast instanceof SingleFieldTypeDenoter) { + SingleFieldTypeDenoter ft = (SingleFieldTypeDenoter) ast; + if (ft.I.spelling.compareTo(I.spelling) == 0) { + I.decl = ast; + return ft.T; + } + } + return StdEnvironment.errorType; + } + + // Creates a small AST to represent the "declaration" of a standard + // type, and enters it in the identification table. + + private TypeDeclaration declareStdType(String id, TypeDenoter typedenoter) { + + TypeDeclaration binding; + + binding = new TypeDeclaration(new Identifier(id, dummyPos), typedenoter, dummyPos); + idTable.enter(id, binding); + return binding; + } + + // Creates a small AST to represent the "declaration" of a standard + // type, and enters it in the identification table. + + private ConstDeclaration declareStdConst(String id, TypeDenoter constType) { + + IntegerExpression constExpr; + ConstDeclaration binding; + + // constExpr used only as a placeholder for constType + constExpr = new IntegerExpression(null, dummyPos); + constExpr.type = constType; + binding = new ConstDeclaration(new Identifier(id, dummyPos), constExpr, dummyPos); + idTable.enter(id, binding); + return binding; + } + + // Creates a small AST to represent the "declaration" of a standard + // type, and enters it in the identification table. + + private ProcDeclaration declareStdProc(String id, FormalParameterSequence fps) { + + ProcDeclaration binding; + + binding = new ProcDeclaration(new Identifier(id, dummyPos), fps, + new EmptyCommand(dummyPos), dummyPos); + idTable.enter(id, binding); + return binding; + } + + // Creates a small AST to represent the "declaration" of a standard + // type, and enters it in the identification table. + + private FuncDeclaration declareStdFunc(String id, FormalParameterSequence fps, + TypeDenoter resultType) { + + FuncDeclaration binding; + + binding = new FuncDeclaration(new Identifier(id, dummyPos), fps, resultType, + new EmptyExpression(dummyPos), dummyPos); + idTable.enter(id, binding); + return binding; + } + + // Creates a small AST to represent the "declaration" of a + // unary operator, and enters it in the identification table. + // This "declaration" summarises the operator's type info. + + private UnaryOperatorDeclaration declareStdUnaryOp(String op, TypeDenoter argType, TypeDenoter resultType) { + + UnaryOperatorDeclaration binding; + + binding = new UnaryOperatorDeclaration(new Operator(op, dummyPos), + argType, resultType, dummyPos); + idTable.enter(op, binding); + return binding; + } + + // Creates a small AST to represent the "declaration" of a + // binary operator, and enters it in the identification table. + // This "declaration" summarises the operator's type info. + + private BinaryOperatorDeclaration declareStdBinaryOp(String op, TypeDenoter arg1Type, TypeDenoter arg2type, + TypeDenoter resultType) { + + BinaryOperatorDeclaration binding; + + binding = new BinaryOperatorDeclaration(new Operator(op, dummyPos), + arg1Type, arg2type, resultType, dummyPos); + idTable.enter(op, binding); + return binding; + } + + // Creates small ASTs to represent the standard types. + // Creates small ASTs to represent "declarations" of standard types, + // constants, procedures, functions, and operators. + // Enters these "declarations" in the identification table. + + private final static Identifier dummyI = new Identifier("", dummyPos); + + private void establishStdEnvironment() { + + // idTable.startIdentification(); + StdEnvironment.booleanType = new BoolTypeDenoter(dummyPos); + StdEnvironment.integerType = new IntTypeDenoter(dummyPos); + StdEnvironment.charType = new CharTypeDenoter(dummyPos); + StdEnvironment.anyType = new AnyTypeDenoter(dummyPos); + StdEnvironment.errorType = new ErrorTypeDenoter(dummyPos); + + StdEnvironment.booleanDecl = declareStdType("Boolean", StdEnvironment.booleanType); + StdEnvironment.falseDecl = declareStdConst("false", StdEnvironment.booleanType); + StdEnvironment.trueDecl = declareStdConst("true", StdEnvironment.booleanType); + StdEnvironment.notDecl = declareStdUnaryOp("\\", StdEnvironment.booleanType, StdEnvironment.booleanType); + StdEnvironment.andDecl = declareStdBinaryOp("/\\", StdEnvironment.booleanType, StdEnvironment.booleanType, + StdEnvironment.booleanType); + StdEnvironment.orDecl = declareStdBinaryOp("\\/", StdEnvironment.booleanType, StdEnvironment.booleanType, + StdEnvironment.booleanType); + + StdEnvironment.integerDecl = declareStdType("Integer", StdEnvironment.integerType); + StdEnvironment.maxintDecl = declareStdConst("maxint", StdEnvironment.integerType); + StdEnvironment.addDecl = declareStdBinaryOp("+", StdEnvironment.integerType, StdEnvironment.integerType, + StdEnvironment.integerType); + StdEnvironment.subtractDecl = declareStdBinaryOp("-", StdEnvironment.integerType, StdEnvironment.integerType, + StdEnvironment.integerType); + StdEnvironment.multiplyDecl = declareStdBinaryOp("*", StdEnvironment.integerType, StdEnvironment.integerType, + StdEnvironment.integerType); + StdEnvironment.divideDecl = declareStdBinaryOp("/", StdEnvironment.integerType, StdEnvironment.integerType, + StdEnvironment.integerType); + StdEnvironment.moduloDecl = declareStdBinaryOp("//", StdEnvironment.integerType, StdEnvironment.integerType, + StdEnvironment.integerType); + StdEnvironment.lessDecl = declareStdBinaryOp("<", StdEnvironment.integerType, StdEnvironment.integerType, + StdEnvironment.booleanType); + StdEnvironment.notgreaterDecl = declareStdBinaryOp("<=", StdEnvironment.integerType, StdEnvironment.integerType, + StdEnvironment.booleanType); + StdEnvironment.greaterDecl = declareStdBinaryOp(">", StdEnvironment.integerType, StdEnvironment.integerType, + StdEnvironment.booleanType); + StdEnvironment.notlessDecl = declareStdBinaryOp(">=", StdEnvironment.integerType, StdEnvironment.integerType, + StdEnvironment.booleanType); + + StdEnvironment.charDecl = declareStdType("Char", StdEnvironment.charType); + StdEnvironment.chrDecl = declareStdFunc("chr", new SingleFormalParameterSequence( + new ConstFormalParameter(dummyI, StdEnvironment.integerType, dummyPos), dummyPos), StdEnvironment.charType); + StdEnvironment.ordDecl = declareStdFunc("ord", new SingleFormalParameterSequence( + new ConstFormalParameter(dummyI, StdEnvironment.charType, dummyPos), dummyPos), StdEnvironment.integerType); + StdEnvironment.eofDecl = declareStdFunc("eof", new EmptyFormalParameterSequence(dummyPos), + StdEnvironment.booleanType); + StdEnvironment.eolDecl = declareStdFunc("eol", new EmptyFormalParameterSequence(dummyPos), + StdEnvironment.booleanType); + StdEnvironment.getDecl = declareStdProc("get", new SingleFormalParameterSequence( + new VarFormalParameter(dummyI, StdEnvironment.charType, dummyPos), dummyPos)); + StdEnvironment.putDecl = declareStdProc("put", new SingleFormalParameterSequence( + new ConstFormalParameter(dummyI, StdEnvironment.charType, dummyPos), dummyPos)); + StdEnvironment.getintDecl = declareStdProc("getint", new SingleFormalParameterSequence( + new VarFormalParameter(dummyI, StdEnvironment.integerType, dummyPos), dummyPos)); + StdEnvironment.putintDecl = declareStdProc("putint", new SingleFormalParameterSequence( + new ConstFormalParameter(dummyI, StdEnvironment.integerType, dummyPos), dummyPos)); + StdEnvironment.geteolDecl = declareStdProc("geteol", new EmptyFormalParameterSequence(dummyPos)); + StdEnvironment.puteolDecl = declareStdProc("puteol", new EmptyFormalParameterSequence(dummyPos)); + StdEnvironment.equalDecl = declareStdBinaryOp("=", StdEnvironment.anyType, StdEnvironment.anyType, + StdEnvironment.booleanType); + StdEnvironment.unequalDecl = declareStdBinaryOp("\\=", StdEnvironment.anyType, StdEnvironment.anyType, + StdEnvironment.booleanType); + + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdEntry.java b/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdEntry.java new file mode 100644 index 0000000..465710d --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdEntry.java @@ -0,0 +1,33 @@ +/* + * @(#)IdEntry.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.ContextualAnalyzer; + +import Triangle.AbstractSyntaxTrees.Declaration; + +public class IdEntry { + + protected String id; + protected Declaration attr; + protected int level; + protected IdEntry previous; + + IdEntry(String id, Declaration attr, int level, IdEntry previous) { + this.id = id; + this.attr = attr; + this.level = level; + this.previous = previous; + } + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdentificationTable.java b/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdentificationTable.java new file mode 100644 index 0000000..a3276f0 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/ContextualAnalyzer/IdentificationTable.java @@ -0,0 +1,108 @@ +/* + * @(#)IdentificationTable.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.ContextualAnalyzer; + +import Triangle.AbstractSyntaxTrees.Declaration; + +public final class IdentificationTable { + + private int level; + private IdEntry latest; + + public IdentificationTable() { + level = 0; + latest = null; + } + + // Opens a new level in the identification table, 1 higher than the + // current topmost level. + + public void openScope() { + + level++; + } + + // Closes the topmost level in the identification table, discarding + // all entries belonging to that level. + + public void closeScope() { + + IdEntry entry, local; + + // Presumably, idTable.level > 0. + entry = this.latest; + while (entry.level == this.level) { + local = entry; + entry = local.previous; + } + this.level--; + this.latest = entry; + } + + // Makes a new entry in the identification table for the given identifier + // and attribute. The new entry belongs to the current level. + // duplicated is set to to true iff there is already an entry for the + // same identifier at the current level. + + public void enter(String id, Declaration attr) { + + IdEntry entry = this.latest; + boolean present = false, searching = true; + + // Check for duplicate entry ... + while (searching) { + if (entry == null || entry.level < this.level) + searching = false; + else if (entry.id.equals(id)) { + present = true; + searching = false; + } else + entry = entry.previous; + } + + attr.duplicated = present; + // Add new entry ... + entry = new IdEntry(id, attr, this.level, this.latest); + this.latest = entry; + } + + // Finds an entry for the given identifier in the identification table, + // if any. If there are several entries for that identifier, finds the + // entry at the highest level, in accordance with the scope rules. + // Returns null iff no entry is found. + // otherwise returns the attribute field of the entry found. + + public Declaration retrieve(String id) { + + IdEntry entry; + Declaration attr = null; + boolean present = false, searching = true; + + entry = this.latest; + while (searching) { + if (entry == null) + searching = false; + else if (entry.id.equals(id)) { + present = true; + searching = false; + attr = entry.attr; + } else + entry = entry.previous; + } + + return attr; + } + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/ErrorReporter.java b/Triangle.Compiler/src/main/java/Triangle/ErrorReporter.java new file mode 100644 index 0000000..aadbfcb --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/ErrorReporter.java @@ -0,0 +1,42 @@ +/* + * @(#)ErrorReporter.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle; + +import Triangle.SyntacticAnalyzer.SourcePosition; + +public class ErrorReporter { + + int numErrors; + + ErrorReporter() { + numErrors = 0; + } + + public void reportError(String message, String tokenName, SourcePosition pos) { + System.out.print("ERROR: "); + + for (int p = 0; p < message.length(); p++) + if (message.charAt(p) == '%') + System.out.print(tokenName); + else + System.out.print(message.charAt(p)); + System.out.println(" " + pos.start + ".." + pos.finish); + numErrors++; + } + + public void reportRestriction(String message) { + System.out.println("RESTRICTION: " + message); + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/StdEnvironment.java b/Triangle.Compiler/src/main/java/Triangle/StdEnvironment.java new file mode 100644 index 0000000..1366d1e --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/StdEnvironment.java @@ -0,0 +1,47 @@ +/* + * @(#)StdEnvironment.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle; + +import Triangle.AbstractSyntaxTrees.BinaryOperatorDeclaration; +import Triangle.AbstractSyntaxTrees.ConstDeclaration; +import Triangle.AbstractSyntaxTrees.FuncDeclaration; +import Triangle.AbstractSyntaxTrees.ProcDeclaration; +import Triangle.AbstractSyntaxTrees.TypeDeclaration; +import Triangle.AbstractSyntaxTrees.TypeDenoter; +import Triangle.AbstractSyntaxTrees.UnaryOperatorDeclaration; + +public final class StdEnvironment { + + // These are small ASTs representing standard types. + + public static TypeDenoter booleanType, charType, integerType, anyType, errorType; + + public static TypeDeclaration booleanDecl, charDecl, integerDecl; + + // These are small ASTs representing "declarations" of standard entities. + + public static ConstDeclaration falseDecl, trueDecl, maxintDecl; + + public static UnaryOperatorDeclaration notDecl; + + public static BinaryOperatorDeclaration andDecl, orDecl, + addDecl, subtractDecl, multiplyDecl, divideDecl, moduloDecl, + equalDecl, unequalDecl, lessDecl, notlessDecl, greaterDecl, notgreaterDecl; + + public static ProcDeclaration getDecl, putDecl, getintDecl, putintDecl, geteolDecl, puteolDecl; + + public static FuncDeclaration chrDecl, ordDecl, eolDecl, eofDecl; + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Parser.java b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Parser.java new file mode 100644 index 0000000..ded9e7e --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Parser.java @@ -0,0 +1,933 @@ +/* + * @(#)Parser.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.SyntacticAnalyzer; + +import Triangle.ErrorReporter; +import Triangle.AbstractSyntaxTrees.ActualParameter; +import Triangle.AbstractSyntaxTrees.ActualParameterSequence; +import Triangle.AbstractSyntaxTrees.ArrayAggregate; +import Triangle.AbstractSyntaxTrees.ArrayExpression; +import Triangle.AbstractSyntaxTrees.ArrayTypeDenoter; +import Triangle.AbstractSyntaxTrees.AssignCommand; +import Triangle.AbstractSyntaxTrees.BinaryExpression; +import Triangle.AbstractSyntaxTrees.CallCommand; +import Triangle.AbstractSyntaxTrees.CallExpression; +import Triangle.AbstractSyntaxTrees.CharacterExpression; +import Triangle.AbstractSyntaxTrees.CharacterLiteral; +import Triangle.AbstractSyntaxTrees.Command; +import Triangle.AbstractSyntaxTrees.ConstActualParameter; +import Triangle.AbstractSyntaxTrees.ConstDeclaration; +import Triangle.AbstractSyntaxTrees.ConstFormalParameter; +import Triangle.AbstractSyntaxTrees.Declaration; +import Triangle.AbstractSyntaxTrees.DotVname; +import Triangle.AbstractSyntaxTrees.EmptyActualParameterSequence; +import Triangle.AbstractSyntaxTrees.EmptyCommand; +import Triangle.AbstractSyntaxTrees.EmptyFormalParameterSequence; +import Triangle.AbstractSyntaxTrees.Expression; +import Triangle.AbstractSyntaxTrees.FieldTypeDenoter; +import Triangle.AbstractSyntaxTrees.FormalParameter; +import Triangle.AbstractSyntaxTrees.FormalParameterSequence; +import Triangle.AbstractSyntaxTrees.FuncActualParameter; +import Triangle.AbstractSyntaxTrees.FuncDeclaration; +import Triangle.AbstractSyntaxTrees.FuncFormalParameter; +import Triangle.AbstractSyntaxTrees.Identifier; +import Triangle.AbstractSyntaxTrees.IfCommand; +import Triangle.AbstractSyntaxTrees.IfExpression; +import Triangle.AbstractSyntaxTrees.IntegerExpression; +import Triangle.AbstractSyntaxTrees.IntegerLiteral; +import Triangle.AbstractSyntaxTrees.LetCommand; +import Triangle.AbstractSyntaxTrees.LetExpression; +import Triangle.AbstractSyntaxTrees.MultipleActualParameterSequence; +import Triangle.AbstractSyntaxTrees.MultipleArrayAggregate; +import Triangle.AbstractSyntaxTrees.MultipleFieldTypeDenoter; +import Triangle.AbstractSyntaxTrees.MultipleFormalParameterSequence; +import Triangle.AbstractSyntaxTrees.MultipleRecordAggregate; +import Triangle.AbstractSyntaxTrees.Operator; +import Triangle.AbstractSyntaxTrees.ProcActualParameter; +import Triangle.AbstractSyntaxTrees.ProcDeclaration; +import Triangle.AbstractSyntaxTrees.ProcFormalParameter; +import Triangle.AbstractSyntaxTrees.Program; +import Triangle.AbstractSyntaxTrees.RecordAggregate; +import Triangle.AbstractSyntaxTrees.RecordExpression; +import Triangle.AbstractSyntaxTrees.RecordTypeDenoter; +import Triangle.AbstractSyntaxTrees.SequentialCommand; +import Triangle.AbstractSyntaxTrees.SequentialDeclaration; +import Triangle.AbstractSyntaxTrees.SimpleTypeDenoter; +import Triangle.AbstractSyntaxTrees.SimpleVname; +import Triangle.AbstractSyntaxTrees.SingleActualParameterSequence; +import Triangle.AbstractSyntaxTrees.SingleArrayAggregate; +import Triangle.AbstractSyntaxTrees.SingleFieldTypeDenoter; +import Triangle.AbstractSyntaxTrees.SingleFormalParameterSequence; +import Triangle.AbstractSyntaxTrees.SingleRecordAggregate; +import Triangle.AbstractSyntaxTrees.SubscriptVname; +import Triangle.AbstractSyntaxTrees.TypeDeclaration; +import Triangle.AbstractSyntaxTrees.TypeDenoter; +import Triangle.AbstractSyntaxTrees.UnaryExpression; +import Triangle.AbstractSyntaxTrees.VarActualParameter; +import Triangle.AbstractSyntaxTrees.VarDeclaration; +import Triangle.AbstractSyntaxTrees.VarFormalParameter; +import Triangle.AbstractSyntaxTrees.Vname; +import Triangle.AbstractSyntaxTrees.VnameExpression; +import Triangle.AbstractSyntaxTrees.WhileCommand; + +public class Parser { + + private Scanner lexicalAnalyser; + private ErrorReporter errorReporter; + private Token currentToken; + private SourcePosition previousTokenPosition; + + public Parser(Scanner lexer, ErrorReporter reporter) { + lexicalAnalyser = lexer; + errorReporter = reporter; + previousTokenPosition = new SourcePosition(); + } + + // accept checks whether the current token matches tokenExpected. + // If so, fetches the next token. + // If not, reports a syntactic error. + + void accept(int tokenExpected) throws SyntaxError { + if (currentToken.kind == tokenExpected) { + previousTokenPosition = currentToken.position; + currentToken = lexicalAnalyser.scan(); + } else { + syntacticError("\"%\" expected here", Token.spell(tokenExpected)); + } + } + + void acceptIt() { + previousTokenPosition = currentToken.position; + currentToken = lexicalAnalyser.scan(); + } + + // start records the position of the start of a phrase. + // This is defined to be the position of the first + // character of the first token of the phrase. + + void start(SourcePosition position) { + position.start = currentToken.position.start; + } + + // finish records the position of the end of a phrase. + // This is defined to be the position of the last + // character of the last token of the phrase. + + void finish(SourcePosition position) { + position.finish = previousTokenPosition.finish; + } + + void syntacticError(String messageTemplate, String tokenQuoted) throws SyntaxError { + SourcePosition pos = currentToken.position; + errorReporter.reportError(messageTemplate, tokenQuoted, pos); + throw (new SyntaxError()); + } + + /////////////////////////////////////////////////////////////////////////////// + // + // PROGRAMS + // + /////////////////////////////////////////////////////////////////////////////// + + public Program parseProgram() { + + Program programAST = null; + + previousTokenPosition.start = 0; + previousTokenPosition.finish = 0; + currentToken = lexicalAnalyser.scan(); + + try { + Command cAST = parseCommand(); + programAST = new Program(cAST, previousTokenPosition); + if (currentToken.kind != Token.EOT) { + syntacticError("\"%\" not expected after end of program", + currentToken.spelling); + } + } catch (SyntaxError s) { + return null; + } + return programAST; + } + + /////////////////////////////////////////////////////////////////////////////// + // + // LITERALS + // + /////////////////////////////////////////////////////////////////////////////// + + // parseIntegerLiteral parses an integer-literal, and constructs + // a leaf AST to represent it. + + IntegerLiteral parseIntegerLiteral() throws SyntaxError { + IntegerLiteral IL = null; + + if (currentToken.kind == Token.INTLITERAL) { + previousTokenPosition = currentToken.position; + String spelling = currentToken.spelling; + IL = new IntegerLiteral(spelling, previousTokenPosition); + currentToken = lexicalAnalyser.scan(); + } else { + IL = null; + syntacticError("integer literal expected here", ""); + } + return IL; + } + + // parseCharacterLiteral parses a character-literal, and constructs a leaf + // AST to represent it. + + CharacterLiteral parseCharacterLiteral() throws SyntaxError { + CharacterLiteral CL = null; + + if (currentToken.kind == Token.CHARLITERAL) { + previousTokenPosition = currentToken.position; + String spelling = currentToken.spelling; + CL = new CharacterLiteral(spelling, previousTokenPosition); + currentToken = lexicalAnalyser.scan(); + } else { + CL = null; + syntacticError("character literal expected here", ""); + } + return CL; + } + + // parseIdentifier parses an identifier, and constructs a leaf AST to + // represent it. + + Identifier parseIdentifier() throws SyntaxError { + Identifier I = null; + + if (currentToken.kind == Token.IDENTIFIER) { + previousTokenPosition = currentToken.position; + String spelling = currentToken.spelling; + I = new Identifier(spelling, previousTokenPosition); + currentToken = lexicalAnalyser.scan(); + } else { + I = null; + syntacticError("identifier expected here", ""); + } + return I; + } + + // parseOperator parses an operator, and constructs a leaf AST to + // represent it. + + Operator parseOperator() throws SyntaxError { + Operator O = null; + + if (currentToken.kind == Token.OPERATOR) { + previousTokenPosition = currentToken.position; + String spelling = currentToken.spelling; + O = new Operator(spelling, previousTokenPosition); + currentToken = lexicalAnalyser.scan(); + } else { + O = null; + syntacticError("operator expected here", ""); + } + return O; + } + + /////////////////////////////////////////////////////////////////////////////// + // + // COMMANDS + // + /////////////////////////////////////////////////////////////////////////////// + + // parseCommand parses the command, and constructs an AST + // to represent its phrase structure. + + Command parseCommand() throws SyntaxError { + Command commandAST = null; // in case there's a syntactic error + + SourcePosition commandPos = new SourcePosition(); + + start(commandPos); + commandAST = parseSingleCommand(); + while (currentToken.kind == Token.SEMICOLON) { + acceptIt(); + Command c2AST = parseSingleCommand(); + finish(commandPos); + commandAST = new SequentialCommand(commandAST, c2AST, commandPos); + } + return commandAST; + } + + Command parseSingleCommand() throws SyntaxError { + Command commandAST = null; // in case there's a syntactic error + + SourcePosition commandPos = new SourcePosition(); + start(commandPos); + + switch (currentToken.kind) { + + case Token.IDENTIFIER: { + Identifier iAST = parseIdentifier(); + if (currentToken.kind == Token.LPAREN) { + acceptIt(); + ActualParameterSequence apsAST = parseActualParameterSequence(); + accept(Token.RPAREN); + finish(commandPos); + commandAST = new CallCommand(iAST, apsAST, commandPos); + + } else { + + Vname vAST = parseRestOfVname(iAST); + accept(Token.BECOMES); + Expression eAST = parseExpression(); + finish(commandPos); + commandAST = new AssignCommand(vAST, eAST, commandPos); + } + } + break; + + case Token.BEGIN: + acceptIt(); + commandAST = parseCommand(); + accept(Token.END); + break; + + case Token.LET: { + acceptIt(); + Declaration dAST = parseDeclaration(); + accept(Token.IN); + Command cAST = parseSingleCommand(); + finish(commandPos); + commandAST = new LetCommand(dAST, cAST, commandPos); + } + break; + + case Token.IF: { + acceptIt(); + Expression eAST = parseExpression(); + accept(Token.THEN); + Command c1AST = parseSingleCommand(); + accept(Token.ELSE); + Command c2AST = parseSingleCommand(); + finish(commandPos); + commandAST = new IfCommand(eAST, c1AST, c2AST, commandPos); + } + break; + + case Token.WHILE: { + acceptIt(); + Expression eAST = parseExpression(); + accept(Token.DO); + Command cAST = parseSingleCommand(); + finish(commandPos); + commandAST = new WhileCommand(eAST, cAST, commandPos); + } + break; + + case Token.SEMICOLON: + case Token.END: + case Token.ELSE: + case Token.IN: + case Token.EOT: + + finish(commandPos); + commandAST = new EmptyCommand(commandPos); + break; + + default: + syntacticError("\"%\" cannot start a command", + currentToken.spelling); + break; + + } + + return commandAST; + } + + /////////////////////////////////////////////////////////////////////////////// + // + // EXPRESSIONS + // + /////////////////////////////////////////////////////////////////////////////// + + Expression parseExpression() throws SyntaxError { + Expression expressionAST = null; // in case there's a syntactic error + + SourcePosition expressionPos = new SourcePosition(); + + start(expressionPos); + + switch (currentToken.kind) { + + case Token.LET: { + acceptIt(); + Declaration dAST = parseDeclaration(); + accept(Token.IN); + Expression eAST = parseExpression(); + finish(expressionPos); + expressionAST = new LetExpression(dAST, eAST, expressionPos); + } + break; + + case Token.IF: { + acceptIt(); + Expression e1AST = parseExpression(); + accept(Token.THEN); + Expression e2AST = parseExpression(); + accept(Token.ELSE); + Expression e3AST = parseExpression(); + finish(expressionPos); + expressionAST = new IfExpression(e1AST, e2AST, e3AST, expressionPos); + } + break; + + default: + expressionAST = parseSecondaryExpression(); + break; + } + return expressionAST; + } + + Expression parseSecondaryExpression() throws SyntaxError { + Expression expressionAST = null; // in case there's a syntactic error + + SourcePosition expressionPos = new SourcePosition(); + start(expressionPos); + + expressionAST = parsePrimaryExpression(); + while (currentToken.kind == Token.OPERATOR) { + Operator opAST = parseOperator(); + Expression e2AST = parsePrimaryExpression(); + expressionAST = new BinaryExpression(expressionAST, opAST, e2AST, + expressionPos); + } + return expressionAST; + } + + Expression parsePrimaryExpression() throws SyntaxError { + Expression expressionAST = null; // in case there's a syntactic error + + SourcePosition expressionPos = new SourcePosition(); + start(expressionPos); + + switch (currentToken.kind) { + + case Token.INTLITERAL: { + IntegerLiteral ilAST = parseIntegerLiteral(); + finish(expressionPos); + expressionAST = new IntegerExpression(ilAST, expressionPos); + } + break; + + case Token.CHARLITERAL: { + CharacterLiteral clAST = parseCharacterLiteral(); + finish(expressionPos); + expressionAST = new CharacterExpression(clAST, expressionPos); + } + break; + + case Token.LBRACKET: { + acceptIt(); + ArrayAggregate aaAST = parseArrayAggregate(); + accept(Token.RBRACKET); + finish(expressionPos); + expressionAST = new ArrayExpression(aaAST, expressionPos); + } + break; + + case Token.LCURLY: { + acceptIt(); + RecordAggregate raAST = parseRecordAggregate(); + accept(Token.RCURLY); + finish(expressionPos); + expressionAST = new RecordExpression(raAST, expressionPos); + } + break; + + case Token.IDENTIFIER: { + Identifier iAST = parseIdentifier(); + if (currentToken.kind == Token.LPAREN) { + acceptIt(); + ActualParameterSequence apsAST = parseActualParameterSequence(); + accept(Token.RPAREN); + finish(expressionPos); + expressionAST = new CallExpression(iAST, apsAST, expressionPos); + + } else { + Vname vAST = parseRestOfVname(iAST); + finish(expressionPos); + expressionAST = new VnameExpression(vAST, expressionPos); + } + } + break; + + case Token.OPERATOR: { + Operator opAST = parseOperator(); + Expression eAST = parsePrimaryExpression(); + finish(expressionPos); + expressionAST = new UnaryExpression(opAST, eAST, expressionPos); + } + break; + + case Token.LPAREN: + acceptIt(); + expressionAST = parseExpression(); + accept(Token.RPAREN); + break; + + default: + syntacticError("\"%\" cannot start an expression", + currentToken.spelling); + break; + + } + return expressionAST; + } + + RecordAggregate parseRecordAggregate() throws SyntaxError { + RecordAggregate aggregateAST = null; // in case there's a syntactic error + + SourcePosition aggregatePos = new SourcePosition(); + start(aggregatePos); + + Identifier iAST = parseIdentifier(); + accept(Token.IS); + Expression eAST = parseExpression(); + + if (currentToken.kind == Token.COMMA) { + acceptIt(); + RecordAggregate aAST = parseRecordAggregate(); + finish(aggregatePos); + aggregateAST = new MultipleRecordAggregate(iAST, eAST, aAST, aggregatePos); + } else { + finish(aggregatePos); + aggregateAST = new SingleRecordAggregate(iAST, eAST, aggregatePos); + } + return aggregateAST; + } + + ArrayAggregate parseArrayAggregate() throws SyntaxError { + ArrayAggregate aggregateAST = null; // in case there's a syntactic error + + SourcePosition aggregatePos = new SourcePosition(); + start(aggregatePos); + + Expression eAST = parseExpression(); + if (currentToken.kind == Token.COMMA) { + acceptIt(); + ArrayAggregate aAST = parseArrayAggregate(); + finish(aggregatePos); + aggregateAST = new MultipleArrayAggregate(eAST, aAST, aggregatePos); + } else { + finish(aggregatePos); + aggregateAST = new SingleArrayAggregate(eAST, aggregatePos); + } + return aggregateAST; + } + + /////////////////////////////////////////////////////////////////////////////// + // + // VALUE-OR-VARIABLE NAMES + // + /////////////////////////////////////////////////////////////////////////////// + + Vname parseVname() throws SyntaxError { + Vname vnameAST = null; // in case there's a syntactic error + Identifier iAST = parseIdentifier(); + vnameAST = parseRestOfVname(iAST); + return vnameAST; + } + + Vname parseRestOfVname(Identifier identifierAST) throws SyntaxError { + SourcePosition vnamePos = new SourcePosition(); + vnamePos = identifierAST.position; + Vname vAST = new SimpleVname(identifierAST, vnamePos); + + while (currentToken.kind == Token.DOT || + currentToken.kind == Token.LBRACKET) { + + if (currentToken.kind == Token.DOT) { + acceptIt(); + Identifier iAST = parseIdentifier(); + vAST = new DotVname(vAST, iAST, vnamePos); + } else { + acceptIt(); + Expression eAST = parseExpression(); + accept(Token.RBRACKET); + finish(vnamePos); + vAST = new SubscriptVname(vAST, eAST, vnamePos); + } + } + return vAST; + } + + /////////////////////////////////////////////////////////////////////////////// + // + // DECLARATIONS + // + /////////////////////////////////////////////////////////////////////////////// + + Declaration parseDeclaration() throws SyntaxError { + Declaration declarationAST = null; // in case there's a syntactic error + + SourcePosition declarationPos = new SourcePosition(); + start(declarationPos); + declarationAST = parseSingleDeclaration(); + while (currentToken.kind == Token.SEMICOLON) { + acceptIt(); + Declaration d2AST = parseSingleDeclaration(); + finish(declarationPos); + declarationAST = new SequentialDeclaration(declarationAST, d2AST, + declarationPos); + } + return declarationAST; + } + + Declaration parseSingleDeclaration() throws SyntaxError { + Declaration declarationAST = null; // in case there's a syntactic error + + SourcePosition declarationPos = new SourcePosition(); + start(declarationPos); + + switch (currentToken.kind) { + + case Token.CONST: { + acceptIt(); + Identifier iAST = parseIdentifier(); + accept(Token.IS); + Expression eAST = parseExpression(); + finish(declarationPos); + declarationAST = new ConstDeclaration(iAST, eAST, declarationPos); + } + break; + + case Token.VAR: { + acceptIt(); + Identifier iAST = parseIdentifier(); + accept(Token.COLON); + TypeDenoter tAST = parseTypeDenoter(); + finish(declarationPos); + declarationAST = new VarDeclaration(iAST, tAST, declarationPos); + } + break; + + case Token.PROC: { + acceptIt(); + Identifier iAST = parseIdentifier(); + accept(Token.LPAREN); + FormalParameterSequence fpsAST = parseFormalParameterSequence(); + accept(Token.RPAREN); + accept(Token.IS); + Command cAST = parseSingleCommand(); + finish(declarationPos); + declarationAST = new ProcDeclaration(iAST, fpsAST, cAST, declarationPos); + } + break; + + case Token.FUNC: { + acceptIt(); + Identifier iAST = parseIdentifier(); + accept(Token.LPAREN); + FormalParameterSequence fpsAST = parseFormalParameterSequence(); + accept(Token.RPAREN); + accept(Token.COLON); + TypeDenoter tAST = parseTypeDenoter(); + accept(Token.IS); + Expression eAST = parseExpression(); + finish(declarationPos); + declarationAST = new FuncDeclaration(iAST, fpsAST, tAST, eAST, + declarationPos); + } + break; + + case Token.TYPE: { + acceptIt(); + Identifier iAST = parseIdentifier(); + accept(Token.IS); + TypeDenoter tAST = parseTypeDenoter(); + finish(declarationPos); + declarationAST = new TypeDeclaration(iAST, tAST, declarationPos); + } + break; + + default: + syntacticError("\"%\" cannot start a declaration", + currentToken.spelling); + break; + + } + return declarationAST; + } + + /////////////////////////////////////////////////////////////////////////////// + // + // PARAMETERS + // + /////////////////////////////////////////////////////////////////////////////// + + FormalParameterSequence parseFormalParameterSequence() throws SyntaxError { + FormalParameterSequence formalsAST; + + SourcePosition formalsPos = new SourcePosition(); + + start(formalsPos); + if (currentToken.kind == Token.RPAREN) { + finish(formalsPos); + formalsAST = new EmptyFormalParameterSequence(formalsPos); + + } else { + formalsAST = parseProperFormalParameterSequence(); + } + return formalsAST; + } + + FormalParameterSequence parseProperFormalParameterSequence() throws SyntaxError { + FormalParameterSequence formalsAST = null; // in case there's a syntactic error; + + SourcePosition formalsPos = new SourcePosition(); + start(formalsPos); + FormalParameter fpAST = parseFormalParameter(); + if (currentToken.kind == Token.COMMA) { + acceptIt(); + FormalParameterSequence fpsAST = parseProperFormalParameterSequence(); + finish(formalsPos); + formalsAST = new MultipleFormalParameterSequence(fpAST, fpsAST, + formalsPos); + + } else { + finish(formalsPos); + formalsAST = new SingleFormalParameterSequence(fpAST, formalsPos); + } + return formalsAST; + } + + FormalParameter parseFormalParameter() throws SyntaxError { + FormalParameter formalAST = null; // in case there's a syntactic error; + + SourcePosition formalPos = new SourcePosition(); + start(formalPos); + + switch (currentToken.kind) { + + case Token.IDENTIFIER: { + Identifier iAST = parseIdentifier(); + accept(Token.COLON); + TypeDenoter tAST = parseTypeDenoter(); + finish(formalPos); + formalAST = new ConstFormalParameter(iAST, tAST, formalPos); + } + break; + + case Token.VAR: { + acceptIt(); + Identifier iAST = parseIdentifier(); + accept(Token.COLON); + TypeDenoter tAST = parseTypeDenoter(); + finish(formalPos); + formalAST = new VarFormalParameter(iAST, tAST, formalPos); + } + break; + + case Token.PROC: { + acceptIt(); + Identifier iAST = parseIdentifier(); + accept(Token.LPAREN); + FormalParameterSequence fpsAST = parseFormalParameterSequence(); + accept(Token.RPAREN); + finish(formalPos); + formalAST = new ProcFormalParameter(iAST, fpsAST, formalPos); + } + break; + + case Token.FUNC: { + acceptIt(); + Identifier iAST = parseIdentifier(); + accept(Token.LPAREN); + FormalParameterSequence fpsAST = parseFormalParameterSequence(); + accept(Token.RPAREN); + accept(Token.COLON); + TypeDenoter tAST = parseTypeDenoter(); + finish(formalPos); + formalAST = new FuncFormalParameter(iAST, fpsAST, tAST, formalPos); + } + break; + + default: + syntacticError("\"%\" cannot start a formal parameter", + currentToken.spelling); + break; + + } + return formalAST; + } + + ActualParameterSequence parseActualParameterSequence() throws SyntaxError { + ActualParameterSequence actualsAST; + + SourcePosition actualsPos = new SourcePosition(); + + start(actualsPos); + if (currentToken.kind == Token.RPAREN) { + finish(actualsPos); + actualsAST = new EmptyActualParameterSequence(actualsPos); + + } else { + actualsAST = parseProperActualParameterSequence(); + } + return actualsAST; + } + + ActualParameterSequence parseProperActualParameterSequence() throws SyntaxError { + ActualParameterSequence actualsAST = null; // in case there's a syntactic error + + SourcePosition actualsPos = new SourcePosition(); + + start(actualsPos); + ActualParameter apAST = parseActualParameter(); + if (currentToken.kind == Token.COMMA) { + acceptIt(); + ActualParameterSequence apsAST = parseProperActualParameterSequence(); + finish(actualsPos); + actualsAST = new MultipleActualParameterSequence(apAST, apsAST, + actualsPos); + } else { + finish(actualsPos); + actualsAST = new SingleActualParameterSequence(apAST, actualsPos); + } + return actualsAST; + } + + ActualParameter parseActualParameter() throws SyntaxError { + ActualParameter actualAST = null; // in case there's a syntactic error + + SourcePosition actualPos = new SourcePosition(); + + start(actualPos); + + switch (currentToken.kind) { + + case Token.IDENTIFIER: + case Token.INTLITERAL: + case Token.CHARLITERAL: + case Token.OPERATOR: + case Token.LET: + case Token.IF: + case Token.LPAREN: + case Token.LBRACKET: + case Token.LCURLY: { + Expression eAST = parseExpression(); + finish(actualPos); + actualAST = new ConstActualParameter(eAST, actualPos); + } + break; + + case Token.VAR: { + acceptIt(); + Vname vAST = parseVname(); + finish(actualPos); + actualAST = new VarActualParameter(vAST, actualPos); + } + break; + + case Token.PROC: { + acceptIt(); + Identifier iAST = parseIdentifier(); + finish(actualPos); + actualAST = new ProcActualParameter(iAST, actualPos); + } + break; + + case Token.FUNC: { + acceptIt(); + Identifier iAST = parseIdentifier(); + finish(actualPos); + actualAST = new FuncActualParameter(iAST, actualPos); + } + break; + + default: + syntacticError("\"%\" cannot start an actual parameter", + currentToken.spelling); + break; + + } + return actualAST; + } + + /////////////////////////////////////////////////////////////////////////////// + // + // TYPE-DENOTERS + // + /////////////////////////////////////////////////////////////////////////////// + + TypeDenoter parseTypeDenoter() throws SyntaxError { + TypeDenoter typeAST = null; // in case there's a syntactic error + SourcePosition typePos = new SourcePosition(); + + start(typePos); + + switch (currentToken.kind) { + + case Token.IDENTIFIER: { + Identifier iAST = parseIdentifier(); + finish(typePos); + typeAST = new SimpleTypeDenoter(iAST, typePos); + } + break; + + case Token.ARRAY: { + acceptIt(); + IntegerLiteral ilAST = parseIntegerLiteral(); + accept(Token.OF); + TypeDenoter tAST = parseTypeDenoter(); + finish(typePos); + typeAST = new ArrayTypeDenoter(ilAST, tAST, typePos); + } + break; + + case Token.RECORD: { + acceptIt(); + FieldTypeDenoter fAST = parseFieldTypeDenoter(); + accept(Token.END); + finish(typePos); + typeAST = new RecordTypeDenoter(fAST, typePos); + } + break; + + default: + syntacticError("\"%\" cannot start a type denoter", + currentToken.spelling); + break; + + } + return typeAST; + } + + FieldTypeDenoter parseFieldTypeDenoter() throws SyntaxError { + FieldTypeDenoter fieldAST = null; // in case there's a syntactic error + + SourcePosition fieldPos = new SourcePosition(); + + start(fieldPos); + Identifier iAST = parseIdentifier(); + accept(Token.COLON); + TypeDenoter tAST = parseTypeDenoter(); + if (currentToken.kind == Token.COMMA) { + acceptIt(); + FieldTypeDenoter fAST = parseFieldTypeDenoter(); + finish(fieldPos); + fieldAST = new MultipleFieldTypeDenoter(iAST, tAST, fAST, fieldPos); + } else { + finish(fieldPos); + fieldAST = new SingleFieldTypeDenoter(iAST, tAST, fieldPos); + } + return fieldAST; + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Scanner.java b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Scanner.java new file mode 100644 index 0000000..8d347a9 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Scanner.java @@ -0,0 +1,273 @@ +/* + * @(#)Scanner.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.SyntacticAnalyzer; + +public final class Scanner { + + private SourceFile sourceFile; + private boolean debug; + + private char currentChar; + private StringBuffer currentSpelling; + private boolean currentlyScanningToken; + + private boolean isLetter(char c) { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); + } + + private boolean isDigit(char c) { + return (c >= '0' && c <= '9'); + } + + // isOperator returns true iff the given character is an operator character. + + private boolean isOperator(char c) { + return (c == '+' || c == '-' || c == '*' || c == '/' || + c == '=' || c == '<' || c == '>' || c == '\\' || + c == '&' || c == '@' || c == '%' || c == '^' || + c == '?'); + } + + /////////////////////////////////////////////////////////////////////////////// + + public Scanner(SourceFile source) { + sourceFile = source; + currentChar = sourceFile.getSource(); + debug = false; + } + + public void enableDebugging() { + debug = true; + } + + // takeIt appends the current character to the current token, and gets + // the next character from the source program. + + private void takeIt() { + if (currentlyScanningToken) + currentSpelling.append(currentChar); + currentChar = sourceFile.getSource(); + } + + // scanSeparator skips a single separator. + + private void scanSeparator() { + switch (currentChar) { + case '!': { + takeIt(); + while ((currentChar != SourceFile.EOL) && (currentChar != SourceFile.EOT)) + takeIt(); + if (currentChar == SourceFile.EOL) + takeIt(); + } + break; + + case ' ': + case '\n': + case '\r': + case '\t': + takeIt(); + break; + } + } + + private int scanToken() { + + switch (currentChar) { + + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + takeIt(); + while (isLetter(currentChar) || isDigit(currentChar)) + takeIt(); + return Token.IDENTIFIER; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + takeIt(); + while (isDigit(currentChar)) + takeIt(); + return Token.INTLITERAL; + + case '+': + case '-': + case '*': + case '/': + case '=': + case '<': + case '>': + case '\\': + case '&': + case '@': + case '%': + case '^': + case '?': + takeIt(); + while (isOperator(currentChar)) + takeIt(); + return Token.OPERATOR; + + case '\'': + takeIt(); + takeIt(); // the quoted character + if (currentChar == '\'') { + takeIt(); + return Token.CHARLITERAL; + } else + return Token.ERROR; + + case '.': + takeIt(); + return Token.DOT; + + case ':': + takeIt(); + if (currentChar == '=') { + takeIt(); + return Token.BECOMES; + } else + return Token.COLON; + + case ';': + takeIt(); + return Token.SEMICOLON; + + case ',': + takeIt(); + return Token.COMMA; + + case '~': + takeIt(); + return Token.IS; + + case '(': + takeIt(); + return Token.LPAREN; + + case ')': + takeIt(); + return Token.RPAREN; + + case '[': + takeIt(); + return Token.LBRACKET; + + case ']': + takeIt(); + return Token.RBRACKET; + + case '{': + takeIt(); + return Token.LCURLY; + + case '}': + takeIt(); + return Token.RCURLY; + + case SourceFile.EOT: + return Token.EOT; + + default: + takeIt(); + return Token.ERROR; + } + } + + public Token scan() { + Token tok; + SourcePosition pos; + int kind; + + currentlyScanningToken = false; + while (currentChar == '!' + || currentChar == ' ' + || currentChar == '\n' + || currentChar == '\r' + || currentChar == '\t') + scanSeparator(); + + currentlyScanningToken = true; + currentSpelling = new StringBuffer(""); + pos = new SourcePosition(); + pos.start = sourceFile.getCurrentLine(); + + kind = scanToken(); + + pos.finish = sourceFile.getCurrentLine(); + tok = new Token(kind, currentSpelling.toString(), pos); + if (debug) + System.out.println(tok); + return tok; + } + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourceFile.java b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourceFile.java new file mode 100644 index 0000000..3ec7aa2 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourceFile.java @@ -0,0 +1,56 @@ +/* + * @(#)SourceFile.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.SyntacticAnalyzer; + +public class SourceFile { + + public static final char EOL = '\n'; + public static final char EOT = '\u0000'; + + java.io.File sourceFile; + java.io.FileInputStream source; + int currentLine; + + public SourceFile(String filename) { + try { + sourceFile = new java.io.File(filename); + source = new java.io.FileInputStream(sourceFile); + currentLine = 1; + } catch (java.io.IOException s) { + sourceFile = null; + source = null; + currentLine = 0; + } + } + + char getSource() { + try { + int c = source.read(); + + if (c == -1) { + c = EOT; + } else if (c == EOL) { + currentLine++; + } + return (char) c; + } catch (java.io.IOException s) { + return EOT; + } + } + + int getCurrentLine() { + return currentLine; + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourcePosition.java b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourcePosition.java new file mode 100644 index 0000000..3a70fda --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SourcePosition.java @@ -0,0 +1,34 @@ +/* + * @(#)SourcePosition.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.SyntacticAnalyzer; + +public class SourcePosition { + + public int start, finish; + + public SourcePosition() { + start = 0; + finish = 0; + } + + public SourcePosition(int s, int f) { + start = s; + finish = f; + } + + public String toString() { + return "(" + start + ", " + finish + ")"; + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SyntaxError.java b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SyntaxError.java new file mode 100644 index 0000000..214d5b3 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/SyntaxError.java @@ -0,0 +1,27 @@ +/* + * @(#)SyntaxError.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.SyntacticAnalyzer; + +class SyntaxError extends Exception { + + SyntaxError() { + super(); + }; + + SyntaxError(String s) { + super(s); + } + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Token.java b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Token.java new file mode 100644 index 0000000..6f4d4a3 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/SyntacticAnalyzer/Token.java @@ -0,0 +1,148 @@ +/* + * @(#)Token.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.SyntacticAnalyzer; + +final class Token extends Object { + + protected int kind; + protected String spelling; + protected SourcePosition position; + + public Token(int kind, String spelling, SourcePosition position) { + + if (kind == Token.IDENTIFIER) { + int currentKind = firstReservedWord; + boolean searching = true; + + while (searching) { + int comparison = tokenTable[currentKind].compareTo(spelling); + if (comparison == 0) { + this.kind = currentKind; + searching = false; + } else if (comparison > 0 || currentKind == lastReservedWord) { + this.kind = Token.IDENTIFIER; + searching = false; + } else { + currentKind++; + } + } + } else + this.kind = kind; + + this.spelling = spelling; + this.position = position; + + } + + public static String spell(int kind) { + return tokenTable[kind]; + } + + public String toString() { + return "Kind=" + kind + ", spelling=" + spelling + + ", position=" + position; + } + + // Token classes... + + public static final int + + // literals, identifiers, operators... + INTLITERAL = 0, + CHARLITERAL = 1, + IDENTIFIER = 2, + OPERATOR = 3, + + // reserved words - must be in alphabetical order... + ARRAY = 4, + BEGIN = 5, + CONST = 6, + DO = 7, + ELSE = 8, + END = 9, + FUNC = 10, + IF = 11, + IN = 12, + LET = 13, + OF = 14, + PROC = 15, + RECORD = 16, + THEN = 17, + TYPE = 18, + VAR = 19, + WHILE = 20, + + // punctuation... + DOT = 21, + COLON = 22, + SEMICOLON = 23, + COMMA = 24, + BECOMES = 25, + IS = 26, + + // brackets... + LPAREN = 27, + RPAREN = 28, + LBRACKET = 29, + RBRACKET = 30, + LCURLY = 31, + RCURLY = 32, + + // special tokens... + EOT = 33, + ERROR = 34; + + private static String[] tokenTable = new String[] { + "", + "", + "", + "", + "array", + "begin", + "const", + "do", + "else", + "end", + "func", + "if", + "in", + "let", + "of", + "proc", + "record", + "then", + "type", + "var", + "while", + ".", + ":", + ";", + ",", + ":=", + "~", + "(", + ")", + "[", + "]", + "{", + "}", + "", + "" + }; + + private final static int firstReservedWord = Token.ARRAY, + lastReservedWord = Token.WHILE; + +} diff --git a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Drawer.java b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Drawer.java new file mode 100644 index 0000000..cb43f59 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Drawer.java @@ -0,0 +1,61 @@ +/* + * @(#)Drawer.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.TreeDrawer; + +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Point; + +import Triangle.AbstractSyntaxTrees.Program; + +public class Drawer { + + private DrawerFrame frame; + private DrawerPanel panel; + + private Program theAST; + private DrawingTree theDrawing; + + // Draw the AST representing a complete program. + + public void draw(Program ast) { + theAST = ast; + panel = new DrawerPanel(this); + frame = new DrawerFrame(panel); + + Font font = new Font("SansSerif", Font.PLAIN, 12); + frame.setFont(font); + + FontMetrics fontMetrics = frame.getFontMetrics(font); + + LayoutVisitor layout = new LayoutVisitor(fontMetrics); + theDrawing = (DrawingTree) theAST.visit(layout, null); + theDrawing.position(new Point(2048, 10)); + + frame.show(); + } + + public void paintAST(Graphics g) { + g.setColor(panel.getBackground()); + Dimension d = panel.getSize(); + g.fillRect(0, 0, d.width, d.height); + + if (theDrawing != null) { + theDrawing.paint(g); + } + } +} diff --git a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerFrame.java b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerFrame.java new file mode 100644 index 0000000..c12778d --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerFrame.java @@ -0,0 +1,49 @@ +/* + * @(#)DrawerFrame.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.TreeDrawer; + +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; + +class DrawerFrame extends JFrame { + public DrawerFrame(JPanel panel) { + setSize(300, 200); + Toolkit tk = Toolkit.getDefaultToolkit(); + Dimension d = tk.getScreenSize(); + int screenHeight = d.height; + int screenWidth = d.width; + setTitle("Triangle Compiler Abstract Syntax Tree"); + setSize(screenWidth / 2, screenHeight / 2); + setLocation(screenWidth / 4, screenHeight / 4); + // Image img = tk.getImage("icon.gif"); + // setIconImage(img); + + addWindowListener( + new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + Container contentPane = getContentPane(); + contentPane.add(new JScrollPane(panel)); + } +} \ No newline at end of file diff --git a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerPanel.java b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerPanel.java new file mode 100644 index 0000000..2ee0d12 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawerPanel.java @@ -0,0 +1,34 @@ +/* + * @(#)DrawerPanel.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.TreeDrawer; + +import java.awt.Dimension; +import java.awt.Graphics; + +import javax.swing.JPanel; + +class DrawerPanel extends JPanel { + private Drawer drawer; + + public DrawerPanel(Drawer drawer) { + setPreferredSize(new Dimension(4096, 4096)); + this.drawer = drawer; + } + + public void paintComponent(Graphics g) { + super.paintComponent(g); + drawer.paintAST(g); + } +} \ No newline at end of file diff --git a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawingTree.java b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawingTree.java new file mode 100644 index 0000000..d6a0991 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/DrawingTree.java @@ -0,0 +1,88 @@ +/* + * @(#)DrawingTree.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.TreeDrawer; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Point; + +public class DrawingTree { + + String caption; + int width, height; + Point pos, offset; + Polygon contour; + DrawingTree parent; + DrawingTree[] children; + + public DrawingTree(String caption, int width, int height) { + this.caption = caption; + this.width = width; + this.height = height; + this.parent = null; + this.children = null; + this.pos = new Point(0, 0); + this.offset = new Point(0, 0); + this.contour = new Polygon(); + } + + public void setChildren(DrawingTree[] children) { + this.children = children; + for (int i = 0; i < children.length; i++) + children[i].parent = this; + } + + private final int FIXED_FONT_HEIGHT = 10; + private final int FIXED_FONT_ASCENT = 3; + private final Color nodeColor = new Color(250, 220, 100); + + public void paint(Graphics graphics) { + graphics.setColor(nodeColor); + graphics.fillRect(pos.x, pos.y, width, height); + graphics.setColor(Color.black); + graphics.drawRect(pos.x, pos.y, width - 1, height - 1); + graphics.drawString(caption, pos.x + 2, + pos.y + (height + FIXED_FONT_HEIGHT) / 2); + + if (children != null) { + for (int i = 0; i < children.length; i++) { + children[i].paint(graphics); + } + } + + if (parent != null) { + graphics.drawLine(pos.x + width / 2, pos.y, + parent.pos.x + parent.width / 2, + parent.pos.y + parent.height); + } + } + + public void position(Point pos) { + + this.pos.x = pos.x + this.offset.x; + this.pos.y = pos.y + this.offset.y; + + Point temp = new Point(this.pos.x, this.pos.y); + + if (children != null) { + for (int i = 0; i < children.length; i++) { + children[i].position(temp); + temp.x += children[i].offset.x; + temp.y = this.pos.y + children[0].offset.y; + } + } + } + +} \ No newline at end of file diff --git a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/LayoutVisitor.java b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/LayoutVisitor.java new file mode 100644 index 0000000..bf192ba --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/LayoutVisitor.java @@ -0,0 +1,533 @@ +/* + * @(#)LayoutVisitor.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.TreeDrawer; + +import java.awt.FontMetrics; + +import Triangle.AbstractSyntaxTrees.AST; +import Triangle.AbstractSyntaxTrees.AnyTypeDenoter; +import Triangle.AbstractSyntaxTrees.ArrayExpression; +import Triangle.AbstractSyntaxTrees.ArrayTypeDenoter; +import Triangle.AbstractSyntaxTrees.AssignCommand; +import Triangle.AbstractSyntaxTrees.BinaryExpression; +import Triangle.AbstractSyntaxTrees.BinaryOperatorDeclaration; +import Triangle.AbstractSyntaxTrees.BoolTypeDenoter; +import Triangle.AbstractSyntaxTrees.CallCommand; +import Triangle.AbstractSyntaxTrees.CallExpression; +import Triangle.AbstractSyntaxTrees.CharTypeDenoter; +import Triangle.AbstractSyntaxTrees.CharacterExpression; +import Triangle.AbstractSyntaxTrees.CharacterLiteral; +import Triangle.AbstractSyntaxTrees.ConstActualParameter; +import Triangle.AbstractSyntaxTrees.ConstDeclaration; +import Triangle.AbstractSyntaxTrees.ConstFormalParameter; +import Triangle.AbstractSyntaxTrees.DotVname; +import Triangle.AbstractSyntaxTrees.EmptyActualParameterSequence; +import Triangle.AbstractSyntaxTrees.EmptyCommand; +import Triangle.AbstractSyntaxTrees.EmptyExpression; +import Triangle.AbstractSyntaxTrees.EmptyFormalParameterSequence; +import Triangle.AbstractSyntaxTrees.ErrorTypeDenoter; +import Triangle.AbstractSyntaxTrees.FuncActualParameter; +import Triangle.AbstractSyntaxTrees.FuncDeclaration; +import Triangle.AbstractSyntaxTrees.FuncFormalParameter; +import Triangle.AbstractSyntaxTrees.Identifier; +import Triangle.AbstractSyntaxTrees.IfCommand; +import Triangle.AbstractSyntaxTrees.IfExpression; +import Triangle.AbstractSyntaxTrees.IntTypeDenoter; +import Triangle.AbstractSyntaxTrees.IntegerExpression; +import Triangle.AbstractSyntaxTrees.IntegerLiteral; +import Triangle.AbstractSyntaxTrees.LetCommand; +import Triangle.AbstractSyntaxTrees.LetExpression; +import Triangle.AbstractSyntaxTrees.MultipleActualParameterSequence; +import Triangle.AbstractSyntaxTrees.MultipleArrayAggregate; +import Triangle.AbstractSyntaxTrees.MultipleFieldTypeDenoter; +import Triangle.AbstractSyntaxTrees.MultipleFormalParameterSequence; +import Triangle.AbstractSyntaxTrees.MultipleRecordAggregate; +import Triangle.AbstractSyntaxTrees.Operator; +import Triangle.AbstractSyntaxTrees.ProcActualParameter; +import Triangle.AbstractSyntaxTrees.ProcDeclaration; +import Triangle.AbstractSyntaxTrees.ProcFormalParameter; +import Triangle.AbstractSyntaxTrees.Program; +import Triangle.AbstractSyntaxTrees.RecordExpression; +import Triangle.AbstractSyntaxTrees.RecordTypeDenoter; +import Triangle.AbstractSyntaxTrees.SequentialCommand; +import Triangle.AbstractSyntaxTrees.SequentialDeclaration; +import Triangle.AbstractSyntaxTrees.SimpleTypeDenoter; +import Triangle.AbstractSyntaxTrees.SimpleVname; +import Triangle.AbstractSyntaxTrees.SingleActualParameterSequence; +import Triangle.AbstractSyntaxTrees.SingleArrayAggregate; +import Triangle.AbstractSyntaxTrees.SingleFieldTypeDenoter; +import Triangle.AbstractSyntaxTrees.SingleFormalParameterSequence; +import Triangle.AbstractSyntaxTrees.SingleRecordAggregate; +import Triangle.AbstractSyntaxTrees.SubscriptVname; +import Triangle.AbstractSyntaxTrees.TypeDeclaration; +import Triangle.AbstractSyntaxTrees.UnaryExpression; +import Triangle.AbstractSyntaxTrees.UnaryOperatorDeclaration; +import Triangle.AbstractSyntaxTrees.VarActualParameter; +import Triangle.AbstractSyntaxTrees.VarDeclaration; +import Triangle.AbstractSyntaxTrees.VarFormalParameter; +import Triangle.AbstractSyntaxTrees.Visitor; +import Triangle.AbstractSyntaxTrees.VnameExpression; +import Triangle.AbstractSyntaxTrees.WhileCommand; + +public class LayoutVisitor implements Visitor { + + private final int BORDER = 5; + private final int PARENT_SEP = 30; + + private FontMetrics fontMetrics; + + public LayoutVisitor(FontMetrics fontMetrics) { + this.fontMetrics = fontMetrics; + } + + // Commands + public Object visitAssignCommand(AssignCommand ast, Object obj) { + return layoutBinary("AssignCom.", ast.V, ast.E); + } + + public Object visitCallCommand(CallCommand ast, Object obj) { + return layoutBinary("CallCom.", ast.I, ast.APS); + } + + public Object visitEmptyCommand(EmptyCommand ast, Object obj) { + return layoutNullary("EmptyCom."); + } + + public Object visitIfCommand(IfCommand ast, Object obj) { + return layoutTernary("IfCom.", ast.E, ast.C1, ast.C2); + } + + public Object visitLetCommand(LetCommand ast, Object obj) { + return layoutBinary("LetCom.", ast.D, ast.C); + } + + public Object visitSequentialCommand(SequentialCommand ast, Object obj) { + return layoutBinary("Seq.Com.", ast.C1, ast.C2); + } + + public Object visitWhileCommand(WhileCommand ast, Object obj) { + return layoutBinary("WhileCom.", ast.E, ast.C); + } + + // Expressions + public Object visitArrayExpression(ArrayExpression ast, Object obj) { + return layoutUnary("ArrayExpr.", ast.AA); + } + + public Object visitBinaryExpression(BinaryExpression ast, Object obj) { + return layoutTernary("Bin.Expr.", ast.E1, ast.O, ast.E2); + } + + public Object visitCallExpression(CallExpression ast, Object obj) { + return layoutBinary("CallExpr.", ast.I, ast.APS); + } + + public Object visitCharacterExpression(CharacterExpression ast, Object obj) { + return layoutUnary("Char.Expr.", ast.CL); + } + + public Object visitEmptyExpression(EmptyExpression ast, Object obj) { + return layoutNullary("EmptyExpr."); + } + + public Object visitIfExpression(IfExpression ast, Object obj) { + return layoutTernary("IfExpr.", ast.E1, ast.E2, ast.E3); + } + + public Object visitIntegerExpression(IntegerExpression ast, Object obj) { + return layoutUnary("Int.Expr.", ast.IL); + } + + public Object visitLetExpression(LetExpression ast, Object obj) { + return layoutBinary("LetExpr.", ast.D, ast.E); + } + + public Object visitRecordExpression(RecordExpression ast, Object obj) { + return layoutUnary("Rec.Expr.", ast.RA); + } + + public Object visitUnaryExpression(UnaryExpression ast, Object obj) { + return layoutBinary("UnaryExpr.", ast.O, ast.E); + } + + public Object visitVnameExpression(VnameExpression ast, Object obj) { + return layoutUnary("VnameExpr.", ast.V); + } + + // Declarations + public Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Object obj) { + return layoutQuaternary("Bin.Op.Decl.", ast.O, ast.ARG1, ast.ARG2, ast.RES); + } + + public Object visitConstDeclaration(ConstDeclaration ast, Object obj) { + return layoutBinary("ConstDecl.", ast.I, ast.E); + } + + public Object visitFuncDeclaration(FuncDeclaration ast, Object obj) { + return layoutQuaternary("FuncDecl.", ast.I, ast.FPS, ast.T, ast.E); + } + + public Object visitProcDeclaration(ProcDeclaration ast, Object obj) { + return layoutTernary("ProcDecl.", ast.I, ast.FPS, ast.C); + } + + public Object visitSequentialDeclaration(SequentialDeclaration ast, Object obj) { + return layoutBinary("Seq.Decl.", ast.D1, ast.D2); + } + + public Object visitTypeDeclaration(TypeDeclaration ast, Object obj) { + return layoutBinary("TypeDecl.", ast.I, ast.T); + } + + public Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Object obj) { + return layoutTernary("UnaryOp.Decl.", ast.O, ast.ARG, ast.RES); + } + + public Object visitVarDeclaration(VarDeclaration ast, Object obj) { + return layoutBinary("VarDecl.", ast.I, ast.T); + } + + // Array Aggregates + public Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, Object obj) { + return layoutBinary("Mult.ArrayAgg.", ast.E, ast.AA); + } + + public Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object obj) { + return layoutUnary("Sing.ArrayAgg.", ast.E); + } + + // Record Aggregates + public Object visitMultipleRecordAggregate(MultipleRecordAggregate ast, Object obj) { + return layoutTernary("Mult.Rec.Agg.", ast.I, ast.E, ast.RA); + } + + public Object visitSingleRecordAggregate(SingleRecordAggregate ast, Object obj) { + return layoutBinary("Sing.Rec.Agg.", ast.I, ast.E); + } + + // Formal Parameters + public Object visitConstFormalParameter(ConstFormalParameter ast, Object obj) { + return layoutBinary("ConstF.P.", ast.I, ast.T); + } + + public Object visitFuncFormalParameter(FuncFormalParameter ast, Object obj) { + return layoutTernary("FuncF.P.", ast.I, ast.FPS, ast.T); + } + + public Object visitProcFormalParameter(ProcFormalParameter ast, Object obj) { + return layoutBinary("ProcF.P.", ast.I, ast.FPS); + } + + public Object visitVarFormalParameter(VarFormalParameter ast, Object obj) { + return layoutBinary("VarF.P.", ast.I, ast.T); + } + + public Object visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Object obj) { + return layoutNullary("EmptyF.P.S."); + } + + public Object visitMultipleFormalParameterSequence(MultipleFormalParameterSequence ast, Object obj) { + return layoutBinary("Mult.F.P.S.", ast.FP, ast.FPS); + } + + public Object visitSingleFormalParameterSequence(SingleFormalParameterSequence ast, Object obj) { + return layoutUnary("Sing.F.P.S.", ast.FP); + } + + // Actual Parameters + public Object visitConstActualParameter(ConstActualParameter ast, Object obj) { + return layoutUnary("ConstA.P.", ast.E); + } + + public Object visitFuncActualParameter(FuncActualParameter ast, Object obj) { + return layoutUnary("FuncA.P.", ast.I); + } + + public Object visitProcActualParameter(ProcActualParameter ast, Object obj) { + return layoutUnary("ProcA.P.", ast.I); + } + + public Object visitVarActualParameter(VarActualParameter ast, Object obj) { + return layoutUnary("VarA.P.", ast.V); + } + + public Object visitEmptyActualParameterSequence(EmptyActualParameterSequence ast, Object obj) { + return layoutNullary("EmptyA.P.S."); + } + + public Object visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, Object obj) { + return layoutBinary("Mult.A.P.S.", ast.AP, ast.APS); + } + + public Object visitSingleActualParameterSequence(SingleActualParameterSequence ast, Object obj) { + return layoutUnary("Sing.A.P.S.", ast.AP); + } + + // Type Denoters + public Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object obj) { + return layoutNullary("any"); + } + + public Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object obj) { + return layoutBinary("ArrayTypeD.", ast.IL, ast.T); + } + + public Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object obj) { + return layoutNullary("bool"); + } + + public Object visitCharTypeDenoter(CharTypeDenoter ast, Object obj) { + return layoutNullary("char"); + } + + public Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object obj) { + return layoutNullary("error"); + } + + public Object visitSimpleTypeDenoter(SimpleTypeDenoter ast, Object obj) { + return layoutUnary("Sim.TypeD.", ast.I); + } + + public Object visitIntTypeDenoter(IntTypeDenoter ast, Object obj) { + return layoutNullary("int"); + } + + public Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object obj) { + return layoutUnary("Rec.TypeD.", ast.FT); + } + + public Object visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, Object obj) { + return layoutTernary("Mult.F.TypeD.", ast.I, ast.T, ast.FT); + } + + public Object visitSingleFieldTypeDenoter(SingleFieldTypeDenoter ast, Object obj) { + return layoutBinary("Sing.F.TypeD.", ast.I, ast.T); + } + + // Literals, Identifiers and Operators + public Object visitCharacterLiteral(CharacterLiteral ast, Object obj) { + return layoutNullary(ast.spelling); + } + + public Object visitIdentifier(Identifier ast, Object obj) { + return layoutNullary(ast.spelling); + } + + public Object visitIntegerLiteral(IntegerLiteral ast, Object obj) { + return layoutNullary(ast.spelling); + } + + public Object visitOperator(Operator ast, Object obj) { + return layoutNullary(ast.spelling); + } + + // Value-or-variable names + public Object visitDotVname(DotVname ast, Object obj) { + return layoutBinary("DotVname", ast.I, ast.V); + } + + public Object visitSimpleVname(SimpleVname ast, Object obj) { + return layoutUnary("Sim.Vname", ast.I); + } + + public Object visitSubscriptVname(SubscriptVname ast, Object obj) { + return layoutBinary("Sub.Vname", + ast.V, ast.E); + } + + // Programs + public Object visitProgram(Program ast, Object obj) { + return layoutUnary("Program", ast.C); + } + + private DrawingTree layoutCaption(String name) { + int w = fontMetrics.stringWidth(name) + 4; + int h = fontMetrics.getHeight() + 4; + return new DrawingTree(name, w, h); + } + + private DrawingTree layoutNullary(String name) { + DrawingTree dt = layoutCaption(name); + dt.contour.upper_tail = new Polyline(0, dt.height + 2 * BORDER, null); + dt.contour.upper_head = dt.contour.upper_tail; + dt.contour.lower_tail = new Polyline(-dt.width - 2 * BORDER, 0, null); + dt.contour.lower_head = new Polyline(0, dt.height + 2 * BORDER, dt.contour.lower_tail); + return dt; + } + + private DrawingTree layoutUnary(String name, AST child1) { + DrawingTree dt = layoutCaption(name); + DrawingTree d1 = (DrawingTree) child1.visit(this, null); + dt.setChildren(new DrawingTree[] { d1 }); + attachParent(dt, join(dt)); + return dt; + } + + private DrawingTree layoutBinary(String name, AST child1, AST child2) { + DrawingTree dt = layoutCaption(name); + DrawingTree d1 = (DrawingTree) child1.visit(this, null); + DrawingTree d2 = (DrawingTree) child2.visit(this, null); + dt.setChildren(new DrawingTree[] { d1, d2 }); + attachParent(dt, join(dt)); + return dt; + } + + private DrawingTree layoutTernary(String name, AST child1, AST child2, + AST child3) { + DrawingTree dt = layoutCaption(name); + DrawingTree d1 = (DrawingTree) child1.visit(this, null); + DrawingTree d2 = (DrawingTree) child2.visit(this, null); + DrawingTree d3 = (DrawingTree) child3.visit(this, null); + dt.setChildren(new DrawingTree[] { d1, d2, d3 }); + attachParent(dt, join(dt)); + return dt; + } + + private DrawingTree layoutQuaternary(String name, AST child1, AST child2, + AST child3, AST child4) { + DrawingTree dt = layoutCaption(name); + DrawingTree d1 = (DrawingTree) child1.visit(this, null); + DrawingTree d2 = (DrawingTree) child2.visit(this, null); + DrawingTree d3 = (DrawingTree) child3.visit(this, null); + DrawingTree d4 = (DrawingTree) child4.visit(this, null); + dt.setChildren(new DrawingTree[] { d1, d2, d3, d4 }); + attachParent(dt, join(dt)); + return dt; + } + + private void attachParent(DrawingTree dt, int w) { + int y = PARENT_SEP; + int x2 = (w - dt.width) / 2 - BORDER; + int x1 = x2 + dt.width + 2 * BORDER - w; + + dt.children[0].offset.y = y + dt.height; + dt.children[0].offset.x = x1; + dt.contour.upper_head = new Polyline(0, dt.height, + new Polyline(x1, y, dt.contour.upper_head)); + dt.contour.lower_head = new Polyline(0, dt.height, + new Polyline(x2, y, dt.contour.lower_head)); + } + + private int join(DrawingTree dt) { + int w, sum; + + dt.contour = dt.children[0].contour; + sum = w = dt.children[0].width + 2 * BORDER; + + for (int i = 1; i < dt.children.length; i++) { + int d = merge(dt.contour, dt.children[i].contour); + dt.children[i].offset.x = d + w; + dt.children[i].offset.y = 0; + w = dt.children[i].width + 2 * BORDER; + sum += d + w; + } + return sum; + } + + private int merge(Polygon c1, Polygon c2) { + int x, y, total, d; + Polyline lower, upper, b; + + x = y = total = 0; + upper = c1.lower_head; + lower = c2.upper_head; + + while (lower != null && upper != null) { + d = offset(x, y, lower.dx, lower.dy, upper.dx, upper.dy); + x += d; + total += d; + + if (y + lower.dy <= upper.dy) { + x += lower.dx; + y += lower.dy; + lower = lower.link; + } else { + x -= upper.dx; + y -= upper.dy; + upper = upper.link; + } + } + + if (lower != null) { + b = bridge(c1.upper_tail, 0, 0, lower, x, y); + c1.upper_tail = (b.link != null) ? c2.upper_tail : b; + c1.lower_tail = c2.lower_tail; + } else { + b = bridge(c2.lower_tail, x, y, upper, 0, 0); + if (b.link == null) { + c1.lower_tail = b; + } + } + + c1.lower_head = c2.lower_head; + + return total; + } + + private int offset(int p1, int p2, int a1, int a2, int b1, int b2) { + int d, s, t; + + if (b2 <= p2 || p2 + a2 <= 0) { + return 0; + } + + t = b2 * a1 - a2 * b1; + if (t > 0) { + if (p2 < 0) { + s = p2 * a1; + d = s / a2 - p1; + } else if (p2 > 0) { + s = p2 * b1; + d = s / b2 - p1; + } else { + d = -p1; + } + } else if (b2 < p2 + a2) { + s = (b2 - p2) * a1; + d = b1 - (p1 + s / a2); + } else if (b2 > p2 + a2) { + s = (a2 + p2) * b1; + d = s / b2 - (p1 + a1); + } else { + d = b1 - (p1 + a1); + } + + if (d > 0) { + return d; + } else { + return 0; + } + } + + private Polyline bridge(Polyline line1, int x1, int y1, + Polyline line2, int x2, int y2) { + int dy, dx, s; + Polyline r; + + dy = y2 + line2.dy - y1; + if (line2.dy == 0) { + dx = line2.dx; + } else { + s = dy * line2.dx; + dx = s / line2.dy; + } + + r = new Polyline(dx, dy, line2.link); + line1.link = new Polyline(x2 + line2.dx - dx - x1, 0, r); + + return r; + } + +} \ No newline at end of file diff --git a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Polygon.java b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Polygon.java new file mode 100644 index 0000000..37f93f4 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Polygon.java @@ -0,0 +1,20 @@ +/* + * @(#)Polygon.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.TreeDrawer; + +class Polygon { + Polyline lower_head, lower_tail; + Polyline upper_head, upper_tail; +} \ No newline at end of file diff --git a/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Polyline.java b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Polyline.java new file mode 100644 index 0000000..0d3fa90 --- /dev/null +++ b/Triangle.Compiler/src/main/java/Triangle/TreeDrawer/Polyline.java @@ -0,0 +1,26 @@ +/* + * @(#)Polyline.java 2.1 2003/10/07 + * + * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown + * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland + * and School of Computer and Math Sciences, The Robert Gordon University, + * St. Andrew Street, Aberdeen AB25 1HG, Scotland. + * All rights reserved. + * + * This software is provided free for educational use only. It may + * not be used for commercial purposes without the prior written permission + * of the authors. + */ + +package Triangle.TreeDrawer; + +class Polyline { + int dx, dy; + Polyline link; + + Polyline(int dx, int dy, Polyline link) { + this.dx = dx; + this.dy = dy; + this.link = link; + } +}; diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..596fe78 --- /dev/null +++ b/pom.xml @@ -0,0 +1,19 @@ + + 4.0.0 + triangle.tools + triangle-tools + pom + 2.1 + + 1.8 + 1.8 + UTF-8 + + + Triangle.AbstractMachine + Triangle.Compiler + Triangle.AbstractMachine.Disassembler + Triangle.AbstractMachine.Interpreter + + \ No newline at end of file