More using qualified names in IR

This commit is contained in:
Sasha Koshka 2024-01-27 18:16:30 -05:00
parent 2f8b3fcad6
commit 928fef02cd
7 changed files with 138 additions and 23 deletions

View File

@ -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,

View File

@ -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)

View File

@ -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 '!']
}
`)
}

View File

@ -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)

View File

@ -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'
}
`)
}

View File

@ -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

View File

@ -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
}