From 9c69c39cff82f8abf26cae852db2665364622eca Mon Sep 17 00:00:00 2001 From: nub31 Date: Wed, 13 Aug 2025 19:18:37 +0200 Subject: [PATCH] Add support for multiple interfaces --- example/src/main.nub | 26 ++++++++++++------- .../Generation/QBE/QBEGenerator.Expression.cs | 16 +++++++++++- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/example/src/main.nub b/example/src/main.nub index d648d1f..1048304 100644 --- a/example/src/main.nub +++ b/example/src/main.nub @@ -5,28 +5,34 @@ interface Printable func print() } -struct Human : Printable +interface Stringable +{ + func str(): cstring +} + +struct Human : Printable, Stringable { name: cstring + func str(): cstring + { + return this^.name + } + func print() { - puts(this^.name) + puts(this^.str()) } } func main(args: []cstring): i64 { - let human = alloc Human { + let human: Stringable = alloc Human { name = "oliver" } - human.print() - print_printable(human) + puts(human.str()) + // human.print() + return 0 } - -func print_printable(printable: Printable) -{ - printable.print() -} \ No newline at end of file diff --git a/src/compiler/NubLang/Generation/QBE/QBEGenerator.Expression.cs b/src/compiler/NubLang/Generation/QBE/QBEGenerator.Expression.cs index 1e68d2f..ced489e 100644 --- a/src/compiler/NubLang/Generation/QBE/QBEGenerator.Expression.cs +++ b/src/compiler/NubLang/Generation/QBE/QBEGenerator.Expression.cs @@ -459,9 +459,23 @@ public partial class QBEGenerator { 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(); _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(); _writer.Indented($"{objectPointer} =l add {result}, 8");