Add support for multiple interfaces

This commit is contained in:
nub31
2025-08-13 19:18:37 +02:00
parent cc8f8210b5
commit 9c69c39cff
2 changed files with 31 additions and 11 deletions

View File

@@ -5,28 +5,34 @@ interface Printable
func print() func print()
} }
struct Human : Printable interface Stringable
{
func str(): cstring
}
struct Human : Printable, Stringable
{ {
name: cstring name: cstring
func str(): cstring
{
return this^.name
}
func print() func print()
{ {
puts(this^.name) puts(this^.str())
} }
} }
func main(args: []cstring): i64 func main(args: []cstring): i64
{ {
let human = alloc Human { let human: Stringable = alloc Human {
name = "oliver" name = "oliver"
} }
human.print() puts(human.str())
print_printable(human) // human.print()
return 0 return 0
} }
func print_printable(printable: Printable)
{
printable.print()
}

View File

@@ -459,9 +459,23 @@ public partial class QBEGenerator
{ {
var implementation = EmitUnwrap(EmitExpression(interfaceInitializer.Implementation)); var implementation = EmitUnwrap(EmitExpression(interfaceInitializer.Implementation));
var vtableOffset = 0;
foreach (var interfaceImplementation in interfaceInitializer.StructType.InterfaceImplementations)
{
if (interfaceImplementation == interfaceInitializer.InterfaceType)
{
break;
}
vtableOffset += interfaceImplementation.Functions.Count * 8;
}
var result = TmpName(); var result = TmpName();
_writer.Indented($"{result} =l alloc8 16"); _writer.Indented($"{result} =l alloc8 16");
_writer.Indented($"storel {StructVtableName(interfaceInitializer.StructType.Name)}, {result}");
var interfaceVtablePointer = TmpName();
_writer.Indented($"{interfaceVtablePointer} =l add {StructVtableName(interfaceInitializer.StructType.Name)}, {vtableOffset}");
_writer.Indented($"storel {interfaceVtablePointer}, {result}");
var objectPointer = TmpName(); var objectPointer = TmpName();
_writer.Indented($"{objectPointer} =l add {result}, 8"); _writer.Indented($"{objectPointer} =l add {result}, 8");