diff --git a/generator/expression-loc.go b/generator/expression-loc.go index 72278d8..717fa2a 100644 --- a/generator/expression-loc.go +++ b/generator/expression-loc.go @@ -102,7 +102,7 @@ func (this *generator) generateSubscriptLoc (subscript *entity.Subscript) (llvm. sourceType := analyzer.ReduceToBase(subscript.Slice.Type()) switch sourceType := sourceType.(type) { case *entity.TypeSlice: - irSourceType, err := this.generateType(sourceType) + irSourceType, err := this.generateType(subscript.Slice.Type()) if err != nil { return nil, err } elementType = sourceType.Element dataAddress = this.getSliceDataAddress(source, irSourceType) @@ -134,10 +134,9 @@ func (this *generator) generateMemberAccessLoc (access *entity.MemberAccess) (ll source, err := this.generateExpressionLoc(access.Source) if err != nil { return nil, err } - switch sourceTypeAny := analyzer.ReduceToBase(access.Source.Type()).(type) { + switch sourceType := analyzer.ReduceToBase(access.Source.Type()).(type) { case *entity.TypeStruct: - sourceType := sourceTypeAny - irSourceType, err := this.generateType(sourceType) + irSourceType, err := this.generateType(access.Source.Type()) if err != nil { return nil, err } offset := this.getStructMemberIndex(sourceType, access.Member) return this.blockManager.NewGetElementPtr ( @@ -147,10 +146,10 @@ func (this *generator) generateMemberAccessLoc (access *entity.MemberAccess) (ll llvm.NewConstInt(llvm.I32, int64(offset))), nil case *entity.TypePointer: - sourceType := analyzer.ReduceToBase(sourceTypeAny.Referenced).(*entity.TypeStruct) - irSourceType, err := this.generateType(sourceType) + irSourceType, err := this.generateType(sourceType.Referenced) if err != nil { return nil, err } - offset := this.getStructMemberIndex(sourceType, access.Member) + referencedSourceType := analyzer.ReduceToBase(sourceType.Referenced).(*entity.TypeStruct) + offset := this.getStructMemberIndex(referencedSourceType, access.Member) source = this.blockManager.NewLoad(new(llvm.TypePointer), source) return this.blockManager.NewGetElementPtr ( irSourceType, diff --git a/generator/function_test.go b/generator/function_test.go index 0ab7e6d..c9602f3 100644 --- a/generator/function_test.go +++ b/generator/function_test.go @@ -112,7 +112,7 @@ testString (test, %Greeter = type { %String } define void @main() { 0: - %1 = alloca { %String } + %1 = alloca %Greeter %2 = alloca [6 x i8] %3 = getelementptr [6 x i8], ptr %2, i32 0, i32 0 store i8 104, ptr %3 @@ -126,13 +126,13 @@ define void @main() { store i8 111, ptr %7 %8 = getelementptr [6 x i8], ptr %2, i32 0, i32 5 store i8 0, ptr %8 - %9 = alloca { ptr, %Index } - %10 = getelementptr { ptr, %Index }, ptr %9, i32 0, i32 0 + %9 = alloca %String + %10 = getelementptr %String, ptr %9, i32 0, i32 0 store ptr %2, ptr %10 - %11 = getelementptr { ptr, %Index }, ptr %9, i32 0, i32 1 + %11 = getelementptr %String, ptr %9, i32 0, i32 1 store %Index 6, ptr %11 %12 = load %String, ptr %9 - %13 = getelementptr { %String }, ptr %1, i32 0, i32 0 + %13 = getelementptr %Greeter, ptr %1, i32 0, i32 0 store %String %12, ptr %13 %14 = load %Greeter, ptr %1 %15 = alloca %Greeter @@ -145,8 +145,8 @@ define void @Greeter.greet(ptr %this) { %1 = alloca ptr store ptr %this, ptr %1 %2 = load ptr, ptr %1 - %3 = getelementptr { %String }, ptr %2, i32 0, i32 0 - %4 = getelementptr { ptr, %Index }, ptr %3, i32 0, i32 0 + %3 = getelementptr %Greeter, ptr %2, i32 0, i32 0 + %4 = getelementptr %String, ptr %3, i32 0, i32 0 %5 = load ptr, ptr %4 %6 = getelementptr i8, ptr %5, i64 0 %7 = call %Index @puts(ptr %6) diff --git a/generator/interface_test.go b/generator/interface_test.go index 9571d94..29387ba 100644 --- a/generator/interface_test.go +++ b/generator/interface_test.go @@ -191,3 +191,22 @@ File.[write buffer:*:Byte]:Index = [write [.this] [~*Byte buffer] [#buffer]] } `) } + +func TestInterfaceInStruct (test *testing.T) { +testString (test, +``, +` +Writer: ([write buffer:*:Byte]: Index) +A: (output: Writer) + +File: I32 +File.[write buffer:*:Byte]:Index = [write [.this] [~*Byte buffer] [#buffer]] +[write fd:File buffer:*Byte count:Index]: Index + +[main] 'main' = { + a:A = (output: [~File 0]) + output: Writer = a.output + output.[write '!'] +} +`) +} diff --git a/generator/literal.go b/generator/literal.go index 4bd9386..27501be 100644 --- a/generator/literal.go +++ b/generator/literal.go @@ -168,7 +168,7 @@ func (this *generator) generateLiteralStringLoc (literal *entity.LiteralString) switch base := base.(type) { case *entity.TypeInt: var value llvm.Value - irType, err := this.generateType(base) + irType, err := this.generateType(literal.Type()) if err != nil { return nil, err } switch { case base.Width >= 32: @@ -189,7 +189,7 @@ func (this *generator) generateLiteralStringLoc (literal *entity.LiteralString) case *entity.TypeSlice: array, length, err := makeData(base.Element, false) if err != nil { return nil, err } - return this.generateSliceDefinedLength(base, array, length) + return this.generateSliceDefinedLength(literal.Type(), array, length) case *entity.TypePointer: array, _, err := makeData(base.Referenced, true) diff --git a/generator/literal_test.go b/generator/literal_test.go index bb902d4..818adfe 100644 --- a/generator/literal_test.go +++ b/generator/literal_test.go @@ -18,12 +18,12 @@ define void @main() { store i8 128, ptr %3 %4 = alloca i8 store i8 -127, ptr %4 - %5 = alloca i8 + %5 = alloca %Byte store i8 104, ptr %5 %6 = load %Byte, ptr %5 %7 = alloca %Byte store %Byte %6, ptr %7 - %8 = alloca i32 + %8 = alloca %Rune store i32 48, ptr %8 %9 = load %Rune, ptr %8 %10 = alloca %Rune @@ -79,10 +79,10 @@ define void @main() { store i8 108, ptr %37 %38 = getelementptr [11 x i8], ptr %27, i32 0, i32 10 store i8 100, ptr %38 - %39 = alloca { ptr, %Index } - %40 = getelementptr { ptr, %Index }, ptr %39, i32 0, i32 0 + %39 = alloca %String + %40 = getelementptr %String, ptr %39, i32 0, i32 0 store ptr %27, ptr %40 - %41 = getelementptr { ptr, %Index }, ptr %39, i32 0, i32 1 + %41 = getelementptr %String, ptr %39, i32 0, i32 1 store %Index 11, ptr %41 %42 = load %String, ptr %39 %43 = alloca %String @@ -192,3 +192,100 @@ define void @main() { } `) } + +func TestTypedStructInstantiation (test *testing.T) { +testString (test, +`%A = type { i64 } +define void @main() { +0: + %1 = alloca %A + %2 = getelementptr %A, ptr %1, i32 0, i32 0 + store i64 5, ptr %2 + %3 = load %A, ptr %1 + %4 = alloca %A + store %A %3, ptr %4 + ret void +} +`, +` +A: (x:Int) +[main] 'main' = { + a:A = (x: 5) +} +`) +} + +func TestTypedArrayInstantiation (test *testing.T) { +testString (test, +`%A = type [2 x i64] +define void @main() { +0: + %1 = alloca %A + %2 = getelementptr %A, ptr %1, i32 0, i32 0 + store i64 1, ptr %2 + %3 = getelementptr %A, ptr %1, i32 0, i32 1 + store i64 2, ptr %3 + %4 = load %A, ptr %1 + %5 = alloca %A + store %A %4, ptr %5 + ret void +} +`, +` +A: 2:Int +[main] 'main' = { + a:A = (* 1 2) +} +`) +} + +func TestTypedStringInstantiation (test *testing.T) { +testString (test, +`%Byte = type i8 +%A = type [1 x %Byte] +%Index = type i64 +%B = type { ptr, %Index } +%C = type ptr +define void @main() { +0: + %1 = alloca [1 x i8] + %2 = getelementptr [1 x i8], ptr %1, i32 0, i32 0 + store i8 104, ptr %2 + %3 = load %A, ptr %1 + %4 = alloca %A + store %A %3, ptr %4 + %5 = alloca [1 x i8] + %6 = getelementptr [1 x i8], ptr %5, i32 0, i32 0 + store i8 104, ptr %6 + %7 = alloca %B + %8 = getelementptr %B, ptr %7, i32 0, i32 0 + store ptr %5, ptr %8 + %9 = getelementptr %B, ptr %7, i32 0, i32 1 + store %Index 1, ptr %9 + %10 = load %B, ptr %7 + %11 = alloca %B + store %B %10, ptr %11 + %12 = alloca [2 x i8] + %13 = getelementptr [2 x i8], ptr %12, i32 0, i32 0 + store i8 104, ptr %13 + %14 = getelementptr [2 x i8], ptr %12, i32 0, i32 1 + store i8 0, ptr %14 + %15 = alloca ptr + store ptr %12, ptr %15 + %16 = load %C, ptr %15 + %17 = alloca %C + store %C %16, ptr %17 + ret void +} +`, +` +A: 1:Byte +B: *:Byte +C: *Byte +[main] 'main' = { + a:A = 'h' + b:B = 'h' + c:C = 'h' +} +`) +} diff --git a/generator/misc_test.go b/generator/misc_test.go index b67935f..9078ded 100644 --- a/generator/misc_test.go +++ b/generator/misc_test.go @@ -11,7 +11,7 @@ define void @printDigit(%Byte %digit) { %1 = alloca %Byte store %Byte %digit, ptr %1 %2 = load %Byte, ptr %1 - %3 = alloca i8 + %3 = alloca %Byte store i8 48, ptr %3 %4 = load %Byte, ptr %3 %5 = add %Byte %2, %4 diff --git a/generator/type_test.go b/generator/type_test.go index d0f5abf..a0117ce 100644 --- a/generator/type_test.go +++ b/generator/type_test.go @@ -115,7 +115,7 @@ testString (test, define void @main() { 0: %1 = alloca %B - %2 = getelementptr { i64 }, ptr %1, i32 0, i32 0 + %2 = getelementptr %B, ptr %1, i32 0, i32 0 store i64 5, ptr %2 ret void }