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"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//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()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										113
									
								
								wrap/main.go
									
									
									
									
									
								
							
							
						
						
									
										113
									
								
								wrap/main.go
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user