Fixed type wrapping, further conversion to new type system. The
Go side looks pretty good at this point.
This commit is contained in:
parent
fb21881a8b
commit
e143dbb6a7
|
@ -5,8 +5,13 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//super is a map recording which class is the parent of each other class
|
||||||
var super map[string]string
|
var super map[string]string
|
||||||
|
|
||||||
|
//wrapped is a map recording whether a given GoType is to be "wrapped" in a
|
||||||
|
//go struct.
|
||||||
|
var wrapped map[string]bool
|
||||||
|
|
||||||
func Super(c string) string {
|
func Super(c string) string {
|
||||||
if super == nil {
|
if super == nil {
|
||||||
super = make(map[string]string)
|
super = make(map[string]string)
|
||||||
|
@ -25,7 +30,6 @@ type Type struct {
|
||||||
Node *Node
|
Node *Node
|
||||||
Class string
|
Class string
|
||||||
ctype string
|
ctype string
|
||||||
wrapped bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewType(n *Node, c string) *Type {
|
func NewType(n *Node, c string) *Type {
|
||||||
|
@ -52,9 +56,12 @@ func (t *Type) String() string {
|
||||||
return t.Node.String()
|
return t.Node.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Type) Wrap() *Type {
|
func (t *Type) Wrap() {
|
||||||
t.wrapped = true
|
if wrapped == nil {
|
||||||
return t
|
wrapped = make(map[string]bool)
|
||||||
|
}
|
||||||
|
// it is the pointers to this type that get wrapped
|
||||||
|
wrapped["*" + t.GoType()] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Type) BaseType() *Type {
|
func (t *Type) BaseType() *Type {
|
||||||
|
@ -108,7 +115,8 @@ func (t *Type) CType() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Type) GoTypeDecl() string {
|
func (t *Type) GoTypeDecl() string {
|
||||||
if t.wrapped {
|
if wrapped[t.GoType()] {
|
||||||
|
fmt.Printf("%s -> %s: %s is wrapped\n",t.GoType(),t.CGoType(),t.Class)
|
||||||
return t.GoInterfaceDecl()
|
return t.GoInterfaceDecl()
|
||||||
}
|
}
|
||||||
return fmt.Sprintf(`
|
return fmt.Sprintf(`
|
||||||
|
@ -138,11 +146,11 @@ func GoToC(name string, pnames []string, rtype *Type, ptypes []*Type) string {
|
||||||
var ret strings.Builder
|
var ret strings.Builder
|
||||||
rt := rtype.CType()
|
rt := rtype.CType()
|
||||||
if rt != "void" {
|
if rt != "void" {
|
||||||
if rtype.wrapped {
|
if wrapped[rtype.GoType()] {
|
||||||
ret.WriteString("ret := &" + rtype.GoType()[1:] + "{}\n")
|
ret.WriteString(" ret := &" + rtype.GoType()[1:] + "{}\n")
|
||||||
ret.WriteString("ret.ptr = unsafe.Pointer(")
|
ret.WriteString(" ret.ptr = unsafe.Pointer(")
|
||||||
} else {
|
} else {
|
||||||
ret.WriteString("return (" + rtype.GoType() + ")(")
|
ret.WriteString(" return (" + rtype.GoType() + ")(")
|
||||||
if rtype.Node.IsPointer() {
|
if rtype.Node.IsPointer() {
|
||||||
ret.WriteString("unsafe.Pointer(")
|
ret.WriteString("unsafe.Pointer(")
|
||||||
}
|
}
|
||||||
|
@ -153,7 +161,7 @@ func GoToC(name string, pnames []string, rtype *Type, ptypes []*Type) string {
|
||||||
for i := 0; i < len(pnames); i++ {
|
for i := 0; i < len(pnames); i++ {
|
||||||
pn,pt := pnames[i],ptypes[i]
|
pn,pt := pnames[i],ptypes[i]
|
||||||
p := pn
|
p := pn
|
||||||
if pt.wrapped {
|
if wrapped[pt.GoType()] {
|
||||||
p = pn + ".ptr"
|
p = pn + ".ptr"
|
||||||
} else {
|
} else {
|
||||||
p = "(" + pt.CGoType() + ")(" + pn + ")"
|
p = "(" + pt.CGoType() + ")(" + pn + ")"
|
||||||
|
@ -163,15 +171,16 @@ func GoToC(name string, pnames []string, rtype *Type, ptypes []*Type) string {
|
||||||
ret.WriteString(strings.Join(parms,", "))
|
ret.WriteString(strings.Join(parms,", "))
|
||||||
ret.WriteString(")")
|
ret.WriteString(")")
|
||||||
if rt != "void" {
|
if rt != "void" {
|
||||||
if rtype.wrapped {
|
if wrapped[rtype.GoType()] {
|
||||||
ret.WriteString(`)
|
ret.WriteString(`)
|
||||||
return ret
|
return ret
|
||||||
`)
|
`)
|
||||||
} else {
|
} else {
|
||||||
ret.WriteString(")")
|
ret.WriteString(")")
|
||||||
if rtype.Node.IsPointer() {
|
if rtype.Node.IsPointer() {
|
||||||
ret.WriteString(")")
|
ret.WriteString(")")
|
||||||
}
|
}
|
||||||
|
ret.WriteString("\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret.String()
|
return ret.String()
|
||||||
|
|
|
@ -119,6 +119,13 @@ func (n *Node) IsStruct() bool {
|
||||||
return n.Children[0].Kind == "Struct"
|
return n.Children[0].Kind == "Struct"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *Node) IsFunction() bool {
|
||||||
|
if n == nil || len(n.Children) < 1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return n.Children[len(n.Children)-1].Kind == "Function"
|
||||||
|
}
|
||||||
|
|
||||||
//BaseType strips off all layers of pointer indirection
|
//BaseType strips off all layers of pointer indirection
|
||||||
func (n *Node) BaseType() *Node {
|
func (n *Node) BaseType() *Node {
|
||||||
if n == nil {
|
if n == nil {
|
||||||
|
|
113
wrap/main.go
113
wrap/main.go
|
@ -30,6 +30,7 @@ type Wrapper struct {
|
||||||
goTypes strings.Builder // put Go type declarations here
|
goTypes strings.Builder // put Go type declarations here
|
||||||
goCode strings.Builder // put Go code here
|
goCode strings.Builder // put Go code here
|
||||||
Processed map[string]bool
|
Processed map[string]bool
|
||||||
|
Processed2 map[string]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var gobuiltinTypes map[string]bool = map[string]bool{
|
var gobuiltinTypes map[string]bool = map[string]bool{
|
||||||
|
@ -155,23 +156,6 @@ func (w *Wrapper) goType(t,class string) string {
|
||||||
return ct
|
return ct
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME: to be deleted
|
|
||||||
func cType(t, class string) string {
|
|
||||||
n, err := types.Parse(t)
|
|
||||||
if err != nil {
|
|
||||||
//fmt.Printf("Cannot parse type %s\n",t)
|
|
||||||
return "NOT IMPLEMENTED"
|
|
||||||
}
|
|
||||||
nt := n.CtypeSimplified()
|
|
||||||
if nt == "id" {
|
|
||||||
return "NSObject"
|
|
||||||
}
|
|
||||||
if nt == "instancetype" {
|
|
||||||
return class + " *"
|
|
||||||
}
|
|
||||||
return nt
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewWrapper(debug bool) *Wrapper {
|
func NewWrapper(debug bool) *Wrapper {
|
||||||
Debug = debug
|
Debug = debug
|
||||||
if Debug { fmt.Println("// Debug mode") }
|
if Debug { fmt.Println("// Debug mode") }
|
||||||
|
@ -182,6 +166,7 @@ func NewWrapper(debug bool) *Wrapper {
|
||||||
ctMap: map[string]*types.Node{},
|
ctMap: map[string]*types.Node{},
|
||||||
goStructTypes: map[string]cStruct{},
|
goStructTypes: map[string]cStruct{},
|
||||||
Processed: map[string]bool{},
|
Processed: map[string]bool{},
|
||||||
|
Processed2: map[string]bool{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,6 +352,8 @@ func (w *Wrapper) add(name string, ns []ast.Node) {
|
||||||
}
|
}
|
||||||
w.AddType(name,name) // need this?
|
w.AddType(name,name) // need this?
|
||||||
}
|
}
|
||||||
|
tp := types.NewTypeFromString(name,name)
|
||||||
|
tp.Wrap()
|
||||||
var avail bool
|
var avail bool
|
||||||
for _,c := range ns {
|
for _,c := range ns {
|
||||||
switch x := c.(type) {
|
switch x := c.(type) {
|
||||||
|
@ -433,7 +420,7 @@ func (w *Wrapper) GetParms(n *ast.ObjCMethodDecl,class string) ([]Parameter,bool
|
||||||
Pname: n.Parameters[j],
|
Pname: n.Parameters[j],
|
||||||
Vname: x.Name,
|
Vname: x.Name,
|
||||||
Type: x.Type,
|
Type: x.Type,
|
||||||
Tp: types.NewTypeFromString(x.Name,class),
|
Tp: types.NewTypeFromString(x.Type,class),
|
||||||
}
|
}
|
||||||
ret = append(ret,p)
|
ret = append(ret,p)
|
||||||
j++
|
j++
|
||||||
|
@ -474,6 +461,30 @@ func (w *Wrapper) GetParms(n *ast.ObjCMethodDecl,class string) ([]Parameter,bool
|
||||||
return ret, true
|
return ret, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// new version of ProcessType
|
||||||
|
func (w *Wrapper) pt2(tps ...*types.Type) {
|
||||||
|
switch len(tps) {
|
||||||
|
case 0:
|
||||||
|
return
|
||||||
|
case 1:
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
for _,tp := range tps {
|
||||||
|
w.pt2(tp)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tp := tps[0].BaseType()
|
||||||
|
if w.Processed2[tp.GoType()] {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Processed2[tp.GoType()] = true
|
||||||
|
if tp.Node.IsFunction() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.goTypes.WriteString(tp.GoTypeDecl())
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Wrapper) ProcessType(gotype string) {
|
func (w *Wrapper) ProcessType(gotype string) {
|
||||||
if gotype == "" {
|
if gotype == "" {
|
||||||
return
|
return
|
||||||
|
@ -574,62 +585,24 @@ New%s() {
|
||||||
if Debug {
|
if Debug {
|
||||||
fmt.Printf(" method: %s (%s)\n", m.Name, m.Type)
|
fmt.Printf(" method: %s (%s)\n", m.Name, m.Type)
|
||||||
}
|
}
|
||||||
|
if m.Tp.Node.IsFunction() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
gname := strings.Title(m.Name)
|
gname := strings.Title(m.Name)
|
||||||
|
cname := i.Name + "_" + m.Name
|
||||||
|
|
||||||
grtype := ""
|
|
||||||
grptr := ""
|
|
||||||
_ = grptr
|
|
||||||
w.AddType(m.Type,i.Name)
|
w.AddType(m.Type,i.Name)
|
||||||
//cmtype := cType(m.Type,i.Name)
|
//cmtype := w.ctMap[w.goType(m.Type,i.Name)].CtypeSimplified()
|
||||||
cmtype := w.ctMap[w.goType(m.Type,i.Name)].CtypeSimplified()
|
gplist,_,_ := w.goparamlist(m)
|
||||||
if !m.isVoid() {
|
cmtype := m.Tp.CType()
|
||||||
grtype = w.goType(cmtype,i.Name)
|
|
||||||
if grtype == "" {
|
|
||||||
grtype = fmt.Sprintf("// goType(%s): NOT IMPLEMENTED\n",cmtype)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gcast := ""
|
|
||||||
gcast2 := ""
|
|
||||||
_ = gcast
|
|
||||||
_ = gcast2
|
|
||||||
if grtype != "" {
|
|
||||||
if grtype[0] == '*' { // pointer return type
|
|
||||||
if _,ok := w.Interfaces[grtype[1:]]; ok {
|
|
||||||
//grptr = "*"
|
|
||||||
gcast = "ret := &" + grtype[1:] + "{}\n ret.ptr = unsafe.Pointer("
|
|
||||||
gcast2 = ")\n return ret"
|
|
||||||
} else {
|
|
||||||
gcast = "return (" + grtype + ")(unsafe.Pointer("
|
|
||||||
gcast2 = "))"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
gcast = fmt.Sprintf("return (%s)(",grtype)
|
|
||||||
gcast2 = ")"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if grtype == "id" { // can't return id
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
w.ProcessType(grtype)
|
|
||||||
gplist, gptypes, ok := w.goparamlist(m)
|
|
||||||
_ = gplist
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
w.ProcessTypes(gptypes)
|
|
||||||
ns,tps := gpntp(m)
|
ns,tps := gpntp(m)
|
||||||
|
w.pt2(tps...)
|
||||||
|
w.pt2(m.Tp)
|
||||||
w.goCode.WriteString(fmt.Sprintf(`
|
w.goCode.WriteString(fmt.Sprintf(`
|
||||||
func (o *%s) %s(%s) %s {
|
func (o *%s) %s(%s) %s {
|
||||||
`,i.Name,gname,gplist,m.Tp.GoType()))
|
`,i.Name,gname,gplist,m.Tp.GoType()))
|
||||||
w.goCode.WriteString(types.GoToC(gname,ns,m.Tp,tps))
|
w.goCode.WriteString(
|
||||||
w.goCode.WriteString(`
|
types.GoToC(cname,ns,m.Tp,tps) + "}\n")
|
||||||
}
|
|
||||||
`)
|
|
||||||
|
|
||||||
/*w.goCode.WriteString(fmt.Sprintf(`
|
|
||||||
%sC.%s_%s(%s)%s
|
|
||||||
}`,i.Name, gname, gplist, grptr, grtype, gcast, i.Name, m.Name, w.goparamnames(m),gcast2))*/
|
|
||||||
|
|
||||||
cret := ""
|
cret := ""
|
||||||
if !m.isVoid() {
|
if !m.isVoid() {
|
||||||
|
@ -643,9 +616,9 @@ func (o *%s) %s(%s) %s {
|
||||||
}
|
}
|
||||||
w.cCode.WriteString(fmt.Sprintf(`
|
w.cCode.WriteString(fmt.Sprintf(`
|
||||||
%s
|
%s
|
||||||
%s_%s(%s) {
|
%s(%s) {
|
||||||
%s[%s %s];
|
%s[%s %s];
|
||||||
}`, cmtype, i.Name, m.Name, w.cparamlist(m), cret, cobj, w.objcparamlist(m)))
|
}`, cmtype, cname, w.cparamlist(m), cret, cobj, w.objcparamlist(m)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Println(`package main
|
fmt.Println(`package main
|
||||||
|
|
Loading…
Reference in New Issue
Block a user