Skip to content

Commit bcdaa3e

Browse files
committed
generate: Further iteration on function support
1 parent c8f5646 commit bcdaa3e

File tree

4 files changed

+3953
-694
lines changed

4 files changed

+3953
-694
lines changed

generate/codegen/gen_function.go

Lines changed: 59 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,15 @@ type Function struct {
2828
}
2929

3030
var reservedWords = map[string]bool{
31-
"func": true,
32-
"map": true,
33-
"new": true,
34-
"var": true,
35-
"len": true,
36-
"copy": true,
37-
"range": true,
38-
"type": true,
31+
"func": true,
32+
"map": true,
33+
"new": true,
34+
"var": true,
35+
"len": true,
36+
"copy": true,
37+
"range": true,
38+
"type": true,
39+
"string": true,
3940
}
4041

4142
var typeMap = map[string]string{
@@ -54,13 +55,13 @@ func (f *Function) GoArgs(currentModule *modules.Module) string {
5455
log.Println("rendering function", f.Name, p.Name, p.Type)
5556
log.Printf("rendering function ptype: %T", p.Type)
5657
// if is reserved word, add _ suffix
57-
if _, ok := reservedWords[p.Name]; ok {
58-
p.Name = p.Name + "_"
59-
}
6058
if p.Name == "" {
6159
p.Name = fmt.Sprintf("arg%d", blankArgCounter)
6260
blankArgCounter++
6361
}
62+
if _, ok := reservedWords[p.Name]; ok {
63+
p.Name = p.Name + "_"
64+
}
6465
typ := p.Type.GoName(currentModule, false)
6566
if v, ok := typeMap[typ]; ok {
6667
typ = v
@@ -89,7 +90,16 @@ func (f *Function) CArgs(currentModule *modules.Module) string {
8990
var args []string
9091
for _, p := range f.Parameters {
9192
// log.Printf("rendering cfunction arg: %s %s %T", p.Name, p.Type, p.Type)
92-
args = append(args, fmt.Sprintf("%s %s", p.Type.CName(), p.Name))
93+
typ := p.Type.CName()
94+
if cs, ok := p.Type.(CSignatureer); ok {
95+
typ = cs.CSignature()
96+
}
97+
// check reserved words
98+
if _, ok := reservedWords[p.Name]; ok {
99+
p.Name = p.Name + "_"
100+
}
101+
args = append(args, fmt.Sprintf("%s %s", typ, p.Name))
102+
93103
}
94104
return strings.Join(args, ", ")
95105
}
@@ -138,28 +148,48 @@ func (f *Function) WriteGoCallCode(currentModule *modules.Module, cw *CodeWriter
138148

139149
returnTypeStr := f.GoReturn(currentModule)
140150

141-
callCode := fmt.Sprintf("C.%s(", f.GoName)
151+
callCode := fmt.Sprintf("C.%s(\n", f.GoName)
142152
var sb strings.Builder
143-
for idx, p := range f.Parameters {
153+
for _, p := range f.Parameters {
144154
// cast to C type
145-
switch tt := p.Type.(type) {
155+
sb.WriteString(fmt.Sprintf(cw.IndentStr+" // %T\n", p.Type))
156+
typ := p.Type
157+
switch tt := typ.(type) {
146158
case *typing.AliasType:
147-
sb.WriteString(fmt.Sprintf("C.%s(%s)", tt.CName(), p.GoName()))
159+
sb.WriteString(fmt.Sprintf(cw.IndentStr+" // %T\n", tt.Type))
160+
if _, ok := tt.Type.(*typing.VoidPointerType); ok {
161+
sb.WriteString(cw.IndentStr + fmt.Sprintf(" unsafe.Pointer(%s)", p.GoName()))
162+
} else if _, ok := tt.Type.(*typing.ClassType); ok {
163+
sb.WriteString(cw.IndentStr + fmt.Sprintf(" unsafe.Pointer(%s)", p.GoName()))
164+
} else {
165+
sb.WriteString(cw.IndentStr + fmt.Sprintf("(C.%s)(%s)", tt.CName(), p.GoName()))
166+
}
167+
case *typing.RefType:
168+
sb.WriteString(cw.IndentStr + fmt.Sprintf(" unsafe.Pointer(%s)", p.GoName()))
169+
case *typing.StructType:
170+
sb.WriteString(cw.IndentStr + fmt.Sprintf(" *(*C.%s)(unsafe.Pointer(&%s))", tt.CName(), p.GoName()))
171+
case *typing.PrimitiveType:
172+
sb.WriteString(cw.IndentStr + fmt.Sprintf(" C.%s(%s)", tt.CName(), p.GoName()))
173+
case *typing.PointerType:
174+
sb.WriteString(cw.IndentStr + fmt.Sprintf(" (*C.%s)(unsafe.Pointer(%s))", tt.Type.CName(), p.GoName()))
148175
default:
149-
sb.WriteString(p.GoName())
150-
}
151-
if idx < len(f.Parameters)-1 {
152-
sb.WriteString(", ")
176+
sb.WriteString(cw.IndentStr + p.GoName())
153177
}
178+
sb.WriteString(",\n")
154179
}
155-
callCode += sb.String() + ")"
180+
callCode += sb.String() + cw.IndentStr + ")"
156181

157182
if returnTypeStr == "" {
158183
cw.WriteLine(callCode)
159184
} else {
160185
var resultName = "rv"
161186
cw.WriteLine(resultName + " := " + callCode)
162-
cw.WriteLineF("return %s(%s)", returnTypeStr, resultName)
187+
switch tt := f.ReturnType.(type) {
188+
case *typing.StructType:
189+
cw.WriteLineF("return *(*%s)(unsafe.Pointer(&%s))", tt.GoName(currentModule, true), resultName)
190+
default:
191+
cw.WriteLineF("return %s(%s)", returnTypeStr, resultName)
192+
}
163193
}
164194
cw.UnIndent()
165195
cw.WriteLine("}")
@@ -190,6 +220,9 @@ func (f *Function) WriteObjcWrapper(currentModule *modules.Module, cw *CodeWrite
190220
cw.WriteLine("// deprecated")
191221
}
192222
returnTypeStr := f.Type.ReturnType.CName()
223+
if cs, ok := f.Type.ReturnType.(CSignatureer); ok {
224+
returnTypeStr = cs.CSignature()
225+
}
193226
cw.WriteLineF("%v %v(%v) {", returnTypeStr, f.GoName, f.CArgs(currentModule))
194227
cw.Indent()
195228
var args []string
@@ -201,6 +234,10 @@ func (f *Function) WriteObjcWrapper(currentModule *modules.Module, cw *CodeWrite
201234
cw.WriteLine("}")
202235
}
203236

237+
type CSignatureer interface {
238+
CSignature() string
239+
}
240+
204241
func (f *Function) WriteCSignature(currentModule *modules.Module, cw *CodeWriter) {
205242
var returnTypeStr string
206243
rt := f.Type.ReturnType

generate/typing/pointer_type.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ func (c *PointerType) CName() string {
4444
return c.Type.ObjcName() + "*"
4545
}
4646

47+
func (c *PointerType) CSignature() string {
48+
return c.Type.ObjcName() + "*"
49+
}
50+
4751
func (c *PointerType) DeclareModule() *modules.Module {
4852
return c.Type.DeclareModule()
4953
}

0 commit comments

Comments
 (0)