bind: first stab at supporting arrays

This commit is contained in:
Sebastien Binet 2015-07-31 18:01:49 +02:00
parent 63c5bca8e1
commit 94f02af665
5 changed files with 72 additions and 27 deletions

View File

@ -15,8 +15,10 @@ const (
)
var (
Debug = false // Debug switches between debug and prod
Anon = Person{Age: 1, Name: "<nobody>"} // Anon is a default anonymous person
Debug = false // Debug switches between debug and prod
Anon = Person{Age: 1, Name: "<nobody>"} // Anon is a default anonymous person
IntSlice = []int{1, 2} // A slice of ints
IntArray = [2]int{1, 2} // An array of ints
)
// Hi prints hi from Go

View File

@ -850,6 +850,14 @@ func (g *cpyGen) genConst(o Const) {
}
func (g *cpyGen) genVar(v Var) {
ret := qualifiedType(v.GoType())
switch v.GoType().(type) {
case *types.Array, *types.Slice:
g.decl.Printf("/* wrapping %s */\n", v.GoType().String())
g.decl.Printf("typedef void* %s;\n\n", ret)
}
id := g.pkg.Name() + "_" + v.Name()
doc := v.doc
{

View File

@ -276,7 +276,7 @@ func (g *goGen) genStruct(s Struct) {
}
ft := f.Type()
ftname := g.qualifiedType(ft)
ftname := qualifiedType(ft)
if needWrapType(ft) {
ftname = fmt.Sprintf("GoPy_%[1]s_field_%d", s.ID(), i+1)
g.Printf("//export %s\n", ftname)
@ -431,8 +431,15 @@ func (g *goGen) genConst(o Const) {
func (g *goGen) genVar(o Var) {
pkgname := o.pkg.Name()
ret := qualifiedType(o.GoType())
switch o.GoType().(type) {
case *types.Array, *types.Slice:
g.Printf("//export %s\n", ret)
g.Printf("type %s unsafe.Pointer\n\n", ret)
}
g.Printf("//export GoPy_get_%s\n", o.id)
ret := g.qualifiedType(o.GoType())
g.Printf("func GoPy_get_%[1]s() %[2]s {\n", o.id, ret)
g.Indent()
if o.needWrap() {
@ -485,30 +492,8 @@ func (g *goGen) tupleString(tuple []*Var) string {
for _, v := range tuple {
n := v.Name()
typ := v.GoType()
str = append(str, n+" "+g.qualifiedType(typ))
str = append(str, n+" "+qualifiedType(typ))
}
return strings.Join(str, ", ")
}
func (g *goGen) qualifiedType(typ types.Type) string {
switch typ := typ.(type) {
case *types.Basic:
return typ.Name()
case *types.Named:
obj := typ.Obj()
switch typ.Underlying().(type) {
case *types.Struct:
return "GoPy_" + obj.Pkg().Name() + "_" + obj.Name()
case *types.Interface:
if obj.Name() == "error" {
return "error"
}
return "GoPy_" + obj.Name()
default:
return "GoPy_ooops_" + obj.Name()
}
}
return fmt.Sprintf("%#T", typ)
}

View File

@ -31,6 +31,12 @@ func needWrapType(typ types.Type) bool {
case *types.Struct:
return true
}
case *types.Array:
return true
case *types.Slice:
return true
case *types.Interface:
return true
}
return false
}

View File

@ -46,6 +46,10 @@ func newVarFrom(p *Package, v *types.Var) *Var {
return newVar(p, v.Type(), v.Name(), v.Name(), p.getDoc("", v))
}
func getTypeString(t types.Type) string {
return types.TypeString(t, func(*types.Package) string { return " " })
}
func getTypedesc(t types.Type) typedesc {
switch typ := t.(type) {
case *types.Basic:
@ -82,6 +86,16 @@ func getTypedesc(t types.Type) typedesc {
default:
panic(fmt.Errorf("unhandled type: %#v", typ))
}
case *types.Array:
id := fmt.Sprintf("_array_%d_%s", typ.Len(), getTypeString(typ.Elem()))
return typedesc{
ctype: "GoPy_" + id,
cgotype: "GoPy_" + id,
pyfmt: "O&",
c2py: "cgopy_cnv_c2py_" + id,
py2c: "cgopy_cnv_py2c_" + id,
}
case *types.Pointer:
elem := typ.Elem()
return getTypedesc(elem)
@ -184,3 +198,33 @@ func (v *Var) needWrap() bool {
typ := v.GoType()
return needWrapType(typ)
}
func qualifiedType(typ types.Type) string {
switch typ := typ.(type) {
case *types.Basic:
return typ.Name()
case *types.Named:
obj := typ.Obj()
switch typ.Underlying().(type) {
case *types.Struct:
return "GoPy_" + obj.Pkg().Name() + "_" + obj.Name()
case *types.Interface:
if obj.Name() == "error" {
return "error"
}
return "GoPy_" + obj.Name()
default:
return "GoPy_ooops_" + obj.Name()
}
case *types.Array:
id := fmt.Sprintf("_array_%d_%s", typ.Len(), getTypeString(typ.Elem()))
return "GoPy_" + id
case *types.Slice:
id := fmt.Sprintf("_slice_%s", getTypeString(typ.Elem()))
return "GoPy_" + id
}
return fmt.Sprintf("%#T", typ)
}