forked from gorgonia/cu
/
templates.go
134 lines (114 loc) · 3.62 KB
/
templates.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package main
import "text/template"
var alphaTemplateRaw = `{{$lso := .LSO -}}
var {{range $i, $p := .Params }}{{$p}}C {{if lt $i $lso}},{{end}} {{end }} unsafe.Pointer
switch {{.Check}}.dataType {
case Float, Half:
var {{range $i, $p := .Params }}{{$p}}F{{if lt $i $lso}},{{end }} {{end }} C.float
{{range .Params -}}
{{.}}F = C.float(float32({{.}}))
{{end -}}
{{range .Params -}}
{{.}}C = unsafe.Pointer(&{{.}}F)
{{end -}}
case Double:
var {{range $i, $p := .Params }}{{$p}}F{{if lt $i $lso}},{{end }} {{end }} C.double
{{range .Params -}}
{{.}}F = C.double({{.}})
{{end -}}
{{range .Params -}}
{{.}}C = unsafe.Pointer(&{{.}}F)
{{end -}}
default:
{{if .MultiReturn -}}
err = errors.Errorf("Unsupported data type: %v", {{.Check}}.dataType)
return
{{else -}}
return errors.Errorf("Unsupported data type: %v", {{.Check}}.dataType)
{{end -}}
}
`
type AlphaBeta struct {
Params []string // parameters that are alpha/beta
Check string // what to check
LSO int // length of params -1
MultiReturn bool
}
var callTemplateRaw = `// call {{.CFuncName}}
{{if .MultiReturn -}} err = result(C.{{.CFuncName}}({{range $i, $v := .Params}}{{if $v.IsPtr}}&{{end}}{{toC $v.Name $v.Type -}}, {{end -}}))
{{else -}}return result(C.{{.CFuncName}}({{range $i, $v := .Params}}{{toC $v.Name $v.Type -}}, {{end -}})) {{end -}}
`
type Call struct {
Params []Param
CFuncName string
MultiReturn bool
}
type Con struct {
Ctype string
GoType string
Create string
Set []string
Destroy string
Params []string
ParamType []string
TODO string // TODO represents a part where human intervention is required
}
var constructStructRaw = `// {{.GoType}} is a representation of {{.Ctype}}.
type {{.GoType}} struct {
internal C.{{.Ctype}}
{{$l := len .Set}}
{{if gt $l 1}} //TODO
{{else -}}
{{$pt := .ParamType}}
{{range $i, $v := .Params -}}
{{unexport $v}} {{index $pt $i}}
{{end -}}
{{end -}}
}
`
var constructionRaw = `var internal C.{{.Ctype}}
if err := result(C.{{.Create}}(&internal)); err != nil {
return nil, err
}
{{if ne .TODO ""}}// TODO: {{.TODO}}{{end}}
{{$pt := .ParamType}}
if err := result(C.{{index .Set 0}}(internal, {{range $i, $v := .Params -}}{{$t := index $pt $i -}}{{toC $v $t -}},{{end -}})); err != nil {
return nil, err
}
retVal = &{{.GoType}} {
internal: internal,
{{range .Params -}}
{{.}}: {{.}},
{{end -}}
}
runtime.SetFinalizer(retVal, destroy{{.GoType}})
return retVal, nil
`
var constructionTODORaw = `// available "Set" methods:
{{range .Set -}}
// {{.}}
{{end -}}
return nil, errors.Errorf("TODO: Manual Intervention required")
`
var destructRaw = `C.{{.Destroy}}(obj.internal)`
var (
alphaTemplate *template.Template
callTemplate *template.Template
constructionTemplate *template.Template
constructionTODOTemplate *template.Template
constructStructTemplate *template.Template
destructTemplate *template.Template
)
var funcs = template.FuncMap{
"isBuiltin": isBuiltin,
"unexport": unexport,
"toC": toC,
}
func init() {
alphaTemplate = template.Must(template.New("alpha").Parse(alphaTemplateRaw))
callTemplate = template.Must(template.New("call").Funcs(funcs).Parse(callTemplateRaw))
constructionTemplate = template.Must(template.New("cons").Funcs(funcs).Parse(constructionRaw))
constructionTODOTemplate = template.Must(template.New("cons").Funcs(funcs).Parse(constructionTODORaw))
constructStructTemplate = template.Must(template.New("cons2").Funcs(funcs).Parse(constructStructRaw))
destructTemplate = template.Must(template.New("Destroy").Funcs(funcs).Parse(destructRaw))
}