github.com/goplus/igop@v0.25.0/unop_gen.go (about)

     1  //go:build ignore
     2  // +build ignore
     3  
     4  /*
     5   * Copyright (c) 2022 The GoPlus Authors (goplus.org). All rights reserved.
     6   *
     7   * Licensed under the Apache License, Version 2.0 (the "License");
     8   * you may not use this file except in compliance with the License.
     9   * You may obtain a copy of the License at
    10   *
    11   *     http://www.apache.org/licenses/LICENSE-2.0
    12   *
    13   * Unless required by applicable law or agreed to in writing, software
    14   * distributed under the License is distributed on an "AS IS" BASIS,
    15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16   * See the License for the specific language governing permissions and
    17   * limitations under the License.
    18   */
    19  
    20  package main
    21  
    22  import (
    23  	"bytes"
    24  	"fmt"
    25  	"go/format"
    26  	"io/ioutil"
    27  	"os"
    28  	"strings"
    29  )
    30  
    31  var (
    32  	ints = []string{"int", "int8", "int16", "int32", "int64",
    33  		"uint", "uint8", "uint16", "uint32", "uint64", "uintptr"}
    34  	floats = []string{"float32", "float64"}
    35  	comps  = []string{"complex64", "complex128"}
    36  )
    37  
    38  func json(kinds ...[]string) (r []string) {
    39  	for _, kind := range kinds {
    40  		r = append(r, kind...)
    41  	}
    42  	return
    43  }
    44  
    45  func main() {
    46  	var buf bytes.Buffer
    47  	buf.WriteString(pkg_head)
    48  
    49  	makeFuncOp(&buf, "makeUnOpSUB", "-", "Neg", json(ints, floats, comps))
    50  	makeFuncOp(&buf, "makeUnOpXOR", "^", "Xor", json(ints))
    51  
    52  	data, err := format.Source(buf.Bytes())
    53  	if err != nil {
    54  		fmt.Println("format error", err)
    55  		os.Exit(2)
    56  	}
    57  	ioutil.WriteFile("./unop.go", data, 0666)
    58  }
    59  
    60  func makeFuncOp(buf *bytes.Buffer, fnname string, op string, neg string, kinds []string) {
    61  	buf.WriteString(strings.Replace(func_head_op, "$NAME", fnname, 1))
    62  	buf.WriteString(`if typ.PkgPath() == "" {
    63  		switch typ.Kind() {
    64  `)
    65  	for _, kind := range kinds {
    66  		r := strings.NewReplacer(
    67  			"Int", strings.Title(kind),
    68  			"int", kind,
    69  			"-", op,
    70  			"Neg", neg)
    71  		r.WriteString(buf, func_case1)
    72  	}
    73  	buf.WriteString(`}
    74  	} else {
    75  	switch typ.Kind() {
    76  `)
    77  	for _, kind := range kinds {
    78  		r := strings.NewReplacer(
    79  			"Int", strings.Title(kind),
    80  			"-", op,
    81  			"Neg", neg)
    82  		r.WriteString(buf, func_case2)
    83  	}
    84  	buf.WriteString(`}
    85  	}
    86  	panic("unreachable")
    87  }`)
    88  }
    89  
    90  var pkg_head = `/*
    91   * Copyright (c) 2022 The GoPlus Authors (goplus.org). All rights reserved.
    92   *
    93   * Licensed under the Apache License, Version 2.0 (the "License");
    94   * you may not use this file except in compliance with the License.
    95   * You may obtain a copy of the License at
    96   *
    97   *     http://www.apache.org/licenses/LICENSE-2.0
    98   *
    99   * Unless required by applicable law or agreed to in writing, software
   100   * distributed under the License is distributed on an "AS IS" BASIS,
   101   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   102   * See the License for the specific language governing permissions and
   103   * limitations under the License.
   104   */
   105  
   106  package igop
   107  
   108  import (
   109  	"reflect"
   110  
   111  	"github.com/visualfc/xtype"
   112  	"golang.org/x/tools/go/ssa"
   113  )
   114  `
   115  
   116  var func_head_op = `
   117  func $NAME(pfn *function, instr *ssa.UnOp) func(fr *frame) {
   118  	ir := pfn.regIndex(instr)
   119  	ix, kx, vx := pfn.regIndex3(instr.X)
   120  	typ := pfn.Interp.preToType(instr.Type())
   121  `
   122  
   123  var func_case1 = `case reflect.Int:
   124  if kx == kindConst {
   125  	v := -vx.(int)
   126  	return func(fr *frame) { fr.setReg(ir, v) }
   127  } else {
   128  	return func(fr *frame) {
   129  		v := -fr.reg(ix).(int)
   130  		fr.setReg(ir, v)
   131  	}
   132  }
   133  `
   134  
   135  var func_case2 = `case reflect.Int:
   136  if kx == kindConst {
   137  	v := xtype.NegInt(vx)
   138  	return func(fr *frame) { fr.setReg(ir, v) }
   139  } else {
   140  	return func(fr *frame) {
   141  		v := xtype.NegInt(fr.reg(ix))
   142  		fr.setReg(ir, v)
   143  	}
   144  }
   145  `