From a6a078680c779b3997e38320b8738dee8b429628 Mon Sep 17 00:00:00 2001 From: Deryck Brown Date: Mon, 23 May 2022 21:39:42 +0100 Subject: [PATCH] Simplify code generation using overridden AST methods. --- .../expressions/CharacterExpression.java | 10 ++ .../expressions/Expression.java | 8 ++ .../expressions/IntegerExpression.java | 10 ++ .../types/AnyTypeDenoter.java | 5 + .../types/ArrayTypeDenoter.java | 5 + .../types/BoolTypeDenoter.java | 6 + .../types/CharTypeDenoter.java | 6 + .../types/ErrorTypeDenoter.java | 5 + .../types/IntTypeDenoter.java | 6 + .../types/MultipleFieldTypeDenoter.java | 5 + .../types/RecordTypeDenoter.java | 5 + .../types/SimpleTypeDenoter.java | 5 + .../types/SingleFieldTypeDenoter.java | 5 + .../types/TypeDenoter.java | 2 + .../java/triangle/codeGenerator/Encoder.java | 107 ++++-------------- 15 files changed, 105 insertions(+), 85 deletions(-) diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/CharacterExpression.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/CharacterExpression.java index b105b49..ba2e959 100644 --- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/CharacterExpression.java +++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/CharacterExpression.java @@ -30,4 +30,14 @@ public class CharacterExpression extends Expression { } public final CharacterLiteral CL; + + @Override + public boolean isLiteral() { + return true; + } + + @Override + public int getValue() { + return CL.getValue(); + } } diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/Expression.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/Expression.java index efea114..70739bd 100644 --- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/Expression.java +++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/Expression.java @@ -28,6 +28,14 @@ public abstract class Expression extends AbstractSyntaxTree { public TypeDenoter type; + public boolean isLiteral() { + return false; + } + + public int getValue() { + throw new UnsupportedOperationException(); + } + public abstract TResult visit(ExpressionVisitor visitor, TArg arg); public TResult visit(ExpressionVisitor visitor) { diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/IntegerExpression.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/IntegerExpression.java index 7f0507e..97de244 100644 --- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/IntegerExpression.java +++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/IntegerExpression.java @@ -30,4 +30,14 @@ public class IntegerExpression extends Expression { } public final IntegerLiteral IL; + + @Override + public boolean isLiteral() { + return true; + } + + @Override + public int getValue() { + return IL.getValue(); + } } diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/AnyTypeDenoter.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/AnyTypeDenoter.java index 4ef7559..171c9ca 100644 --- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/AnyTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/AnyTypeDenoter.java @@ -31,4 +31,9 @@ public class AnyTypeDenoter extends TypeDenoter { public boolean equals(Object obj) { return false; } + + @Override + public int getSize() { + return 0; + } } diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/ArrayTypeDenoter.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/ArrayTypeDenoter.java index a20f5d4..8d43342 100644 --- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/ArrayTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/ArrayTypeDenoter.java @@ -41,6 +41,11 @@ public class ArrayTypeDenoter extends TypeDenoter { return false; } } + + @Override + public int getSize() { + return IL.getValue() * T.getSize(); + } public final IntegerLiteral IL; public TypeDenoter T; diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/BoolTypeDenoter.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/BoolTypeDenoter.java index 3ce413f..f00e05e 100644 --- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/BoolTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/BoolTypeDenoter.java @@ -14,6 +14,7 @@ package triangle.abstractSyntaxTrees.types; +import triangle.abstractMachine.Machine; import triangle.abstractSyntaxTrees.visitors.TypeDenoterVisitor; import triangle.syntacticAnalyzer.SourcePosition; @@ -26,6 +27,11 @@ public class BoolTypeDenoter extends TypeDenoter { public TResult visit(TypeDenoterVisitor v, TArg arg) { return v.visitBoolTypeDenoter(this, arg); } + + @Override + public int getSize() { + return Machine.booleanSize; + } @Override public boolean equals(Object obj) { diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/CharTypeDenoter.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/CharTypeDenoter.java index 7d36c7f..7f474b4 100644 --- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/CharTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/CharTypeDenoter.java @@ -14,6 +14,7 @@ package triangle.abstractSyntaxTrees.types; +import triangle.abstractMachine.Machine; import triangle.abstractSyntaxTrees.visitors.TypeDenoterVisitor; import triangle.syntacticAnalyzer.SourcePosition; @@ -26,6 +27,11 @@ public class CharTypeDenoter extends TypeDenoter { public TResult visit(TypeDenoterVisitor v, TArg arg) { return v.visitCharTypeDenoter(this, arg); } + + @Override + public int getSize() { + return Machine.characterSize; + } @Override public boolean equals(Object obj) { diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/ErrorTypeDenoter.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/ErrorTypeDenoter.java index aace3d3..de6ec0a 100644 --- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/ErrorTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/ErrorTypeDenoter.java @@ -27,6 +27,11 @@ public class ErrorTypeDenoter extends TypeDenoter { return v.visitErrorTypeDenoter(this, arg); } + @Override + public int getSize() { + return 0; + } + @Override public boolean equals(Object obj) { return true; diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/IntTypeDenoter.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/IntTypeDenoter.java index 67f99d4..9c5fb7f 100644 --- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/IntTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/IntTypeDenoter.java @@ -14,6 +14,7 @@ package triangle.abstractSyntaxTrees.types; +import triangle.abstractMachine.Machine; import triangle.abstractSyntaxTrees.visitors.TypeDenoterVisitor; import triangle.syntacticAnalyzer.SourcePosition; @@ -26,6 +27,11 @@ public class IntTypeDenoter extends TypeDenoter { public TResult visit(TypeDenoterVisitor v, TArg arg) { return v.visitIntTypeDenoter(this, arg); } + + @Override + public int getSize() { + return Machine.integerSize; + } @Override public boolean equals(Object obj) { diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/MultipleFieldTypeDenoter.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/MultipleFieldTypeDenoter.java index eefe222..c9b7658 100644 --- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/MultipleFieldTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/MultipleFieldTypeDenoter.java @@ -31,6 +31,11 @@ public class MultipleFieldTypeDenoter extends FieldTypeDenoter { public TResult visit(TypeDenoterVisitor v, TArg arg) { return v.visitMultipleFieldTypeDenoter(this, arg); } + + @Override + public int getSize() { + return T.getSize() + FT.getSize(); + } @Override public boolean equals(Object obj) { diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/RecordTypeDenoter.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/RecordTypeDenoter.java index d10c298..8ba90d6 100644 --- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/RecordTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/RecordTypeDenoter.java @@ -27,6 +27,11 @@ public class RecordTypeDenoter extends TypeDenoter { public TResult visit(TypeDenoterVisitor v, TArg arg) { return v.visitRecordTypeDenoter(this, arg); } + + @Override + public int getSize() { + return FT.getSize(); + } @Override public boolean equals(Object obj) { diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/SimpleTypeDenoter.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/SimpleTypeDenoter.java index 7cc96d8..9d2d2b5 100644 --- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/SimpleTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/SimpleTypeDenoter.java @@ -28,6 +28,11 @@ public class SimpleTypeDenoter extends TypeDenoter { public TResult visit(TypeDenoterVisitor v, TArg arg) { return v.visitSimpleTypeDenoter(this, arg); } + + @Override + public int getSize() { + return 0; + } @Override public boolean equals(Object obj) { diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/SingleFieldTypeDenoter.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/SingleFieldTypeDenoter.java index 9372058..1471bb0 100644 --- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/SingleFieldTypeDenoter.java +++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/SingleFieldTypeDenoter.java @@ -29,6 +29,11 @@ public class SingleFieldTypeDenoter extends FieldTypeDenoter { public TResult visit(TypeDenoterVisitor v, TArg arg) { return v.visitSingleFieldTypeDenoter(this, arg); } + + @Override + public int getSize() { + return T.getSize(); + } @Override public boolean equals(Object obj) { diff --git a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/TypeDenoter.java b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/TypeDenoter.java index aa38d24..b59be4f 100644 --- a/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/TypeDenoter.java +++ b/Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/TypeDenoter.java @@ -32,4 +32,6 @@ public abstract class TypeDenoter extends AbstractSyntaxTree { public TResult visit(TypeDenoterVisitor visitor) { return visit(visitor, null); } + + public abstract int getSize(); } diff --git a/Triangle.Compiler/src/main/java/triangle/codeGenerator/Encoder.java b/Triangle.Compiler/src/main/java/triangle/codeGenerator/Encoder.java index be9c53e..d924d46 100644 --- a/Triangle.Compiler/src/main/java/triangle/codeGenerator/Encoder.java +++ b/Triangle.Compiler/src/main/java/triangle/codeGenerator/Encoder.java @@ -107,6 +107,7 @@ import triangle.codeGenerator.entities.KnownAddress; import triangle.codeGenerator.entities.KnownRoutine; import triangle.codeGenerator.entities.KnownValue; import triangle.codeGenerator.entities.PrimitiveRoutine; +import triangle.codeGenerator.entities.RoutineEntity; import triangle.codeGenerator.entities.RuntimeEntity; import triangle.codeGenerator.entities.TypeRepresentation; import triangle.codeGenerator.entities.UnknownAddress; @@ -209,7 +210,7 @@ public final class Encoder implements ActualParameterVisitor, @Override public Integer visitCharacterExpression(CharacterExpression ast, Frame frame) { var valSize = ast.type.visit(this); - emitter.emit(OpCode.LOADL, ast.CL.spelling.charAt(1)); + emitter.emit(OpCode.LOADL, ast.CL.getValue()); return valSize; } @@ -234,7 +235,7 @@ public final class Encoder implements ActualParameterVisitor, @Override public Integer visitIntegerExpression(IntegerExpression ast, Frame frame) { var valSize = ast.type.visit(this); - emitter.emit(OpCode.LOADL, Integer.parseInt(ast.IL.spelling)); + emitter.emit(OpCode.LOADL, ast.IL.getValue()); return valSize; } @@ -280,15 +281,11 @@ public final class Encoder implements ActualParameterVisitor, @Override public Integer visitConstDeclaration(ConstDeclaration ast, Frame frame) { var extraSize = 0; - if (ast.E instanceof CharacterExpression) { - var CL = ((CharacterExpression) ast.E).CL; - ast.entity = new KnownValue(Machine.characterSize, CL.getValue()); - } else if (ast.E instanceof IntegerExpression) { - var IL = ((IntegerExpression) ast.E).IL; - ast.entity = new KnownValue(Machine.integerSize, IL.getValue()); + if (ast.E.isLiteral()) { + ast.entity = new KnownValue(ast.E.type.getSize(), ast.E.getValue()); } else { var valSize = ast.E.visit(this, frame); - ast.entity = new UnknownValue(valSize, frame.getLevel(), frame.getSize()); + ast.entity = new UnknownValue(valSize, frame); extraSize = valSize; } writeTableDetails(ast); @@ -359,7 +356,7 @@ public final class Encoder implements ActualParameterVisitor, public Integer visitVarDeclaration(VarDeclaration ast, Frame frame) { var extraSize = ast.T.visit(this); emitter.emit(OpCode.PUSH, extraSize); - ast.entity = new KnownAddress(Machine.addressSize, frame.getLevel(), frame.getSize()); + ast.entity = new KnownAddress(Machine.addressSize, frame); writeTableDetails(ast); return extraSize; } @@ -451,41 +448,15 @@ public final class Encoder implements ActualParameterVisitor, @Override public Integer visitFuncActualParameter(FuncActualParameter ast, Frame frame) { - if (ast.I.decl.entity instanceof KnownRoutine) { - var address = ((KnownRoutine) ast.I.decl.entity).getAddress(); - // static link, code address - emitter.emit(OpCode.LOADA, 0, frame.getDisplayRegister(address), 0); - emitter.emit(OpCode.LOADA, 0, Register.CB, address.getDisplacement()); - } else if (ast.I.decl.entity instanceof UnknownRoutine) { - var address = ((UnknownRoutine) ast.I.decl.entity).getAddress(); - emitter.emit(OpCode.LOAD, Machine.closureSize, frame.getDisplayRegister(address), - address.getDisplacement()); - } else if (ast.I.decl.entity instanceof PrimitiveRoutine) { - var primitive = ((PrimitiveRoutine) ast.I.decl.entity).getPrimitive(); - // static link, code address - emitter.emit(OpCode.LOADA, 0, Register.SB, 0); - emitter.emit(OpCode.LOADA, Register.PB, primitive); - } + var routineEntity = (RoutineEntity) ast.I.decl.entity; + routineEntity.encodeFetch(emitter, frame); return Machine.closureSize; } @Override public Integer visitProcActualParameter(ProcActualParameter ast, Frame frame) { - if (ast.I.decl.entity instanceof KnownRoutine) { - var address = ((KnownRoutine) ast.I.decl.entity).getAddress(); - // static link, code address - emitter.emit(OpCode.LOADA, 0, frame.getDisplayRegister(address), 0); - emitter.emit(OpCode.LOADA, 0, Register.CB, address.getDisplacement()); - } else if (ast.I.decl.entity instanceof UnknownRoutine) { - var address = ((UnknownRoutine) ast.I.decl.entity).getAddress(); - emitter.emit(OpCode.LOAD, Machine.closureSize, frame.getDisplayRegister(address), - address.getDisplacement()); - } else if (ast.I.decl.entity instanceof PrimitiveRoutine) { - var primitive = ((PrimitiveRoutine) ast.I.decl.entity).getPrimitive(); - // static link, code address - emitter.emit(OpCode.LOADA, 0, Register.SB, 0); - emitter.emit(OpCode.LOADA, Register.PB, primitive); - } + var routineEntity = (RoutineEntity) ast.I.decl.entity; + routineEntity.encodeFetch(emitter, frame); return Machine.closureSize; } @@ -524,7 +495,7 @@ public final class Encoder implements ActualParameterVisitor, int typeSize; if (ast.entity == null) { var elemSize = ast.T.visit(this); - typeSize = Integer.parseInt(ast.IL.spelling) * elemSize; + typeSize = ast.IL.getValue() * elemSize; ast.entity = new TypeRepresentation(typeSize); writeTableDetails(ast); } else { @@ -623,23 +594,8 @@ public final class Encoder implements ActualParameterVisitor, @Override public Void visitIdentifier(Identifier ast, Frame frame) { - if (ast.decl.entity instanceof KnownRoutine) { - var address = ((KnownRoutine) ast.decl.entity).getAddress(); - emitter.emit(OpCode.CALL, frame.getDisplayRegister(address), Register.CB, address.getDisplacement()); - } else if (ast.decl.entity instanceof UnknownRoutine) { - var address = ((UnknownRoutine) ast.decl.entity).getAddress(); - emitter.emit(OpCode.LOAD, Machine.closureSize, frame.getDisplayRegister(address), - address.getDisplacement()); - emitter.emit(OpCode.CALLI, 0); - } else if (ast.decl.entity instanceof PrimitiveRoutine) { - var primitive = ((PrimitiveRoutine) ast.decl.entity).getPrimitive(); - if (primitive != Primitive.ID) - emitter.emit(OpCode.CALL, Register.PB, primitive); - } else if (ast.decl.entity instanceof EqualityRoutine) { // "=" or "\=" - var primitive = ((EqualityRoutine) ast.decl.entity).getPrimitive(); - emitter.emit(OpCode.LOADL, 0, frame.getSize() / 2); - emitter.emit(OpCode.CALL, Register.PB, primitive); - } + var routineEntity = (RoutineEntity) ast.decl.entity; + routineEntity.encodeCall(emitter, frame); return null; } @@ -650,23 +606,8 @@ public final class Encoder implements ActualParameterVisitor, @Override public Void visitOperator(Operator ast, Frame frame) { - if (ast.decl.entity instanceof KnownRoutine) { - var address = ((KnownRoutine) ast.decl.entity).getAddress(); - emitter.emit(OpCode.CALL, frame.getDisplayRegister(address), Register.CB, address.getDisplacement()); - } else if (ast.decl.entity instanceof UnknownRoutine) { - var address = ((UnknownRoutine) ast.decl.entity).getAddress(); - emitter.emit(OpCode.LOAD, Machine.closureSize, frame.getDisplayRegister(address), - address.getDisplacement()); - emitter.emit(OpCode.CALLI, 0); - } else if (ast.decl.entity instanceof PrimitiveRoutine) { - var primitive = ((PrimitiveRoutine) ast.decl.entity).getPrimitive(); - if (primitive != Primitive.ID) - emitter.emit(OpCode.CALL, Register.PB, primitive); - } else if (ast.decl.entity instanceof EqualityRoutine) { // "=" or "\=" - var primitive = ((EqualityRoutine) ast.decl.entity).getPrimitive(); - emitter.emit(OpCode.LOADL, 0, frame.getSize() / 2); - emitter.emit(OpCode.CALL, Register.PB, primitive); - } + var routineEntity = (RoutineEntity) ast.decl.entity; + routineEntity.encodeCall(emitter, frame); return null; } @@ -693,9 +634,8 @@ public final class Encoder implements ActualParameterVisitor, ast.offset = ast.V.offset; ast.indexed = ast.V.indexed; var elemSize = ast.type.visit(this); - if (ast.E instanceof IntegerExpression) { - var IL = ((IntegerExpression) ast.E).IL; - ast.offset = ast.offset + Integer.parseInt(IL.spelling) * elemSize; + if (ast.E.isLiteral()) { + ast.offset = ast.offset + ast.E.getValue() * elemSize; } else { // v-name is indexed by a proper expression, not a literal if (ast.indexed) { @@ -743,14 +683,11 @@ public final class Encoder implements ActualParameterVisitor, } // Decides run-time representation of a standard constant. - private final void elaborateStdConst(Declaration constDeclaration, int value) { + private final void elaborateStdConst(ConstDeclaration constDeclaration, int value) { - if (constDeclaration instanceof ConstDeclaration) { - var decl = (ConstDeclaration) constDeclaration; - var typeSize = decl.E.type.visit(this); - decl.entity = new KnownValue(typeSize, value); - writeTableDetails(constDeclaration); - } + var typeSize = constDeclaration.E.type.visit(this); + constDeclaration.entity = new KnownValue(typeSize, value); + writeTableDetails(constDeclaration); } // Decides run-time representation of a standard routine.