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