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  }