github.com/xhebox/bstruct@v0.0.0-20221115052913-86d4d6d98866/const.go (about) 1 package bstruct 2 3 import ( 4 "fmt" 5 "go/ast" 6 "go/token" 7 "unicode" 8 ) 9 10 var ( 11 writerType = &ast.UnaryExpr{X: newSel("bstruct", "Writer"), Op: token.MUL} 12 readerType = &ast.UnaryExpr{X: newSel("bstruct", "Reader"), Op: token.MUL} 13 ) 14 15 func capitalize(s string) string { 16 if len(s) == 0 { 17 return s 18 } 19 return string(unicode.ToUpper(rune(s[0]))) + s[1:] 20 } 21 22 func newMul(l, r ast.Expr) *ast.BinaryExpr { 23 return &ast.BinaryExpr{X: l, Y: r, Op: token.MUL} 24 } 25 26 func newSel(l any, r string) *ast.SelectorExpr { 27 return &ast.SelectorExpr{X: newIdent(l), Sel: ast.NewIdent(r)} 28 } 29 30 func newPtr(l ast.Expr) *ast.UnaryExpr { 31 return &ast.UnaryExpr{X: l, Op: token.AND} 32 } 33 34 func newOpt(l string) string { 35 return fmt.Sprintf("__%s", l) 36 } 37 38 func newIdx(l ast.Expr, d any) *ast.IndexExpr { 39 switch v := d.(type) { 40 case int: 41 return &ast.IndexExpr{X: l, Index: intLit(v)} 42 case uint: 43 return &ast.IndexExpr{X: l, Index: intLit(v)} 44 case ast.Expr, string: 45 return &ast.IndexExpr{X: l, Index: newIdent(v)} 46 default: 47 panic("wth") 48 } 49 } 50 51 func newLen(l ast.Expr) *ast.CallExpr { 52 return newCall("len", l) 53 } 54 55 func newCall(f any, args ...ast.Expr) *ast.CallExpr { 56 return &ast.CallExpr{ 57 Fun: newIdent(f), 58 Args: args, 59 } 60 } 61 62 func newDef(l, r any) *ast.AssignStmt { 63 return &ast.AssignStmt{ 64 Lhs: []ast.Expr{newIdent(l)}, 65 Tok: token.DEFINE, 66 Rhs: []ast.Expr{newIdent(r)}, 67 } 68 } 69 70 func newAssign(l, r any) *ast.AssignStmt { 71 return &ast.AssignStmt{ 72 Lhs: []ast.Expr{newIdent(l)}, 73 Tok: token.ASSIGN, 74 Rhs: []ast.Expr{newIdent(r)}, 75 } 76 } 77 78 func newCallST(f any, args ...ast.Expr) *ast.ExprStmt { 79 return &ast.ExprStmt{X: newCall(f, args...)} 80 } 81 82 func unsafePtr(e ast.Expr) *ast.CallExpr { 83 return &ast.CallExpr{ 84 Fun: newSel("unsafe", "Pointer"), 85 Args: []ast.Expr{e}, 86 } 87 } 88 89 type integer interface { 90 ~int | uint 91 } 92 93 func intLit[T integer](d T) *ast.BasicLit { 94 return &ast.BasicLit{Kind: token.INT, Value: fmt.Sprintf("%d", d)} 95 } 96 97 func newIdent(l any) ast.Expr { 98 switch v := l.(type) { 99 case string: 100 return ast.NewIdent(v) 101 case ast.Expr: 102 return v 103 default: 104 panic("wrong") 105 } 106 }