Skip to content

Commit c99bad6

Browse files
committed
build: instantiate generics
1 parent e35d70f commit c99bad6

File tree

13 files changed

+652
-9
lines changed

13 files changed

+652
-9
lines changed

cl/_testgo/tpindex/in.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package main
2+
3+
// The index function returns the index of the first occurrence of v in s,
4+
// or -1 if not present.
5+
func index[E comparable](s []E, v E) int {
6+
for i, vs := range s {
7+
if v == vs {
8+
return i
9+
}
10+
}
11+
return -1
12+
}
13+
14+
func main() {
15+
s := []int{1, 3, 5, 2, 4}
16+
println(index(s, 3))
17+
println(index(s, 6))
18+
}

cl/_testgo/tpindex/out.ll

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
; ModuleID = 'main'
2+
source_filename = "main"
3+
4+
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
5+
6+
@"main.init$guard" = global i1 false, align 1
7+
@__llgo_argc = global i32 0, align 4
8+
@__llgo_argv = global ptr null, align 8
9+
10+
define void @main.init() {
11+
_llgo_0:
12+
%0 = load i1, ptr @"main.init$guard", align 1
13+
br i1 %0, label %_llgo_2, label %_llgo_1
14+
15+
_llgo_1: ; preds = %_llgo_0
16+
store i1 true, ptr @"main.init$guard", align 1
17+
br label %_llgo_2
18+
19+
_llgo_2: ; preds = %_llgo_1, %_llgo_0
20+
ret void
21+
}
22+
23+
define i32 @main(i32 %0, ptr %1) {
24+
_llgo_0:
25+
store i32 %0, ptr @__llgo_argc, align 4
26+
store ptr %1, ptr @__llgo_argv, align 8
27+
call void @"github.com/goplus/llgo/internal/runtime.init"()
28+
call void @main.init()
29+
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 40)
30+
%3 = getelementptr inbounds i64, ptr %2, i64 0
31+
store i64 1, ptr %3, align 4
32+
%4 = getelementptr inbounds i64, ptr %2, i64 1
33+
store i64 3, ptr %4, align 4
34+
%5 = getelementptr inbounds i64, ptr %2, i64 2
35+
store i64 5, ptr %5, align 4
36+
%6 = getelementptr inbounds i64, ptr %2, i64 3
37+
store i64 2, ptr %6, align 4
38+
%7 = getelementptr inbounds i64, ptr %2, i64 4
39+
store i64 4, ptr %7, align 4
40+
%8 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
41+
%9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %8, i32 0, i32 0
42+
store ptr %2, ptr %9, align 8
43+
%10 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %8, i32 0, i32 1
44+
store i64 5, ptr %10, align 4
45+
%11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %8, i32 0, i32 2
46+
store i64 5, ptr %11, align 4
47+
%12 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %8, align 8
48+
%13 = call i64 @"main.index[int]"(%"github.com/goplus/llgo/internal/runtime.Slice" %12, i64 3)
49+
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %13)
50+
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
51+
%14 = call i64 @"main.index[int]"(%"github.com/goplus/llgo/internal/runtime.Slice" %12, i64 6)
52+
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %14)
53+
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
54+
ret i32 0
55+
}
56+
57+
declare void @"github.com/goplus/llgo/internal/runtime.init"()
58+
59+
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
60+
61+
define i64 @"main.index[int]"(%"github.com/goplus/llgo/internal/runtime.Slice" %0, i64 %1) {
62+
_llgo_0:
63+
%2 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1
64+
br label %_llgo_1
65+
66+
_llgo_1: ; preds = %_llgo_2, %_llgo_0
67+
%3 = phi i64 [ -1, %_llgo_0 ], [ %4, %_llgo_2 ]
68+
%4 = add i64 %3, 1
69+
%5 = icmp slt i64 %4, %2
70+
br i1 %5, label %_llgo_2, label %_llgo_3
71+
72+
_llgo_2: ; preds = %_llgo_1
73+
%6 = icmp slt i64 %4, 0
74+
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %6)
75+
%7 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0
76+
%8 = getelementptr inbounds i64, ptr %7, i64 %4
77+
%9 = load i64, ptr %8, align 4
78+
%10 = icmp eq i64 %1, %9
79+
br i1 %10, label %_llgo_4, label %_llgo_1
80+
81+
_llgo_3: ; preds = %_llgo_1
82+
ret i64 -1
83+
84+
_llgo_4: ; preds = %_llgo_2
85+
ret i64 %4
86+
}
87+
88+
declare void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64)
89+
90+
declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8)
91+
92+
declare void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1)

