Remove interfaces
This commit is contained in:
@@ -11,7 +11,6 @@ public class QBEGenerator
|
||||
private readonly QBEWriter _writer;
|
||||
private readonly List<DefinitionNode> _definitions;
|
||||
private readonly HashSet<StructTypeNode> _structTypes;
|
||||
private readonly HashSet<InterfaceTypeNode> _interfaceTypes;
|
||||
|
||||
private readonly List<CStringLiteral> _cStringLiterals = [];
|
||||
private readonly List<StringLiteral> _stringLiterals = [];
|
||||
@@ -23,11 +22,10 @@ public class QBEGenerator
|
||||
private int _stringLiteralIndex;
|
||||
private bool _codeIsReachable = true;
|
||||
|
||||
public QBEGenerator(List<DefinitionNode> definitions, HashSet<StructTypeNode> structTypes, HashSet<InterfaceTypeNode> interfaceTypes)
|
||||
public QBEGenerator(List<DefinitionNode> definitions, HashSet<StructTypeNode> structTypes)
|
||||
{
|
||||
_definitions = definitions;
|
||||
_structTypes = structTypes;
|
||||
_interfaceTypes = interfaceTypes;
|
||||
_writer = new QBEWriter();
|
||||
}
|
||||
|
||||
@@ -261,8 +259,8 @@ public class QBEGenerator
|
||||
return;
|
||||
}
|
||||
|
||||
// Structs and interfaces has known sizes at compile time
|
||||
if (complexType is StructTypeNode or InterfaceTypeNode)
|
||||
// Structs has known sizes at compile time
|
||||
if (complexType is StructTypeNode)
|
||||
{
|
||||
var value = EmitExpression(source);
|
||||
_writer.Indented($"blit {value}, {destination}, {SizeOf(complexType)}");
|
||||
@@ -289,7 +287,7 @@ public class QBEGenerator
|
||||
private string EmitCopy(ExpressionNode source)
|
||||
{
|
||||
// Allowlist for types which are safe to not copy
|
||||
if (source is ArrayInitializerNode or StructInitializerNode or ConvertToInterfaceNode or LiteralNode)
|
||||
if (source is ArrayInitializerNode or StructInitializerNode or LiteralNode)
|
||||
{
|
||||
return EmitExpression(source);
|
||||
}
|
||||
@@ -304,8 +302,8 @@ public class QBEGenerator
|
||||
var value = EmitExpression(source);
|
||||
var destination = TmpName();
|
||||
|
||||
// Structs and interfaces has known sizes at compile time
|
||||
if (complexType is StructTypeNode or InterfaceTypeNode)
|
||||
// Structs has known sizes at compile time
|
||||
if (complexType is StructTypeNode)
|
||||
{
|
||||
var size = SizeOf(complexType);
|
||||
_writer.Indented($"{destination} =l alloc8 {size}");
|
||||
@@ -501,12 +499,6 @@ public class QBEGenerator
|
||||
|
||||
private void EmitStatement(StatementNode statement)
|
||||
{
|
||||
// var tokens = statement.Tokens.ToArray();
|
||||
// if (tokens.Length != 0)
|
||||
// {
|
||||
// _writer.WriteLine($"dbgloc {tokens[0].FileSpan.Span.Start.Line}");
|
||||
// }
|
||||
|
||||
switch (statement)
|
||||
{
|
||||
case AssignmentNode assignment:
|
||||
@@ -622,12 +614,6 @@ public class QBEGenerator
|
||||
|
||||
private string EmitExpression(ExpressionNode expression)
|
||||
{
|
||||
// var tokens = expression.Tokens.ToArray();
|
||||
// if (tokens.Length != 0)
|
||||
// {
|
||||
// _writer.WriteLine($"dbgloc {tokens[0].FileSpan.Span.Start.Line}");
|
||||
// }
|
||||
|
||||
return expression switch
|
||||
{
|
||||
ArrayInitializerNode arrayInitializer => EmitArrayInitializer(arrayInitializer),
|
||||
@@ -636,8 +622,6 @@ public class QBEGenerator
|
||||
DereferenceNode dereference => EmitDereference(dereference),
|
||||
BinaryExpressionNode binary => EmitBinaryExpression(binary),
|
||||
FuncCallNode funcCall => EmitFuncCall(funcCall),
|
||||
InterfaceFuncCallNode interfaceFuncCall => EmitInterfaceFuncCall(interfaceFuncCall),
|
||||
ConvertToInterfaceNode convertToInterface => EmitConvertToInterface(convertToInterface),
|
||||
ConvertIntNode convertInt => EmitConvertInt(convertInt),
|
||||
ConvertFloatNode convertFloat => EmitConvertFloat(convertFloat),
|
||||
VariableIdentifierNode identifier => EmitVariableIdentifier(identifier),
|
||||
@@ -673,14 +657,13 @@ public class QBEGenerator
|
||||
|
||||
private string EmitArrayIndexAccess(ArrayIndexAccessNode arrayIndexAccess)
|
||||
{
|
||||
// var address = EmitAddressOfArrayIndexAccess(arrayIndexAccess);
|
||||
// if (arrayIndexAccess.Type is StructTypeNode)
|
||||
// {
|
||||
// return address;
|
||||
// }
|
||||
//
|
||||
// return EmitLoad(arrayIndexAccess.Type, address);
|
||||
throw new NotImplementedException();
|
||||
var address = EmitAddressOfArrayIndexAccess(arrayIndexAccess);
|
||||
if (arrayIndexAccess.Type is StructTypeNode)
|
||||
{
|
||||
return address;
|
||||
}
|
||||
|
||||
return EmitLoad(arrayIndexAccess.Type, address);
|
||||
}
|
||||
|
||||
private string EmitArrayInitializer(ArrayInitializerNode arrayInitializer)
|
||||
@@ -1114,76 +1097,6 @@ public class QBEGenerator
|
||||
}
|
||||
}
|
||||
|
||||
private string EmitInterfaceFuncCall(InterfaceFuncCallNode interfaceFuncCall)
|
||||
{
|
||||
var target = EmitExpression(interfaceFuncCall.InterfaceExpression);
|
||||
|
||||
var functionIndex = interfaceFuncCall.InterfaceType.Functions.ToList().FindIndex(x => x.Name == interfaceFuncCall.Name);
|
||||
var offset = functionIndex * 8;
|
||||
|
||||
var vtable = TmpName();
|
||||
_writer.Indented($"{vtable} =l loadl {target}");
|
||||
|
||||
var funcOffset = TmpName();
|
||||
_writer.Indented($"{funcOffset} =l add {vtable}, {offset}");
|
||||
|
||||
var func = TmpName();
|
||||
_writer.Indented($"{func} =l loadl {funcOffset}");
|
||||
|
||||
var data = TmpName();
|
||||
_writer.Indented($"{data} =l add {target}, 8");
|
||||
_writer.Indented($"{data} =l loadl {data}");
|
||||
|
||||
List<string> parameterStrings = [$"l {data}"];
|
||||
|
||||
foreach (var parameter in interfaceFuncCall.Parameters)
|
||||
{
|
||||
var copy = EmitCopy(parameter);
|
||||
parameterStrings.Add($"{FuncQBETypeName(parameter.Type)} {copy}");
|
||||
}
|
||||
|
||||
if (interfaceFuncCall.Type is VoidTypeNode)
|
||||
{
|
||||
_writer.Indented($"call {func}({string.Join(", ", parameterStrings)})");
|
||||
return string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
var outputName = TmpName();
|
||||
_writer.Indented($"{outputName} {QBEAssign(interfaceFuncCall.Type)} call {func}({string.Join(", ", parameterStrings)})");
|
||||
return outputName;
|
||||
}
|
||||
}
|
||||
|
||||
private string EmitConvertToInterface(ConvertToInterfaceNode convertToInterface)
|
||||
{
|
||||
var implementation = EmitExpression(convertToInterface.Implementation);
|
||||
|
||||
var vtableOffset = 0;
|
||||
foreach (var interfaceImplementation in convertToInterface.StructType.InterfaceImplementations)
|
||||
{
|
||||
if (interfaceImplementation == convertToInterface.InterfaceType)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
vtableOffset += interfaceImplementation.Functions.Count * 8;
|
||||
}
|
||||
|
||||
var destination = TmpName();
|
||||
_writer.Indented($"{destination} =l alloc8 {SizeOf(convertToInterface.InterfaceType)}");
|
||||
|
||||
var interfaceVtablePointer = TmpName();
|
||||
_writer.Indented($"{interfaceVtablePointer} =l add {StructVtableName(convertToInterface.StructType.Module, convertToInterface.StructType.Name)}, {vtableOffset}");
|
||||
_writer.Indented($"storel {interfaceVtablePointer}, {destination}");
|
||||
|
||||
var objectPointer = TmpName();
|
||||
_writer.Indented($"{objectPointer} =l add {destination}, 8");
|
||||
_writer.Indented($"storel {implementation}, {objectPointer}");
|
||||
|
||||
return destination;
|
||||
}
|
||||
|
||||
private string EmitConvertInt(ConvertIntNode convertInt)
|
||||
{
|
||||
var value = EmitExpression(convertInt.Value);
|
||||
@@ -1279,7 +1192,6 @@ public class QBEGenerator
|
||||
StringTypeNode => 8,
|
||||
ArrayTypeNode => 8,
|
||||
StructTypeNode structType => CalculateStructSize(structType),
|
||||
InterfaceTypeNode => 16,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type), $"Unknown type: {type.GetType()}")
|
||||
};
|
||||
}
|
||||
@@ -1288,8 +1200,6 @@ public class QBEGenerator
|
||||
{
|
||||
var offset = 0;
|
||||
|
||||
var fields = new List<TypeNode>(structType.Fields.Count);
|
||||
|
||||
foreach (var field in structType.Fields)
|
||||
{
|
||||
var fieldAlignment = AlignmentOf(field.Type);
|
||||
@@ -1318,7 +1228,6 @@ public class QBEGenerator
|
||||
StringTypeNode => 8,
|
||||
ArrayTypeNode => 8,
|
||||
StructTypeNode structType => CalculateStructAlignment(structType),
|
||||
InterfaceTypeNode => 8,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type), $"Unknown type: {type.GetType()}")
|
||||
};
|
||||
}
|
||||
@@ -1327,11 +1236,6 @@ public class QBEGenerator
|
||||
{
|
||||
var maxAlignment = 1;
|
||||
|
||||
if (structType.InterfaceImplementations.Any())
|
||||
{
|
||||
maxAlignment = Math.Max(maxAlignment, 8);
|
||||
}
|
||||
|
||||
foreach (var field in structType.Fields)
|
||||
{
|
||||
var fieldAlignment = AlignmentOf(field.Type);
|
||||
@@ -1405,11 +1309,6 @@ public class QBEGenerator
|
||||
{
|
||||
return $"$.{module}.{structName}.func.{funcName}";
|
||||
}
|
||||
|
||||
private static string StructVtableName(string module, string structName)
|
||||
{
|
||||
return $"${module}.{structName}.vtable";
|
||||
}
|
||||
}
|
||||
|
||||
public class StringLiteral(string value, string name)
|
||||
|
||||
Reference in New Issue
Block a user