github.com/gotranspile/cxgo@v0.3.7/types/go_types.go (about) 1 package types 2 3 import ( 4 "fmt" 5 "go/ast" 6 "go/token" 7 "strconv" 8 "strings" 9 ) 10 11 type GoType = ast.Expr 12 13 func ident(name string) *ast.Ident { 14 return &ast.Ident{Name: name} 15 } 16 17 func goName(name string) string { 18 switch name { 19 case "len", "cap", 20 "var", "const", "func", 21 "type", "chan", "range", 22 "copy", "close", "make", "append", 23 "string", "byte", "rune", 24 "interface", "map": 25 name += "_" 26 } 27 name = strings.ReplaceAll(name, "$", "_") 28 if name == "_" { 29 name += "1" 30 } 31 return name 32 } 33 34 func (e *Ident) convertName() { 35 if e.GoName != "" { 36 return 37 } 38 e.GoName = goName(e.Name) 39 } 40 41 func (e *Ident) GoIdent() *ast.Ident { 42 e.convertName() 43 return ident(e.GoName) 44 } 45 46 func (t *unkType) GoType() GoType { 47 if t.isStruct { 48 return ident("struct{}") // TODO 49 } 50 return ident("interface{}") // TODO 51 } 52 53 func (t IntType) GoType() GoType { 54 u := "u" 55 if t.signed { 56 u = "" 57 } 58 return ident(fmt.Sprintf("%sint%d", u, t.Sizeof()*8)) 59 } 60 61 func (t FloatType) GoType() GoType { 62 return ident(fmt.Sprintf("float%d", t.size*8)) 63 } 64 65 func (t BoolType) GoType() GoType { 66 return ident("bool") 67 } 68 69 func (t *ptrType) GoType() GoType { 70 elem := t.Elem() 71 if elem == nil { 72 return ident("unsafe.Pointer") 73 } 74 return &ast.StarExpr{ 75 X: elem.GoType(), 76 } 77 } 78 79 func (t namedPtr) GoType() GoType { 80 return t.name.GoIdent() 81 } 82 83 func (t ArrayType) GoType() GoType { 84 var sz ast.Expr 85 if !t.slice { 86 sz = &ast.BasicLit{ 87 Kind: token.INT, 88 Value: strconv.Itoa(t.size), 89 } 90 } 91 return &ast.ArrayType{ 92 Len: sz, 93 Elt: t.elem.GoType(), 94 } 95 } 96 97 func (t *namedType) GoType() GoType { 98 return t.name.GoIdent() 99 } 100 101 func (f *Field) GoField() *ast.Field { 102 var names []*ast.Ident 103 if f.Name != nil && !f.Name.IsUnnamed() { 104 names = append(names, f.Name.GoIdent()) 105 } 106 return &ast.Field{Names: names, Type: f.Type().GoType()} 107 } 108 109 func (t *StructType) GoType() GoType { 110 fields := &ast.FieldList{} 111 if t.union { 112 fields.List = append(fields.List, &ast.Field{Type: ident("// union")}) 113 } 114 for _, f := range t.fields { 115 fields.List = append(fields.List, f.GoField()) 116 } 117 return &ast.StructType{Fields: fields} 118 } 119 120 func (t *FuncType) GoType() GoType { 121 return t.GoFuncType() 122 } 123 124 func (t *FuncType) GoFuncType() *ast.FuncType { 125 var ret ast.Expr 126 if t.Return() != nil { 127 ret = t.Return().GoType() 128 } 129 p := &ast.FieldList{} 130 f := &ast.FuncType{ 131 Params: p, 132 } 133 if ret != nil { 134 f.Results = &ast.FieldList{List: []*ast.Field{{Type: ret}}} 135 } 136 hasNames := t.ArgN() == 0 // default to names, if only has variadic 137 for _, a := range t.Args() { 138 if a.Name.Name != "" { 139 hasNames = true 140 } 141 p.List = append(p.List, a.GoField()) 142 } 143 if t.Variadic() { 144 var names []*ast.Ident 145 if hasNames { 146 names = []*ast.Ident{ident("_rest")} 147 } 148 p.List = append(p.List, &ast.Field{ 149 Names: names, 150 Type: &ast.Ellipsis{Elt: ident("interface{}")}, 151 }) 152 } 153 return f 154 }