1
2
3
4
5 package specgen
6
7 import (
8 "fmt"
9 "go/token"
10 "go/types"
11 "simd/archsimd/_gen/specgen/specexpr"
12 "strings"
13 )
14
15
16 type Func struct {
17 Name string
18
19
20 Doc string
21
22
23
24 Commutative bool
25
26
27
28 Category string
29
30
31
32 Recv Arg
33
34 In []Arg
35 Out []Arg
36
37
38 Pos token.Position
39
40
41
42 specFunc *specFunc
43 typeParamVars map[*types.TypeParam]specexpr.Variable
44 instance *specexpr.Bindings
45 }
46
47 type Arg struct {
48 Name string
49 Type specexpr.Type
50 }
51
52 func (f *Func) Signature() string {
53 var buf strings.Builder
54 buf.WriteString("func ")
55 argList := func(args []Arg, canShort bool) {
56 if canShort {
57 if len(args) == 0 {
58 return
59 } else if len(args) == 1 && args[0].Name == "" {
60 buf.WriteString(args[0].Type.String())
61 return
62 }
63 }
64 buf.WriteByte('(')
65 for i, arg := range args {
66 if i > 0 {
67 buf.WriteString(", ")
68 }
69 if arg.Name == "" {
70 panic("empty parameter/result name")
71 }
72 fmt.Fprintf(&buf, "%s %s", arg.Name, arg.Type)
73 }
74 buf.WriteByte(')')
75 }
76 if f.Recv.Type != nil {
77 fmt.Fprintf(&buf, "(%s %s) ", f.Recv.Name, f.Recv.Type)
78 }
79 buf.WriteString(f.Name)
80 argList(f.In, false)
81 if len(f.Out) > 0 {
82 buf.WriteByte(' ')
83 argList(f.Out, true)
84 }
85 return buf.String()
86 }
87
88 func (f *Func) Decl() string {
89 var buf strings.Builder
90 if f.Doc != "" {
91 for line := range strings.SplitSeq(strings.TrimRight(f.Doc, "\n"), "\n") {
92 fmt.Fprintf(&buf, "// %s\n", line)
93 }
94 }
95 buf.WriteString(f.Signature())
96 return buf.String()
97 }
98
99
100
101
102
103 func (f *Func) SpecFunc() (name string, sig *types.Signature, typeArgs []types.Type) {
104 sFn := f.specFunc
105
106
107 for _, tparam := range sFn.TypeParams {
108 val := f.instance.Get(f.typeParamVars[tparam])
109 switch val := val.(type) {
110 case specexpr.Type:
111 typeArgs = append(typeArgs, specTypeToType(sFn.Pkg, val))
112 case specexpr.Num:
113 wt := sFn.Pkg.WidthTypes[val]
114 if wt == nil {
115 panic(fmt.Sprintf("no spec package type for width %s", val))
116 }
117 typeArgs = append(typeArgs, wt)
118 default:
119 panic("unexpected type parameter value")
120 }
121 }
122
123 return sFn.Name, sFn.Sig, typeArgs
124 }
125
View as plain text