Simplify code generation using overridden AST methods.

main
Deryck Brown 2 years ago
parent fbada163d4
commit a6a078680c
  1. 10
      Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/CharacterExpression.java
  2. 8
      Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/Expression.java
  3. 10
      Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/expressions/IntegerExpression.java
  4. 5
      Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/AnyTypeDenoter.java
  5. 5
      Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/ArrayTypeDenoter.java
  6. 6
      Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/BoolTypeDenoter.java
  7. 6
      Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/CharTypeDenoter.java
  8. 5
      Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/ErrorTypeDenoter.java
  9. 6
      Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/IntTypeDenoter.java
  10. 5
      Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/MultipleFieldTypeDenoter.java
  11. 5
      Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/RecordTypeDenoter.java
  12. 5
      Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/SimpleTypeDenoter.java
  13. 5
      Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/SingleFieldTypeDenoter.java
  14. 2
      Triangle.Compiler/src/main/java/triangle/abstractSyntaxTrees/types/TypeDenoter.java
  15. 107
      Triangle.Compiler/src/main/java/triangle/codeGenerator/Encoder.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();
}
}

@ -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 <TArg, TResult> TResult visit(ExpressionVisitor<TArg, TResult> visitor, TArg arg);
public <TArg, TResult> TResult visit(ExpressionVisitor<TArg, TResult> visitor) {

@ -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();
}
}

@ -31,4 +31,9 @@ public class AnyTypeDenoter extends TypeDenoter {
public boolean equals(Object obj) {
return false;
}
@Override
public int getSize() {
return 0;
}
}

@ -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;

@ -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 <TArg, TResult> TResult visit(TypeDenoterVisitor<TArg, TResult> v, TArg arg) {
return v.visitBoolTypeDenoter(this, arg);
}
@Override
public int getSize() {
return Machine.booleanSize;
}
@Override
public boolean equals(Object obj) {

@ -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 <TArg, TResult> TResult visit(TypeDenoterVisitor<TArg, TResult> v, TArg arg) {
return v.visitCharTypeDenoter(this, arg);
}
@Override
public int getSize() {
return Machine.characterSize;
}
@Override
public boolean equals(Object obj) {

@ -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;

@ -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 <TArg, TResult> TResult visit(TypeDenoterVisitor<TArg, TResult> v, TArg arg) {
return v.visitIntTypeDenoter(this, arg);
}
@Override
public int getSize() {
return Machine.integerSize;
}
@Override
public boolean equals(Object obj) {

@ -31,6 +31,11 @@ public class MultipleFieldTypeDenoter extends FieldTypeDenoter {
public <TArg, TResult> TResult visit(TypeDenoterVisitor<TArg, TResult> v, TArg arg) {
return v.visitMultipleFieldTypeDenoter(this, arg);
}
@Override
public int getSize() {
return T.getSize() + FT.getSize();
}
@Override
public boolean equals(Object obj) {

@ -27,6 +27,11 @@ public class RecordTypeDenoter extends TypeDenoter {
public <TArg, TResult> TResult visit(TypeDenoterVisitor<TArg, TResult> v, TArg arg) {
return v.visitRecordTypeDenoter(this, arg);
}
@Override
public int getSize() {
return FT.getSize();
}
@Override
public boolean equals(Object obj) {

@ -28,6 +28,11 @@ public class SimpleTypeDenoter extends TypeDenoter {
public <TArg, TResult> TResult visit(TypeDenoterVisitor<TArg, TResult> v, TArg arg) {
return v.visitSimpleTypeDenoter(this, arg);
}
@Override
public int getSize() {
return 0;
}
@Override
public boolean equals(Object obj) {

@ -29,6 +29,11 @@ public class SingleFieldTypeDenoter extends FieldTypeDenoter {
public <TArg, TResult> TResult visit(TypeDenoterVisitor<TArg, TResult> v, TArg arg) {
return v.visitSingleFieldTypeDenoter(this, arg);
}
@Override
public int getSize() {
return T.getSize();
}
@Override
public boolean equals(Object obj) {

@ -32,4 +32,6 @@ public abstract class TypeDenoter extends AbstractSyntaxTree {
public <TArg, TResult> TResult visit(TypeDenoterVisitor<TArg, TResult> visitor) {
return visit(visitor, null);
}
public abstract int getSize();
}

@ -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<Frame, Integer>,
@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<Frame, Integer>,
@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<Frame, Integer>,
@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<Frame, Integer>,
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<Frame, Integer>,
@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<Frame, Integer>,
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<Frame, Integer>,
@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<Frame, Integer>,
@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<Frame, Integer>,
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<Frame, Integer>,
}
// 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.