github.com/goplus/gossa@v0.3.25/unop_gen.go (about) 1 //go:build ignore 2 // +build ignore 3 4 package main 5 6 import ( 7 "bytes" 8 "fmt" 9 "go/format" 10 "io/ioutil" 11 "os" 12 "strings" 13 ) 14 15 var ( 16 ints = []string{"int", "int8", "int16", "int32", "int64", 17 "uint", "uint8", "uint16", "uint32", "uint64", "uintptr"} 18 floats = []string{"float32", "float64"} 19 comps = []string{"complex64", "complex128"} 20 ) 21 22 func json(kinds ...[]string) (r []string) { 23 for _, kind := range kinds { 24 r = append(r, kind...) 25 } 26 return 27 } 28 29 func main() { 30 var buf bytes.Buffer 31 buf.WriteString(pkg_head) 32 33 makeFuncOp(&buf, "makeUnOpSUB", "-", "Neg", json(ints, floats, comps)) 34 makeFuncOp(&buf, "makeUnOpXOR", "^", "Xor", json(ints)) 35 36 data, err := format.Source(buf.Bytes()) 37 if err != nil { 38 fmt.Println("format error", err) 39 os.Exit(2) 40 } 41 ioutil.WriteFile("./unop.go", data, 0666) 42 } 43 44 func makeFuncOp(buf *bytes.Buffer, fnname string, op string, neg string, kinds []string) { 45 buf.WriteString(strings.Replace(func_head_op, "$NAME", fnname, 1)) 46 buf.WriteString(`if typ.PkgPath() == "" { 47 switch typ.Kind() { 48 `) 49 for _, kind := range kinds { 50 r := strings.NewReplacer( 51 "Int", strings.Title(kind), 52 "int", kind, 53 "-", op, 54 "Neg", neg) 55 r.WriteString(buf, func_case1) 56 } 57 buf.WriteString(`} 58 } else { 59 switch typ.Kind() { 60 `) 61 for _, kind := range kinds { 62 r := strings.NewReplacer( 63 "Int", strings.Title(kind), 64 "-", op, 65 "Neg", neg) 66 r.WriteString(buf, func_case2) 67 } 68 buf.WriteString(`} 69 } 70 panic("unreachable") 71 }`) 72 } 73 74 var pkg_head = `package gossa 75 76 import ( 77 "reflect" 78 79 "github.com/goplus/gossa/internal/xtype" 80 "golang.org/x/tools/go/ssa" 81 ) 82 ` 83 84 var func_head_op = ` 85 func $NAME(pfn *function, instr *ssa.UnOp) func(fr *frame) { 86 ir := pfn.regIndex(instr) 87 ix, kx, vx := pfn.regIndex3(instr.X) 88 typ := pfn.Interp.preToType(instr.Type()) 89 ` 90 91 var func_case1 = `case reflect.Int: 92 if kx == kindConst { 93 v := -vx.(int) 94 return func(fr *frame) { fr.setReg(ir, v) } 95 } else { 96 return func(fr *frame) { 97 v := -fr.reg(ix).(int) 98 fr.setReg(ir, v) 99 } 100 } 101 ` 102 103 var func_case2 = `case reflect.Int: 104 if kx == kindConst { 105 v := xtype.NegInt(vx) 106 return func(fr *frame) { fr.setReg(ir, v) } 107 } else { 108 return func(fr *frame) { 109 v := xtype.NegInt(fr.reg(ix)) 110 fr.setReg(ir, v) 111 } 112 } 113 `