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");