github.com/gotranspile/cxgo@v0.3.7/types/env_go.go (about) 1 package types 2 3 import "fmt" 4 5 const GoPrefix = "_cxgo_go_" 6 7 var ( 8 goArch4 = newGo(4) 9 goArch8 = newGo(8) 10 ) 11 12 func GoArch(size int) *Go { 13 switch size { 14 case 4: 15 return goArch4 16 case 8: 17 return goArch8 18 default: 19 return newGo(size) 20 } 21 } 22 23 func newGo(size int) *Go { 24 pkg := newPackage("", "") 25 // Those are native Go types that will always be mapped to themselves when transpiling 26 // All other types might be mapped differently from C to Go 27 g := &Go{ 28 size: size, pkg: pkg, 29 // register basic Go types 30 boolT: pkg.NewAlias(GoPrefix+"bool", "bool", BoolT()), 31 byteT: pkg.NewTypeGo(GoPrefix+"byte", "byte", UintT(1)), 32 runeT: pkg.NewTypeGo(GoPrefix+"rune", "rune", IntT(4)), 33 34 uintptrT: pkg.NewTypeGo(GoPrefix+"uintptr", "uintptr", UintT(size)), 35 intT: pkg.NewTypeGo(GoPrefix+"int", "int", IntT(size)), 36 uintT: pkg.NewTypeGo(GoPrefix+"uint", "uint", UintT(size)), 37 stringT: pkg.NewTypeGo(GoPrefix+"string", "string", UnkT(size*2)), 38 anyT: pkg.NewTypeGo(GoPrefix+"any", "any", UnkT(size*2)), 39 } 40 41 // register fixed-size builtin Go types 42 for _, sz := range []int{ 43 1, 2, 4, 8, 44 } { 45 name := fmt.Sprintf("int%d", sz*8) 46 g.pkg.NewAlias(GoPrefix+name, name, IntT(sz)) // intN 47 g.pkg.NewAlias(GoPrefix+"u"+name, "u"+name, UintT(sz)) // uintN 48 if sz >= 4 { 49 name = fmt.Sprintf("float%d", sz*8) 50 g.pkg.NewAlias(GoPrefix+name, name, FloatT(sz)) // floatN 51 } 52 } 53 54 // identifiers 55 g.iot = NewIdentGo(GoPrefix+"iota", "iota", UntypedIntT(g.size)) 56 g.lenF = NewIdentGo(GoPrefix+"len", "len", FuncTT(g.size, g.intT, g.anyT)) 57 g.capF = NewIdentGo(GoPrefix+"cap", "cap", FuncTT(g.size, g.intT, g.anyT)) 58 g.sliceF = NewIdentGo(GoPrefix+"slice", "_slice", VarFuncTT(g.size, UnkT(g.size), g.anyT)) 59 g.appendF = NewIdentGo(GoPrefix+"append", "append", VarFuncTT(g.size, UnkT(g.size), g.anyT)) 60 g.copyF = NewIdentGo(GoPrefix+"copy", "copy", FuncTT(g.size, g.intT, g.anyT, g.anyT)) 61 g.makeF = NewIdentGo(GoPrefix+"make_impl", "make", VarFuncTT(g.size, UnkT(g.size), g.anyT)) 62 g.panicF = NewIdentGo(GoPrefix+"panic", "panic", FuncTT(g.size, nil, g.anyT)) 63 64 // stdlib 65 g.osExitF = NewIdentGo("_Exit", "os.Exit", FuncTT(g.size, nil, g.intT)) 66 return g 67 } 68 69 type Go struct { 70 size int // size of (u)int and pointers 71 pkg *Package 72 73 // don't forget to update g.Types() when adding new types here 74 75 boolT Type 76 byteT Type 77 runeT Type 78 uintptrT Type 79 intT Type 80 uintT Type 81 anyT Type 82 stringT Type 83 84 iot *Ident 85 lenF *Ident 86 capF *Ident 87 sliceF *Ident 88 appendF *Ident 89 copyF *Ident 90 makeF *Ident 91 panicF *Ident 92 osExitF *Ident 93 } 94 95 // Go returns a package containing builtin Go types. 96 func (e *Env) Go() *Go { 97 return e.g 98 } 99 100 func (e *Env) initGo() { 101 // TODO: we are assuming Go arch = C arch here 102 e.g = GoArch(e.conf.PtrSize) 103 } 104 105 func (g *Go) Types() []Type { 106 return []Type{ 107 g.boolT, 108 g.byteT, 109 g.runeT, 110 g.uintptrT, 111 g.intT, 112 g.uintT, 113 g.anyT, 114 g.stringT, 115 } 116 } 117 118 func (g *Go) IsBuiltinType(t Type) bool { 119 for _, t2 := range g.Types() { 120 if t == t2 { 121 return true 122 } 123 } 124 return false 125 } 126 127 // Bool returns Go bool type. 128 func (g *Go) Bool() Type { 129 return g.boolT 130 } 131 132 // Byte returns Go byte type. 133 func (g *Go) Byte() Type { 134 return g.byteT 135 } 136 137 // Rune returns Go rune type. 138 func (g *Go) Rune() Type { 139 return g.runeT 140 } 141 142 // Uintptr returns Go uintptr type. 143 func (g *Go) Uintptr() Type { 144 return g.uintptrT 145 } 146 147 // UnsafePtr returns Go unsafe.Pointer type. 148 func (g *Go) UnsafePtr() Type { 149 // TODO: reserve a special type for it? 150 return PtrT(g.size, nil) 151 } 152 153 // Int returns Go int type. 154 func (g *Go) Int() Type { 155 return g.intT 156 } 157 158 // Uint returns Go uint type. 159 func (g *Go) Uint() Type { 160 return g.uintT 161 } 162 163 // Any returns Go any type. 164 func (g *Go) Any() Type { 165 return g.anyT 166 } 167 168 // SliceOfAny returns Go []any type. 169 func (g *Go) SliceOfAny() Type { 170 return SliceT(g.anyT) 171 } 172 173 // String returns Go string type. 174 func (g *Go) String() Type { 175 return g.stringT 176 } 177 178 // Bytes returns Go []byte type. 179 func (g *Go) Bytes() Type { 180 return SliceT(g.Byte()) 181 } 182 183 // Iota returns Go iota identifier. 184 func (g *Go) Iota() *Ident { 185 return g.iot 186 } 187 188 // LenFunc returns Go len function identifier. 189 func (g *Go) LenFunc() *Ident { 190 return g.lenF 191 } 192 193 // CapFunc returns Go cap function identifier. 194 func (g *Go) CapFunc() *Ident { 195 return g.capF 196 } 197 198 // SliceFunc returns Go function identifier equivalent to Go slice expression. 199 func (g *Go) SliceFunc() *Ident { 200 return g.sliceF 201 } 202 203 // AppendFunc returns Go append function identifier. 204 func (g *Go) AppendFunc() *Ident { 205 return g.appendF 206 } 207 208 // CopyFunc returns Go copy function identifier. 209 func (g *Go) CopyFunc() *Ident { 210 return g.copyF 211 } 212 213 // MakeFunc returns Go make function identifier. 214 func (g *Go) MakeFunc() *Ident { 215 return g.makeF 216 } 217 218 // PanicFunc returns Go panic function identifier. 219 func (g *Go) PanicFunc() *Ident { 220 return g.panicF 221 } 222 223 // OsExitFunc returns Go os.Exit function identifier. 224 func (g *Go) OsExitFunc() *Ident { 225 return g.osExitF 226 }