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  `