Simplify code generation using overridden AST methods.
This commit is contained in:
parent
fbada163d4
commit
a6a078680c
@ -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.
|
||||
|
Reference in New Issue
Block a user