This commit is contained in:
nub31
2025-07-06 00:29:55 +02:00
parent dc593d0b4e
commit 92ebefd3d6
2 changed files with 80 additions and 70 deletions

View File

@@ -53,17 +53,17 @@ public static class QBEGenerator
_implFuncNameIndex = 0;
_codeIsReachable = true;
// foreach (var structDef in _definitionTable.GetStructs())
// {
// EmitStructDefinition(structDef);
// _writer.NewLine();
// }
//
// foreach (var trait in _definitionTable.GetTraits())
// {
// EmitTraitVTable(trait);
// _writer.NewLine();
// }
foreach (var structDef in _definitionTable.GetStructs())
{
EmitStructDefinition(structDef);
_writer.NewLine();
}
foreach (var trait in _definitionTable.GetTraits())
{
EmitTraitVTable(trait);
_writer.NewLine();
}
foreach (var funcDef in _syntaxTree.TopLevelNodes.OfType<BoundLocalFuncNode>())
{
@@ -574,65 +574,65 @@ public static class QBEGenerator
_writer.EndFunction();
}
// private static void EmitStructDefinition(BoundStructNode structDef)
// {
// var structType = new BoundNubCustomType(structDef.Namespace, structDef.Name);
// _writer.WriteLine($"type {CustomTypeName(structType)} = {{ ");
//
// var types = new Dictionary<string, string>();
//
// foreach (var field in structDef.Fields)
// {
// types.Add(field.Name, StructDefQBEType(field));
// }
//
// var longest = types.Values.Max(x => x.Length);
// foreach (var (name, type) in types)
// {
// var padding = longest - type.Length;
// _writer.Indented($"{type},{new string(' ', padding)} # {name}");
// }
//
// _writer.WriteLine("}");
// return;
//
// string StructDefQBEType(BoundStructFieldNode field)
// {
// return field.Type switch
// {
// BoundNubCustomType customType => CustomTypeName(customType),
// BoundNubComplexType => "l",
// BoundNubSimpleType simpleType => simpleType switch
// {
// BoundNubPointerType or BoundNubFuncType => "l",
// BoundNubPrimitiveType primitiveType => primitiveType.Kind switch
// {
// PrimitiveTypeKind.I64 or PrimitiveTypeKind.U64 => "l",
// PrimitiveTypeKind.I32 or PrimitiveTypeKind.U32 => "w",
// PrimitiveTypeKind.I16 or PrimitiveTypeKind.U16 => "h",
// PrimitiveTypeKind.I8 or PrimitiveTypeKind.U8 or PrimitiveTypeKind.Bool => "b",
// PrimitiveTypeKind.F64 => "d",
// PrimitiveTypeKind.F32 => "s",
// _ => throw new ArgumentOutOfRangeException()
// },
// _ => throw new NotSupportedException($"'{field.Type}' type cannot be used in structs")
// },
// _ => throw new UnreachableException()
// };
// }
// }
//
// private static void EmitTraitVTable(BoundTraitNode traitDef)
// {
// _writer.WriteLine($"type {CustomTypeName(new BoundNubCustomType(traitDef.Namespace, traitDef.Name))} = {{");
//
// foreach (var func in traitDef.Functions)
// {
// _writer.Indented($"l, # func {func.Name}({string.Join(", ", func.Parameters.Select(x => $"{x.Name}: {x.Type}"))}): {func.ReturnType}");
// }
//
// _writer.WriteLine("}");
// }
private static void EmitStructDefinition(BoundStructNode structDef)
{
_writer.WriteLine($"type {StructTypeName(new BoundNubStructType(structDef.Namespace, structDef.Name))} = {{ ");
var types = new Dictionary<string, string>();
foreach (var field in structDef.Fields)
{
types.Add(field.Name, StructDefQBEType(field));
}
var longest = types.Values.Max(x => x.Length);
foreach (var (name, type) in types)
{
var padding = longest - type.Length;
_writer.Indented($"{type},{new string(' ', padding)} # {name}");
}
_writer.WriteLine("}");
return;
string StructDefQBEType(BoundStructFieldNode field)
{
return field.Type switch
{
BoundNubStructType structType => StructTypeName(structType),
BoundNubTraitType traitType => TraitTypeName(traitType),
BoundNubComplexType => "l",
BoundNubSimpleType simpleType => simpleType switch
{
BoundNubPointerType or BoundNubFuncType => "l",
BoundNubPrimitiveType primitiveType => primitiveType.Kind switch
{
PrimitiveTypeKind.I64 or PrimitiveTypeKind.U64 => "l",
PrimitiveTypeKind.I32 or PrimitiveTypeKind.U32 => "w",
PrimitiveTypeKind.I16 or PrimitiveTypeKind.U16 => "h",
PrimitiveTypeKind.I8 or PrimitiveTypeKind.U8 or PrimitiveTypeKind.Bool => "b",
PrimitiveTypeKind.F64 => "d",
PrimitiveTypeKind.F32 => "s",
_ => throw new ArgumentOutOfRangeException()
},
_ => throw new NotSupportedException($"'{field.Type}' type cannot be used in structs")
},
_ => throw new UnreachableException()
};
}
}
private static void EmitTraitVTable(BoundTraitNode traitDef)
{
_writer.WriteLine($"type {TraitTypeName(new BoundNubTraitType(traitDef.Namespace, traitDef.Name))} = {{");
foreach (var func in traitDef.Functions)
{
_writer.Indented($"l, # func {func.Name}({string.Join(", ", func.Parameters.Select(x => $"{x.Name}: {x.Type}"))}): {func.ReturnType}");
}
_writer.WriteLine("}");
}
private static void EmitStatement(BoundStatementNode statement)
{

View File

@@ -121,4 +121,14 @@ public sealed class BoundDefinitionTable
{
return trait.Functions.First(x => x.Name == name);
}
public IEnumerable<BoundStructNode> GetStructs()
{
return _topLevelNodes.OfType<BoundStructNode>();
}
public IEnumerable<BoundTraitNode> GetTraits()
{
return _topLevelNodes.OfType<BoundTraitNode>();
}
}