cl/_testgo/tprecur/in.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package main
2+
3+
func main() {
4+
recursive()
5+
}
6+
7+
func recursive() {
8+
type T int
9+
if got, want := recur1[T](5), T(110); got != want {
10+
panic("error")
11+
}
12+
}
13+
14+
type Integer interface {
15+
~int | ~int32 | ~int64
16+
}
17+
18+
func recur1[T Integer](n T) T {
19+
if n == 0 || n == 1 {
20+
return T(1)
21+
} else {
22+
return n * recur2(n-1)
23+
}
24+
}
25+
26+
func recur2[T Integer](n T) T {
27+
list := make([]T, n)
28+
for i, _ := range list {
29+
list[i] = T(i + 1)
30+
}
31+
var sum T
32+
for _, elt := range list {
33+
sum += elt
34+
}
35+
return sum + recur1(n-1)
36+
}

cl/_testgo/tprecur/out.ll

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
; ModuleID = 'main'
2+
source_filename = "main"
3+
4+
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
5+
%"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr }
6+
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
7+
8+
@"main.init$guard" = global i1 false, align 1
9+
@__llgo_argc = global i32 0, align 4
10+
@__llgo_argv = global ptr null, align 8
11+
@0 = private unnamed_addr constant [5 x i8] c"error", align 1
12+
@_llgo_string = linkonce global ptr null, align 8
13+
14+
define void @main.init() {
15+
_llgo_0:
16+
%0 = load i1, ptr @"main.init$guard", align 1
17+
br i1 %0, label %_llgo_2, label %_llgo_1
18+
19+
_llgo_1: ; preds = %_llgo_0
20+
store i1 true, ptr @"main.init$guard", align 1
21+
call void @"main.init$after"()
22+
br label %_llgo_2
23+
24+
_llgo_2: ; preds = %_llgo_1, %_llgo_0
25+
ret void
26+
}
27+
28+
define i32 @main(i32 %0, ptr %1) {
29+
_llgo_0:
30+
store i32 %0, ptr @__llgo_argc, align 4
31+
store ptr %1, ptr @__llgo_argv, align 8
32+
call void @"github.com/goplus/llgo/internal/runtime.init"()
33+
call void @main.init()
34+
call void @main.recursive()
35+
ret i32 0
36+
}
37+
38+
define void @main.recursive() {
39+
_llgo_0:
40+
%0 = call i64 @"main.recur1[main.T]"(i64 5)
41+
%1 = icmp ne i64 %0, 110
42+
br i1 %1, label %_llgo_1, label %_llgo_2
43+
44+
_llgo_1: ; preds = %_llgo_0
45+
%2 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
46+
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 0
47+
store ptr @0, ptr %3, align 8
48+
%4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 1
49+
store i64 5, ptr %4, align 4
50+
%5 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %2, align 8
51+
%6 = load ptr, ptr @_llgo_string, align 8
52+
%7 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16)
53+
store %"github.com/goplus/llgo/internal/runtime.String" %5, ptr %7, align 8
54+
%8 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
55+
%9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %8, i32 0, i32 0
56+
store ptr %6, ptr %9, align 8
57+
%10 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %8, i32 0, i32 1
58+
store ptr %7, ptr %10, align 8
59+
%11 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %8, align 8
60+
call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %11)
61+
unreachable
62+
63+
_llgo_2: ; preds = %_llgo_0
64+
ret void
65+
}
66+
67+
declare void @"github.com/goplus/llgo/internal/runtime.init"()
68+
69+
define i64 @"main.recur1[main.T]"(i64 %0) {
70+
_llgo_0:
71+
%1 = icmp eq i64 %0, 0
72+
br i1 %1, label %_llgo_1, label %_llgo_3
73+
74+
_llgo_1: ; preds = %_llgo_3, %_llgo_0
75+
ret i64 1
76+
77+
_llgo_2: ; preds = %_llgo_3
78+
%2 = sub i64 %0, 1
79+
%3 = call i64 @"main.recur2[main.T]"(i64 %2)
80+
%4 = mul i64 %0, %3
81+
ret i64 %4
82+
83+
_llgo_3: ; preds = %_llgo_0
84+
%5 = icmp eq i64 %0, 1
85+
br i1 %5, label %_llgo_1, label %_llgo_2
86+
}
87+
88+
define void @"main.init$after"() {
89+
_llgo_0:
90+
%0 = load ptr, ptr @_llgo_string, align 8
91+
%1 = icmp eq ptr %0, null
92+
br i1 %1, label %_llgo_1, label %_llgo_2
93+
94+
_llgo_1: ; preds = %_llgo_0
95+
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 24)
96+
store ptr %2, ptr @_llgo_string, align 8
97+
br label %_llgo_2
98+
99+
_llgo_2: ; preds = %_llgo_1, %_llgo_0
100+
ret void
101+
}
102+
103+
declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64)
104+
105+
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64)
106+
107+
declare void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface")
108+
109+
define i64 @"main.recur2[main.T]"(i64 %0) {
110+
_llgo_0:
111+
%1 = mul i64 %0, 8
112+
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 %1)
113+
%3 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
114+
%4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %3, i32 0, i32 0
115+
store ptr %2, ptr %4, align 8
116+
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %3, i32 0, i32 1
117+
store i64 %0, ptr %5, align 4
118+
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %3, i32 0, i32 2
119+
store i64 %0, ptr %6, align 4
120+
%7 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %3, align 8
121+
%8 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 1
122+
br label %_llgo_1
123+
124+
_llgo_1: ; preds = %_llgo_2, %_llgo_0
125+
%9 = phi i64 [ -1, %_llgo_0 ], [ %10, %_llgo_2 ]
126+
%10 = add i64 %9, 1
127+
%11 = icmp slt i64 %10, %8
128+
br i1 %11, label %_llgo_2, label %_llgo_3
129+
130+
_llgo_2: ; preds = %_llgo_1
131+
%12 = add i64 %10, 1
132+
%13 = icmp slt i64 %10, 0
133+
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %13)
134+
%14 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
135+
%15 = getelementptr inbounds i64, ptr %14, i64 %10
136+
store i64 %12, ptr %15, align 4
137+
br label %_llgo_1
138+
139+
_llgo_3: ; preds = %_llgo_1
140+
%16 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 1
141+
br label %_llgo_4
142+
143+
_llgo_4: ; preds = %_llgo_5, %_llgo_3
144+
%17 = phi i64 [ 0, %_llgo_3 ], [ %25, %_llgo_5 ]
145+
%18 = phi i64 [ -1, %_llgo_3 ], [ %19, %_llgo_5 ]
146+
%19 = add i64 %18, 1
147+
%20 = icmp slt i64 %19, %16
148+
br i1 %20, label %_llgo_5, label %_llgo_6
149+
150+
_llgo_5: ; preds = %_llgo_4
151+
%21 = icmp slt i64 %19, 0
152+
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %21)
153+
%22 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
154+
%23 = getelementptr inbounds i64, ptr %22, i64 %19
155+
%24 = load i64, ptr %23, align 4
156+
%25 = add i64 %17, %24
157+
br label %_llgo_4
158+
159+
_llgo_6: ; preds = %_llgo_4
160+
%26 = sub i64 %0, 1
161+
%27 = call i64 @"main.recur1[main.T]"(i64 %26)
162+
%28 = add i64 %17, %27
163+
ret i64 %28
164+
}
165+
166+
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
167+
168+
declare void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1)

