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"
)
//super is a map recording which class is the parent of each other class
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 {
if super == nil {
super = make(map[string]string)
@ -25,7 +30,6 @@ type Type struct {
Node *Node
Class string
ctype string
wrapped bool
}
func NewType(n *Node, c string) *Type {
@ -52,9 +56,12 @@ func (t *Type) String() string {
return t.Node.String()
}
func (t *Type) Wrap() *Type {
t.wrapped = true
return t
func (t *Type) Wrap() {
if wrapped == nil {
wrapped = make(map[string]bool)
}
// it is the pointers to this type that get wrapped
wrapped["*" + t.GoType()] = true
}
func (t *Type) BaseType() *Type {
@ -108,7 +115,8 @@ func (t *Type) CType() 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 fmt.Sprintf(`
@ -138,11 +146,11 @@ func GoToC(name string, pnames []string, rtype *Type, ptypes []*Type) string {
var ret strings.Builder
rt := rtype.CType()
if rt != "void" {
if rtype.wrapped {
ret.WriteString("ret := &" + rtype.GoType()[1:] + "{}\n")
ret.WriteString("ret.ptr = unsafe.Pointer(")
if wrapped[rtype.GoType()] {
ret.WriteString(" ret := &" + rtype.GoType()[1:] + "{}\n")
ret.WriteString(" ret.ptr = unsafe.Pointer(")
} else {
ret.WriteString("return (" + rtype.GoType() + ")(")
ret.WriteString(" return (" + rtype.GoType() + ")(")
if rtype.Node.IsPointer() {
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++ {
pn,pt := pnames[i],ptypes[i]
p := pn
if pt.wrapped {
if wrapped[pt.GoType()] {
p = pn + ".ptr"
} else {
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(")")
if rt != "void" {
if rtype.wrapped {
if wrapped[rtype.GoType()] {
ret.WriteString(`)
return ret
return ret
`)
} else {
ret.WriteString(")")
if rtype.Node.IsPointer() {
ret.WriteString(")")
}
ret.WriteString("\n")
}
}
return ret.String()

View File

@ -119,6 +119,13 @@ func (n *Node) IsStruct() bool {
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
func (n *Node) BaseType() *Node {
if n == nil {

View File

@ -30,6 +30,7 @@ type Wrapper struct {
goTypes strings.Builder // put Go type declarations here
goCode strings.Builder // put Go code here
Processed map[string]bool
Processed2 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
}
//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 {
Debug = debug
if Debug { fmt.Println("// Debug mode") }
@ -182,6 +166,7 @@ func NewWrapper(debug bool) *Wrapper {
ctMap: map[string]*types.Node{},
goStructTypes: map[string]cStruct{},
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?
}
tp := types.NewTypeFromString(name,name)
tp.Wrap()
var avail bool
for _,c := range ns {
switch x := c.(type) {
@ -433,7 +420,7 @@ func (w *Wrapper) GetParms(n *ast.ObjCMethodDecl,class string) ([]Parameter,bool
Pname: n.Parameters[j],
Vname: x.Name,
Type: x.Type,
Tp: types.NewTypeFromString(x.Name,class),
Tp: types.NewTypeFromString(x.Type,class),
}
ret = append(ret,p)
j++
@ -474,6 +461,30 @@ func (w *Wrapper) GetParms(n *ast.ObjCMethodDecl,class string) ([]Parameter,bool
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) {
if gotype == "" {
return
@ -574,62 +585,24 @@ New%s() {
if Debug {
fmt.Printf(" method: %s (%s)\n", m.Name, m.Type)
}
if m.Tp.Node.IsFunction() {
continue
}
gname := strings.Title(m.Name)
cname := i.Name + "_" + m.Name
grtype := ""
grptr := ""
_ = grptr
w.AddType(m.Type,i.Name)
//cmtype := cType(m.Type,i.Name)
cmtype := w.ctMap[w.goType(m.Type,i.Name)].CtypeSimplified()
if !m.isVoid() {
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)
//cmtype := w.ctMap[w.goType(m.Type,i.Name)].CtypeSimplified()
gplist,_,_ := w.goparamlist(m)
cmtype := m.Tp.CType()
ns,tps := gpntp(m)
w.pt2(tps...)
w.pt2(m.Tp)
w.goCode.WriteString(fmt.Sprintf(`
func (o *%s) %s(%s) %s {
`,i.Name,gname,gplist,m.Tp.GoType()))
w.goCode.WriteString(types.GoToC(gname,ns,m.Tp,tps))
w.goCode.WriteString(`
}
`)
/*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))*/
`,i.Name,gname,gplist,m.Tp.GoType()))
w.goCode.WriteString(
types.GoToC(cname,ns,m.Tp,tps) + "}\n")
cret := ""
if !m.isVoid() {
@ -643,9 +616,9 @@ func (o *%s) %s(%s) %s {
}
w.cCode.WriteString(fmt.Sprintf(`
%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