github.com/goplus/igop@v0.25.0/binop_shift_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 ) 35 36 type TypeKind struct { 37 typ string 38 kind string 39 } 40 41 func main() { 42 var buf bytes.Buffer 43 buf.WriteString(pkg_head) 44 var kinds []*TypeKind 45 for _, v := range ints { 46 kinds = append(kinds, &TypeKind{v, strings.Title(v)}) 47 } 48 49 var lbuf bytes.Buffer 50 makeFuncSHL(&lbuf, kinds) 51 buf.Write(lbuf.Bytes()) 52 r := strings.NewReplacer("makeBinOpSHL", "makeBinOpSHR", "<<", ">>") 53 r.WriteString(&buf, lbuf.String()) 54 55 data, err := format.Source(buf.Bytes()) 56 if err != nil { 57 fmt.Println("format error", err) 58 fmt.Println(buf.String()) 59 os.Exit(2) 60 } 61 ioutil.WriteFile("./binop_shift.go", data, 0666) 62 } 63 64 func makeFuncSHL(buf *bytes.Buffer, kinds []*TypeKind) { 65 buf.WriteString(func_head_op) 66 // check x const && y const 67 buf.WriteString(`if kx == kindConst && ky == kindConst { 68 t := xtype.TypeOfType(xtyp) 69 switch xkind { 70 `) 71 for _, kx := range kinds { 72 buf.WriteString(fmt.Sprintf(` case reflect.%v: 73 x := xtype.%v(vx) 74 switch ykind { 75 `, kx.kind, kx.kind)) 76 for _, ky := range kinds { 77 buf.WriteString(fmt.Sprintf(`case reflect.%v: 78 v := xtype.Make(t, x << xtype.%v(vy)) 79 return func(fr *frame) { fr.setReg(ir,v) } 80 `, ky.kind, ky.kind)) 81 } 82 // end switch ykind 83 buf.WriteString("}\n") 84 } 85 86 // end switch xkind 87 buf.WriteString("}\n") 88 // end x const && y const 89 buf.WriteString("}\n") 90 91 buf.WriteString(`if xtyp.PkgPath() == "" { 92 switch xkind { 93 `) 94 for _, kx := range kinds { 95 buf.WriteString(fmt.Sprintf(` case reflect.%v: 96 `, kx.kind)) 97 // if x const 98 buf.WriteString(fmt.Sprintf(` if kx == kindConst { 99 x := vx.(%v) 100 `, kx.typ)) 101 buf.WriteString(fmt.Sprintf("\t\t\tswitch ykind {\n")) 102 for _, ky := range kinds { 103 buf.WriteString(fmt.Sprintf(`case reflect.%v: 104 return func(fr *frame) { fr.setReg(ir,x<<fr.%v(iy)) } 105 `, ky.kind, ky.typ)) 106 } 107 108 buf.WriteString(fmt.Sprintf("\t\t\t}\n")) 109 110 // else if y const 111 buf.WriteString("\t\t} else if ky == kindConst {\n") 112 buf.WriteString(fmt.Sprintf("\t\t\tswitch ykind {\n")) 113 for _, ky := range kinds { 114 buf.WriteString(fmt.Sprintf(`case reflect.%v: 115 y := xtype.%v(vy) 116 return func(fr *frame) { fr.setReg(ir,fr.reg(ix).(%v)<<y) } 117 `, ky.kind, ky.kind, kx.typ)) 118 } 119 buf.WriteString(fmt.Sprintf("\t\t\t}\n")) 120 121 // else x no const and y no const 122 buf.WriteString("\t} else {\n") 123 buf.WriteString("switch ykind {\n") 124 125 for _, ky := range kinds { 126 buf.WriteString(fmt.Sprintf(`case reflect.%v: 127 return func(fr *frame) { fr.setReg(ir,fr.reg(ix).(%v)<<fr.%v(iy)) } 128 `, ky.kind, kx.typ, ky.typ)) 129 } 130 buf.WriteString("}\n") // end swith ykind 131 buf.WriteString("}\n") 132 } 133 buf.WriteString("\t\t};") // end xkind 134 135 buf.WriteString("} else {") //end xtypIsBasic 136 137 // begin not xtype 138 buf.WriteString(` 139 t := xtype.TypeOfType(xtyp) 140 switch xkind { 141 `) 142 for _, kx := range kinds { 143 buf.WriteString(fmt.Sprintf(` case reflect.%v: 144 `, kx.kind)) 145 // if x const 146 buf.WriteString(fmt.Sprintf(` if kx == kindConst { 147 x := xtype.%v(vx) 148 `, kx.kind)) 149 buf.WriteString(fmt.Sprintf("\t\t\tswitch ykind {\n")) 150 for _, ky := range kinds { 151 buf.WriteString(fmt.Sprintf(`case reflect.%v: 152 return func(fr *frame) { fr.setReg(ir,xtype.Make(t,x<<fr.%v(iy))) } 153 `, ky.kind, ky.typ)) 154 } 155 156 buf.WriteString(fmt.Sprintf("\t\t\t}\n")) 157 158 // else if y const 159 buf.WriteString("\t\t} else if ky == kindConst {\n") 160 buf.WriteString(fmt.Sprintf("\t\t\tswitch ykind {\n")) 161 for _, ky := range kinds { 162 buf.WriteString(fmt.Sprintf(`case reflect.%v: 163 y := xtype.%v(vy) 164 return func(fr *frame) { fr.setReg(ir,xtype.Make(t,fr.%v(ix)<<y)) } 165 `, ky.kind, ky.kind, kx.typ)) 166 } 167 buf.WriteString(fmt.Sprintf("\t\t\t}\n")) 168 169 // else x no const and y no const 170 buf.WriteString("\t} else {\n") 171 buf.WriteString("switch ykind {\n") 172 173 for _, ky := range kinds { 174 buf.WriteString(fmt.Sprintf(`case reflect.%v: 175 return func(fr *frame) { fr.setReg(ir,xtype.Make(t,fr.%v(ix)<<fr.%v(iy))) } 176 `, ky.kind, kx.typ, ky.typ)) 177 } 178 buf.WriteString("}\n") // end swith ykind 179 buf.WriteString("}\n") 180 } 181 buf.WriteString("\t\t};") // end xkind 182 183 buf.WriteString("};") // end not xtype 184 185 buf.WriteString("\tpanic(\"unreachable\")\n}\n") 186 } 187 188 var pkg_head = `package igop 189 190 import ( 191 "reflect" 192 193 "github.com/visualfc/xtype" 194 "golang.org/x/tools/go/ssa" 195 ) 196 ` 197 198 var func_head_op = ` 199 func makeBinOpSHL(pfn *function, instr *ssa.BinOp) func(fr *frame) { 200 ir := pfn.regIndex(instr) 201 ix, kx, vx := pfn.regIndex3(instr.X) 202 iy, ky, vy := pfn.regIndex3(instr.Y) 203 xtyp := pfn.Interp.preToType(instr.X.Type()) 204 ytyp := pfn.Interp.preToType(instr.Y.Type()) 205 xkind := xtyp.Kind() 206 ykind := ytyp.Kind() 207 `