Skip to content

Commit

Permalink
Merge pull request #73 from jhlange/topic/josh/bind_methods_to_structs
Browse files Browse the repository at this point in the history
Allow for object oriented c bindings
  • Loading branch information
xlab committed Aug 21, 2019
2 parents 834d7b4 + 35d2d75 commit 8eeee8c
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 28 deletions.
93 changes: 69 additions & 24 deletions generator/gen_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,82 @@ func (gen *Generator) writeStructMembers(wr io.Writer, structName string, spec t
fmt.Fprintf(wr, "allocs%2x interface{}\n", crc)
}

func (gen *Generator) writeFunctionParams(wr io.Writer, funcName string, funcSpec tl.CType) {
func (gen *Generator) writeInstanceObjectParam(wr io.Writer, funcName string, funcSpec tl.CType) {
spec := funcSpec.(*tl.CFunctionSpec)
ptrTipSpecRx, _ := gen.tr.PtrTipRx(tl.TipScopeFunction, funcName)
typeTipSpecRx, _ := gen.tr.TypeTipRx(tl.TipScopeFunction, funcName)

for i, param := range spec.Params {
ptrTip := ptrTipSpecRx.TipAt(i)

if ptrTip != tl.TipPtrInst {
continue
}

ptrTip = tl.TipPtrRef
typeTip := typeTipSpecRx.TipAt(i)
if !typeTip.IsValid() {
// try to use type tip for the type itself
if tip, ok := gen.tr.TypeTipRx(tl.TipScopeType, param.Spec.CGoName()); ok {
if tip := tip.Self(); tip.IsValid() {
typeTip = tip
}
}
}

writeSpace(wr, 1)
writeStartParams(wr)
gen.writeFunctionParam(wr, param, ptrTip, typeTip)
writeEndParams(wr)

break
}
}

func (gen *Generator) writeFunctionParam(wr io.Writer, param *tl.CDecl, ptrTip tl.Tip, typeTip tl.Tip) {
const public = false

declName := checkName(gen.tr.TransformName(tl.TargetType, param.Name, public))
switch param.Spec.Kind() {
case tl.TypeKind:
goSpec := gen.tr.TranslateSpec(param.Spec, ptrTip, typeTip)
if len(goSpec.OuterArr) > 0 {
fmt.Fprintf(wr, "%s *%s", declName, goSpec)
} else {
fmt.Fprintf(wr, "%s %s", declName, goSpec)
}
case tl.StructKind, tl.OpaqueStructKind, tl.UnionKind:
goSpec := gen.tr.TranslateSpec(param.Spec, ptrTip, typeTip)
if len(goSpec.OuterArr) > 0 {
fmt.Fprintf(wr, "%s *%s", declName, goSpec)
} else {
fmt.Fprintf(wr, "%s %s", declName, goSpec)
}
case tl.EnumKind:
typeRef := gen.tr.TranslateSpec(param.Spec, ptrTip, typeTip).String()
fmt.Fprintf(wr, "%s %s", declName, typeRef)
case tl.FunctionKind:
gen.writeFunctionAsArg(wr, param, ptrTip, typeTip, public)
}
}

func (gen *Generator) writeFunctionParams(wr io.Writer, funcName string, funcSpec tl.CType) {
spec := funcSpec.(*tl.CFunctionSpec)
ptrTipSpecRx, _ := gen.tr.PtrTipRx(tl.TipScopeFunction, funcName)
typeTipSpecRx, _ := gen.tr.TypeTipRx(tl.TipScopeFunction, funcName)

writeStartParams(wr)
for i, param := range spec.Params {
ptrTip := ptrTipSpecRx.TipAt(i)

if ptrTip == tl.TipPtrInst {
continue
}

if !ptrTip.IsValid() {
ptrTip = tl.TipPtrArr
}

typeTip := typeTipSpecRx.TipAt(i)
if !typeTip.IsValid() {
// try to use type tip for the type itself
Expand All @@ -90,29 +154,10 @@ func (gen *Generator) writeFunctionParams(wr io.Writer, funcName string, funcSpe
}
}
}
declName := checkName(gen.tr.TransformName(tl.TargetType, param.Name, public))
switch param.Spec.Kind() {
case tl.TypeKind:
goSpec := gen.tr.TranslateSpec(param.Spec, ptrTip, typeTip)
if len(goSpec.OuterArr) > 0 {
fmt.Fprintf(wr, "%s *%s", declName, goSpec)
} else {
fmt.Fprintf(wr, "%s %s", declName, goSpec)
}
case tl.StructKind, tl.OpaqueStructKind, tl.UnionKind:
goSpec := gen.tr.TranslateSpec(param.Spec, ptrTip, typeTip)
if len(goSpec.OuterArr) > 0 {
fmt.Fprintf(wr, "%s *%s", declName, goSpec)
} else {
fmt.Fprintf(wr, "%s %s", declName, goSpec)
}
case tl.EnumKind:
typeRef := gen.tr.TranslateSpec(param.Spec, ptrTip, typeTip).String()
fmt.Fprintf(wr, "%s %s", declName, typeRef)
case tl.FunctionKind:
gen.writeFunctionAsArg(wr, param, ptrTip, typeTip, public)
}
if i < len(spec.Params)-1 {

gen.writeFunctionParam(wr, param, ptrTip, typeTip)

if i < len(spec.Params)-1 && ptrTipSpecRx.TipAt(i+1) != tl.TipPtrInst {
fmt.Fprintf(wr, ", ")
}
}
Expand Down
4 changes: 3 additions & 1 deletion generator/gen_declares.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ func (gen *Generator) writeFunctionDeclaration(wr io.Writer, decl *tl.CDecl,
}
fmt.Fprintf(wr, "// %s function as declared in %s\n", goName,
gen.tr.SrcLocation(tl.TargetFunction, decl.Name, decl.Pos))
fmt.Fprintf(wr, "func %s", goName)
fmt.Fprintf(wr, "func")
gen.writeInstanceObjectParam(wr, cName, decl.Spec)
fmt.Fprintf(wr, " %s", goName)
gen.writeFunctionParams(wr, cName, decl.Spec)
if len(returnRef) > 0 {
fmt.Fprintf(wr, " %s", returnRef)
Expand Down
2 changes: 1 addition & 1 deletion translator/model_go_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (spec *GoTypeSpec) splitPointers(ptrTip Tip, n uint8) {
case TipPtrRef:
spec.Slices = spec.Slices + n - 1
spec.Pointers++
case TipPtrSRef:
case TipPtrSRef, TipPtrInst:
spec.Pointers += n
case TipPtrArr:
spec.Slices += n
Expand Down
5 changes: 3 additions & 2 deletions translator/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ const (
TipPtrSRef Tip = "sref"
TipPtrRef Tip = "ref"
TipPtrArr Tip = "arr"
TipPtrInst Tip = "inst"
TipMemRaw Tip = "raw"
TipTypeNamed Tip = "named"
TipTypePlain Tip = "plain"
Expand All @@ -106,7 +107,7 @@ const (

func (t Tip) Kind() TipKind {
switch t {
case TipPtrArr, TipPtrRef, TipPtrSRef:
case TipPtrArr, TipPtrRef, TipPtrSRef, TipPtrInst:
return TipKindPtr
case TipTypePlain, TipTypeNamed:
return TipKindType
Expand All @@ -119,7 +120,7 @@ func (t Tip) Kind() TipKind {

func (t Tip) IsValid() bool {
switch t {
case TipPtrArr, TipPtrRef, TipPtrSRef:
case TipPtrArr, TipPtrRef, TipPtrSRef, TipPtrInst:
return true
case TipTypePlain, TipTypeNamed:
return true
Expand Down

0 comments on commit 8eeee8c

Please sign in to comment.