cl/_testgo/tptypes/in.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package main
2+
3+
type Data[T any] struct {
4+
v T
5+
}
6+
7+
func (p *Data[T]) Set(v T) {
8+
p.v = v
9+
}
10+
11+
func (p *(Data[T1])) Set2(v T1) {
12+
p.v = v
13+
}
14+
15+
type sliceOf[E any] interface {
16+
~[]E
17+
}
18+
19+
type Slice[S sliceOf[T], T any] struct {
20+
Data S
21+
}
22+
23+
func (p *Slice[S, T]) Append(t ...T) S {
24+
p.Data = append(p.Data, t...)
25+
return p.Data
26+
}
27+
28+
func (p *Slice[S1, T1]) Append2(t ...T1) S1 {
29+
p.Data = append(p.Data, t...)
30+
return p.Data
31+
}
32+
33+
type (
34+
DataInt = Data[int]
35+
SliceInt = Slice[[]int, int]
36+
DataString = Data[string]
37+
SliceString = Slice[[]string, string]
38+
)
39+
40+
func main() {
41+
println(DataInt{1}.v)
42+
println(DataString{"hello"}.v)
43+
println(Data[int]{100}.v)
44+
println(Data[string]{"hello"}.v)
45+
46+
// TODO
47+
println(Data[struct {
48+
X int
49+
Y int
50+
}]{}.v.X)
51+
52+
v1 := SliceInt{}
53+
v1.Append(100)
54+
v2 := SliceString{}
55+
v2.Append("hello")
56+
v3 := Slice[[]int, int]{}
57+
v3.Append([]int{1, 2, 3, 4}...)
58+
v3.Append2([]int{1, 2, 3, 4}...)
59+
60+
println(v1.Data, v1.Data[0])
61+
println(v2.Data, v2.Data[0])
62+
println(v3.Data, v3.Data[0])
63+
}

0 commit comments

Comments
 (0)