Fixed type wrapping, further conversion to new type system. The

Go side looks pretty good at this point.
This commit is contained in:
Greg 2019-04-26 10:07:34 -04:00
parent fb21881a8b
commit e143dbb6a7
3 changed files with 71 additions and 82 deletions

View File

@ -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()

View File

@ -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 {

View File

@ -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