package generator import "testing" func TestInterfaceBasic (test *testing.T) { testString (test, `%"0zNZN147MN2wzMAQ6NS2dQ==::Doer" = type { ptr, ptr } %"0zNZN147MN2wzMAQ6NS2dQ==::T" = type i64 define void @"0zNZN147MN2wzMAQ6NS2dQ==::main"() { 0: %1 = alloca %"0zNZN147MN2wzMAQ6NS2dQ==::Doer" %2 = getelementptr %"0zNZN147MN2wzMAQ6NS2dQ==::Doer", ptr %1, i32 0, i32 0 %3 = alloca %"0zNZN147MN2wzMAQ6NS2dQ==::T" store ptr %3, ptr %2 %4 = getelementptr %"0zNZN147MN2wzMAQ6NS2dQ==::Doer", ptr %1, i32 0, i32 1 store ptr @"0zNZN147MN2wzMAQ6NS2dQ==::T.do", ptr %4 %5 = getelementptr %"0zNZN147MN2wzMAQ6NS2dQ==::Doer", ptr %1, i32 0, i32 1 %6 = getelementptr %"0zNZN147MN2wzMAQ6NS2dQ==::Doer", ptr %1, i32 0, i32 0 %7 = load ptr, ptr %6 %8 = load ptr, ptr %5 call void %8(ptr %7) ret void } define void @"0zNZN147MN2wzMAQ6NS2dQ==::T.do"(ptr %this) { 0: %1 = alloca ptr store ptr %this, ptr %1 ret void } `, ` Doer: (& [do]) T: Int T.[do] = { } [main] = { ifa:Doer = x:T ifa.[do] } `) } func TestInterfaceIntegerReturn (test *testing.T) { testString (test, `%"0zNZN147MN2wzMAQ6NS2dQ==::Number" = type i64 %"0zNZN147MN2wzMAQ6NS2dQ==::Numbered" = type { ptr, ptr } define i64 @"0zNZN147MN2wzMAQ6NS2dQ==::main"() { 0: %1 = alloca %"0zNZN147MN2wzMAQ6NS2dQ==::Number" store i64 5, ptr %1 %2 = alloca %"0zNZN147MN2wzMAQ6NS2dQ==::Numbered" %3 = getelementptr %"0zNZN147MN2wzMAQ6NS2dQ==::Numbered", ptr %2, i32 0, i32 0 store ptr %1, ptr %3 %4 = getelementptr %"0zNZN147MN2wzMAQ6NS2dQ==::Numbered", ptr %2, i32 0, i32 1 store ptr @"0zNZN147MN2wzMAQ6NS2dQ==::Number.number", ptr %4 %5 = getelementptr %"0zNZN147MN2wzMAQ6NS2dQ==::Numbered", ptr %2, i32 0, i32 1 %6 = getelementptr %"0zNZN147MN2wzMAQ6NS2dQ==::Numbered", ptr %2, i32 0, i32 0 %7 = load ptr, ptr %6 %8 = load ptr, ptr %5 %9 = call i64 %8(ptr %7) ret i64 %9 } define i64 @"0zNZN147MN2wzMAQ6NS2dQ==::Number.number"(ptr %this) { 0: %1 = alloca ptr store ptr %this, ptr %1 %2 = load ptr, ptr %1 %3 = load i64, ptr %2 ret i64 %3 } `, ` Numbered: (& [number]: Int) Number: Int Number.[number]: Int = [.this] [main]: Int = { num:Number = 5 ifa:Numbered = num ifa.[number] } `) } func TestInterfaceWriter (test *testing.T) { testString (test, `%"0zNZN147MN2wzMAQ6NS2dQ==::File" = type i32 %"0zNZN147MN2wzMAQ6NS2dQ==::Writer" = type { ptr, ptr } %"AAAAAAAAAAAAAAAAAAAAAA==::Index" = type i64 %"AAAAAAAAAAAAAAAAAAAAAA==::Byte" = type i8 define i64 @main() { 0: %1 = alloca %"0zNZN147MN2wzMAQ6NS2dQ==::File" store i32 0, ptr %1 %2 = alloca %"0zNZN147MN2wzMAQ6NS2dQ==::Writer" %3 = getelementptr %"0zNZN147MN2wzMAQ6NS2dQ==::Writer", ptr %2, i32 0, i32 0 store ptr %1, ptr %3 %4 = getelementptr %"0zNZN147MN2wzMAQ6NS2dQ==::Writer", ptr %2, i32 0, i32 1 store ptr @"0zNZN147MN2wzMAQ6NS2dQ==::File.write", ptr %4 %5 = load %"0zNZN147MN2wzMAQ6NS2dQ==::Writer", ptr %2 call void @"0zNZN147MN2wzMAQ6NS2dQ==::sayHello"(%"0zNZN147MN2wzMAQ6NS2dQ==::Writer" %5) ret i64 0 } define void @"0zNZN147MN2wzMAQ6NS2dQ==::sayHello"(%"0zNZN147MN2wzMAQ6NS2dQ==::Writer" %writer) { 0: %1 = alloca %"0zNZN147MN2wzMAQ6NS2dQ==::Writer" store %"0zNZN147MN2wzMAQ6NS2dQ==::Writer" %writer, ptr %1 %2 = alloca { ptr, %"AAAAAAAAAAAAAAAAAAAAAA==::Index" } %3 = alloca [17 x %"AAAAAAAAAAAAAAAAAAAAAA==::Byte"] %4 = getelementptr [17 x %"AAAAAAAAAAAAAAAAAAAAAA==::Byte"], ptr %3, i32 0, i32 0 store i8 119, ptr %4 %5 = getelementptr [17 x %"AAAAAAAAAAAAAAAAAAAAAA==::Byte"], ptr %3, i32 0, i32 1 store i8 101, ptr %5 %6 = getelementptr [17 x %"AAAAAAAAAAAAAAAAAAAAAA==::Byte"], ptr %3, i32 0, i32 2 store i8 108, ptr %6 %7 = getelementptr [17 x %"AAAAAAAAAAAAAAAAAAAAAA==::Byte"], ptr %3, i32 0, i32 3 store i8 108, ptr %7 %8 = getelementptr [17 x %"AAAAAAAAAAAAAAAAAAAAAA==::Byte"], ptr %3, i32 0, i32 4 store i8 32, ptr %8 %9 = getelementptr [17 x %"AAAAAAAAAAAAAAAAAAAAAA==::Byte"], ptr %3, i32 0, i32 5 store i8 104, ptr %9 %10 = getelementptr [17 x %"AAAAAAAAAAAAAAAAAAAAAA==::Byte"], ptr %3, i32 0, i32 6 store i8 101, ptr %10 %11 = getelementptr [17 x %"AAAAAAAAAAAAAAAAAAAAAA==::Byte"], ptr %3, i32 0, i32 7 store i8 108, ptr %11 %12 = getelementptr [17 x %"AAAAAAAAAAAAAAAAAAAAAA==::Byte"], ptr %3, i32 0, i32 8 store i8 108, ptr %12 %13 = getelementptr [17 x %"AAAAAAAAAAAAAAAAAAAAAA==::Byte"], ptr %3, i32 0, i32 9 store i8 111, ptr %13 %14 = getelementptr [17 x %"AAAAAAAAAAAAAAAAAAAAAA==::Byte"], ptr %3, i32 0, i32 10 store i8 32, ptr %14 %15 = getelementptr [17 x %"AAAAAAAAAAAAAAAAAAAAAA==::Byte"], ptr %3, i32 0, i32 11 store i8 116, ptr %15 %16 = getelementptr [17 x %"AAAAAAAAAAAAAAAAAAAAAA==::Byte"], ptr %3, i32 0, i32 12 store i8 104, ptr %16 %17 = getelementptr [17 x %"AAAAAAAAAAAAAAAAAAAAAA==::Byte"], ptr %3, i32 0, i32 13 store i8 101, ptr %17 %18 = getelementptr [17 x %"AAAAAAAAAAAAAAAAAAAAAA==::Byte"], ptr %3, i32 0, i32 14 store i8 105, ptr %18 %19 = getelementptr [17 x %"AAAAAAAAAAAAAAAAAAAAAA==::Byte"], ptr %3, i32 0, i32 15 store i8 114, ptr %19 %20 = getelementptr [17 x %"AAAAAAAAAAAAAAAAAAAAAA==::Byte"], ptr %3, i32 0, i32 16 store i8 10, ptr %20 %21 = getelementptr { ptr, %"AAAAAAAAAAAAAAAAAAAAAA==::Index" }, ptr %2, i32 0, i32 0 store ptr %3, ptr %21 %22 = getelementptr { ptr, %"AAAAAAAAAAAAAAAAAAAAAA==::Index" }, ptr %2, i32 0, i32 1 store %"AAAAAAAAAAAAAAAAAAAAAA==::Index" 17, ptr %22 %23 = load { ptr, %"AAAAAAAAAAAAAAAAAAAAAA==::Index" }, ptr %2 %24 = getelementptr %"0zNZN147MN2wzMAQ6NS2dQ==::Writer", ptr %1, i32 0, i32 1 %25 = getelementptr %"0zNZN147MN2wzMAQ6NS2dQ==::Writer", ptr %1, i32 0, i32 0 %26 = load ptr, ptr %25 %27 = load ptr, ptr %24 %28 = call %"AAAAAAAAAAAAAAAAAAAAAA==::Index" %27(ptr %26, { ptr, %"AAAAAAAAAAAAAAAAAAAAAA==::Index" } %23) ret void } define %"AAAAAAAAAAAAAAAAAAAAAA==::Index" @"0zNZN147MN2wzMAQ6NS2dQ==::File.write"(ptr %this, { ptr, %"AAAAAAAAAAAAAAAAAAAAAA==::Index" } %buffer) { 0: %1 = alloca ptr store ptr %this, ptr %1 %2 = alloca { ptr, %"AAAAAAAAAAAAAAAAAAAAAA==::Index" } store { ptr, %"AAAAAAAAAAAAAAAAAAAAAA==::Index" } %buffer, ptr %2 %3 = load ptr, ptr %1 %4 = load %"0zNZN147MN2wzMAQ6NS2dQ==::File", ptr %3 %5 = getelementptr { ptr, %"AAAAAAAAAAAAAAAAAAAAAA==::Index" }, ptr %2, i32 0, i32 0 %6 = load ptr, ptr %5 %7 = getelementptr { ptr, %"AAAAAAAAAAAAAAAAAAAAAA==::Index" }, ptr %2, i32 0, i32 1 %8 = load %"AAAAAAAAAAAAAAAAAAAAAA==::Index", ptr %7 %9 = call %"AAAAAAAAAAAAAAAAAAAAAA==::Index" @"0zNZN147MN2wzMAQ6NS2dQ==::write"(%"0zNZN147MN2wzMAQ6NS2dQ==::File" %4, ptr %6, %"AAAAAAAAAAAAAAAAAAAAAA==::Index" %8) ret %"AAAAAAAAAAAAAAAAAAAAAA==::Index" %9 } declare %"AAAAAAAAAAAAAAAAAAAAAA==::Index" @"0zNZN147MN2wzMAQ6NS2dQ==::write"(%"0zNZN147MN2wzMAQ6NS2dQ==::File" %fd, ptr %buffer, %"AAAAAAAAAAAAAAAAAAAAAA==::Index" %count) `, ` [write fd:File buffer:*Byte count:Index]: Index Writer: (& [write buffer:*:Byte]: Index) File: I32 File.[write buffer:*:Byte]:Index = [write [.this] [~*Byte buffer] [#buffer]] [sayHello writer:Writer] = writer.[write 'well hello their\n'] [main]:Int 'main' = { stdout:File = 0 [sayHello stdout] 0 } `) } func TestInterfaceInStruct (test *testing.T) { testString (test, `%"0zNZN147MN2wzMAQ6NS2dQ==::Writer" = type { ptr, ptr } %"0zNZN147MN2wzMAQ6NS2dQ==::A" = type { %"0zNZN147MN2wzMAQ6NS2dQ==::Writer" } %"0zNZN147MN2wzMAQ6NS2dQ==::File" = type i32 %"AAAAAAAAAAAAAAAAAAAAAA==::Index" = type i64 define void @main() { 0: %1 = alloca %"0zNZN147MN2wzMAQ6NS2dQ==::A" %2 = getelementptr %"0zNZN147MN2wzMAQ6NS2dQ==::A", ptr %1, i32 0, i32 0 %3 = getelementptr %"0zNZN147MN2wzMAQ6NS2dQ==::Writer", ptr %2, i32 0, i32 0 %4 = alloca i32 store i32 0, ptr %4 store ptr %4, ptr %3 %5 = getelementptr %"0zNZN147MN2wzMAQ6NS2dQ==::Writer", ptr %2, i32 0, i32 1 store ptr @"0zNZN147MN2wzMAQ6NS2dQ==::File.write", ptr %5 ret void } declare %"AAAAAAAAAAAAAAAAAAAAAA==::Index" @"0zNZN147MN2wzMAQ6NS2dQ==::File.write"(ptr %this, { ptr, %"AAAAAAAAAAAAAAAAAAAAAA==::Index" } %buffer) `, ` Writer: (& [write buffer:*:Byte]: Index) A: (. output: Writer) File: I32 File.[write buffer:*:Byte]:Index [main] 'main' = { a:A = (. output: [~File 0]) } `) } func TestInterfaceAssignment (test *testing.T) { testString (test, `%"0zNZN147MN2wzMAQ6NS2dQ==::Face" = type { ptr, ptr } %"0zNZN147MN2wzMAQ6NS2dQ==::Impl" = type i64 define void @main() { 0: %1 = alloca %"0zNZN147MN2wzMAQ6NS2dQ==::Face" %2 = getelementptr %"0zNZN147MN2wzMAQ6NS2dQ==::Face", ptr %1, i32 0, i32 0 %3 = alloca %"0zNZN147MN2wzMAQ6NS2dQ==::Impl" store ptr %3, ptr %2 %4 = getelementptr %"0zNZN147MN2wzMAQ6NS2dQ==::Face", ptr %1, i32 0, i32 1 store ptr @"0zNZN147MN2wzMAQ6NS2dQ==::Impl.x", ptr %4 ret void } define i64 @"0zNZN147MN2wzMAQ6NS2dQ==::Impl.x"(ptr %this) { 0: %1 = alloca ptr store ptr %this, ptr %1 ret i64 5 } `, ` Face: (& [x]:Int) Impl: Int Impl.[x]:Int = 5 [main] 'main' = { i:Face = f:Impl } `) }