github.com/runner-mei/ql@v1.1.0/helper/helper.go (about) 1 // +build ignore 2 3 // Copyright 2014 The ql Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 package main 8 9 import ( 10 "bufio" 11 "flag" 12 "fmt" 13 "io" 14 "log" 15 "os" 16 ) 17 18 type t int 19 20 const ( 21 qNil t = iota 22 idealComplex 23 idealFloat 24 idealInt 25 idealRune 26 idealUint 27 qBool 28 qComplex64 29 qComplex128 30 qFloat32 31 qFloat64 32 qInt8 33 qInt16 34 qInt32 35 qInt64 36 qString 37 qUint8 38 qUint16 39 qUint32 40 qUint64 41 qBigInt 42 qBigRat 43 qTime 44 qDuration 45 46 qEnd 47 ) 48 49 func (n t) String() string { 50 switch n { 51 case qNil: 52 return "nil" 53 case idealComplex: 54 return "idealComplex" 55 case idealFloat: 56 return "idealFloat" 57 case idealInt: 58 return "idealInt" 59 case idealRune: 60 return "idealRune" 61 case idealUint: 62 return "idealUint" 63 case qBool: 64 return "bool" 65 case qComplex64: 66 return "complex64" 67 case qComplex128: 68 return "complex128" 69 case qFloat32: 70 return "float32" 71 case qFloat64: 72 return "float64" 73 case qInt8: 74 return "int8" 75 case qInt16: 76 return "int16" 77 case qInt32: 78 return "int32" 79 case qInt64: 80 return "int64" 81 case qString: 82 return "string" 83 case qUint8: 84 return "uint8" 85 case qUint16: 86 return "uint16" 87 case qUint32: 88 return "uint32" 89 case qUint64: 90 return "uint64" 91 case qBigInt: 92 return "*big.Int" 93 case qBigRat: 94 return "*big.Rat" 95 case qTime: 96 return "time.Time" 97 case qDuration: 98 return "time.Duration" 99 default: 100 panic("internal error 046") 101 } 102 } 103 104 func coerceIdealComplex(typ t) string { 105 switch typ { 106 case qComplex64, qComplex128: 107 return fmt.Sprintf("return %s(x)\n", typ) 108 default: 109 return "" 110 } 111 } 112 113 func coerceIdealFloat(typ t) string { 114 switch typ { 115 case idealComplex: 116 return fmt.Sprintf("return %s(complex(float64(x), 0))\n", typ) 117 case qComplex64: 118 return fmt.Sprintf("return %s(complex(float32(x), 0))\n", typ) 119 case qComplex128: 120 return fmt.Sprintf("return %s(complex(float64(x), 0))\n", typ) 121 case idealFloat, qFloat32, qFloat64: 122 return fmt.Sprintf("return %s(float64(x))\n", typ) 123 case qBigRat: 124 return fmt.Sprintf("return big.NewRat(1, 1).SetFloat64(float64(x))\n") 125 default: 126 return "" 127 } 128 return "" 129 } 130 131 func coerceIdealInt(typ t) string { 132 switch typ { 133 case idealComplex: 134 return fmt.Sprintf("return %s(complex(float64(x), 0))\n", typ) 135 case qComplex64: 136 return fmt.Sprintf("return %s(complex(float32(x), 0))\n", typ) 137 case qComplex128: 138 return fmt.Sprintf("return %s(complex(float64(x), 0))\n", typ) 139 case idealFloat, idealInt, qFloat32, qFloat64, qInt64: 140 return fmt.Sprintf("return %s(int64(x))\n", typ) 141 case idealUint: 142 return fmt.Sprintf("if x >= 0 { return %s(int64(x)) }\n", typ) 143 case qInt8: 144 return fmt.Sprintf("if x >= math.MinInt8 && x<= math.MaxInt8 { return %s(int64(x)) }\n", typ) 145 case qInt16: 146 return fmt.Sprintf("if x >= math.MinInt16 && x<= math.MaxInt16 { return %s(int64(x)) }\n", typ) 147 case qInt32: 148 return fmt.Sprintf("if x >= math.MinInt32 && x<= math.MaxInt32 { return %s(int64(x)) }\n", typ) 149 case qUint8: 150 return fmt.Sprintf("if x >= 0 && x<= math.MaxUint8 { return %s(int64(x)) }\n", typ) 151 case qUint16: 152 return fmt.Sprintf("if x >= 0 && x<= math.MaxUint16 { return %s(int64(x)) }\n", typ) 153 case qUint32: 154 return fmt.Sprintf("if x >= 0 && x<= math.MaxUint32 { return %s(int64(x)) }\n", typ) 155 case qUint64: 156 return fmt.Sprintf("if x >= 0 { return %s(int64(x)) }\n", typ) 157 case qBigInt: 158 return fmt.Sprintf("return big.NewInt(int64(x))\n") 159 case qBigRat: 160 return fmt.Sprintf("return big.NewRat(1, 1).SetInt64(int64(x))\n") 161 case qDuration: 162 return fmt.Sprintf("return time.Duration(int64(x))\n") 163 default: 164 return "" 165 } 166 return "" 167 } 168 169 func coerceIdealRune(typ t) string { 170 switch typ { 171 case idealComplex: 172 return fmt.Sprintf("return %s(complex(float64(x), 0))\n", typ) 173 case qComplex64: 174 return fmt.Sprintf("return %s(complex(float32(x), 0))\n", typ) 175 case qComplex128: 176 return fmt.Sprintf("return %s(complex(float64(x), 0))\n", typ) 177 case idealFloat, idealInt, idealRune, idealUint, qFloat32, qFloat64, qInt8, qInt16, qInt32, qInt64, qUint8, qUint16, qUint32, qUint64: 178 return fmt.Sprintf("return %s(int64(x))\n", typ) 179 case qBigInt: 180 return fmt.Sprintf("return big.NewInt(int64(x))\n") 181 case qBigRat: 182 return fmt.Sprintf("return big.NewRat(1, 1).SetInt64(int64(x))\n") 183 case qDuration: 184 return fmt.Sprintf("return time.Duration(int64(x))\n") 185 default: 186 return "" 187 } 188 return "" 189 } 190 191 func coerceIdealUint(typ t) string { 192 switch typ { 193 case idealComplex: 194 return fmt.Sprintf("return %s(complex(float64(x), 0))\n", typ) 195 case qComplex64: 196 return fmt.Sprintf("return %s(complex(float32(x), 0))\n", typ) 197 case qComplex128: 198 return fmt.Sprintf("return %s(complex(float64(x), 0))\n", typ) 199 case idealFloat, idealUint, qFloat32, qFloat64, qUint64: 200 return fmt.Sprintf("return %s(uint64(x))\n", typ) 201 case idealInt: 202 return fmt.Sprintf("if x <= math.MaxInt64 { return %s(int64(x)) }\n", typ) 203 case qInt8: 204 return fmt.Sprintf("if x <= math.MaxInt8 { return %s(int64(x)) }\n", typ) 205 case qInt16: 206 return fmt.Sprintf("if x<= math.MaxInt16 { return %s(int64(x)) }\n", typ) 207 case qInt32: 208 return fmt.Sprintf("if x<= math.MaxInt32 { return %s(int64(x)) }\n", typ) 209 case qInt64: 210 return fmt.Sprintf("if x<= math.MaxInt64 { return %s(int64(x)) }\n", typ) 211 case qUint8: 212 return fmt.Sprintf("if x >= 0 && x<= math.MaxUint8 { return %s(int64(x)) }\n", typ) 213 case qUint16: 214 return fmt.Sprintf("if x >= 0 && x<= math.MaxUint16 { return %s(int64(x)) }\n", typ) 215 case qUint32: 216 return fmt.Sprintf("if x >= 0 && x<= math.MaxUint32 { return %s(int64(x)) }\n", typ) 217 case qBigInt: 218 return fmt.Sprintf("return big.NewInt(0).SetUint64(uint64(x))\n") 219 case qBigRat: 220 return fmt.Sprintf("return big.NewRat(1, 1).SetInt(big.NewInt(0).SetUint64(uint64(x)))\n") 221 case qDuration: 222 return fmt.Sprintf("if x <= math.MaxInt64 { return time.Duration(int64(x)) }\n") 223 default: 224 return "" 225 } 226 return "" 227 } 228 229 func genCoerce1(w io.Writer, in t, f func(out t) string) { 230 fmt.Fprintf(w, "\tcase %s:\n", in) 231 fmt.Fprintf(w, "\t\tswitch otherVal.(type) {\n") 232 233 for i := idealComplex; i < qEnd; i++ { 234 s := f(i) 235 switch s { 236 case "": 237 fmt.Fprintf(w, "\t\t//case %s:\n", i) 238 default: 239 fmt.Fprintf(w, "\t\tcase %s:\n", i) 240 fmt.Fprintf(w, "\t\t\t%s", s) 241 } 242 } 243 244 fmt.Fprintf(w, "\t\t}\n") // switch 245 } 246 247 func genCoerce(w io.Writer) { 248 fmt.Fprintf(w, 249 ` 250 func coerce1(inVal, otherVal interface{}) (coercedInVal interface{}) { 251 coercedInVal = inVal 252 if otherVal == nil { 253 return 254 } 255 256 switch x := inVal.(type) { 257 case nil: 258 return 259 `) 260 genCoerce1(w, idealComplex, coerceIdealComplex) 261 genCoerce1(w, idealFloat, coerceIdealFloat) 262 genCoerce1(w, idealInt, coerceIdealInt) 263 genCoerce1(w, idealRune, coerceIdealRune) 264 genCoerce1(w, idealUint, coerceIdealUint) 265 fmt.Fprintf(w, "\t}\n") // switch 266 267 fmt.Fprintf(w, "\treturn\n}\n") // func 268 } 269 270 func main() { 271 ofn := flag.String("o", "", "") 272 flag.Parse() 273 _, err := os.Stat(*ofn) 274 if err == nil { 275 log.Fatalf("%s exists", *ofn) 276 } 277 278 w := bufio.NewWriter(os.Stdout) 279 if s := *ofn; s != "" { 280 f, err := os.Create(s) 281 if err != nil { 282 log.Fatal(err) 283 } 284 285 defer f.Close() 286 w = bufio.NewWriter(f) 287 } 288 defer w.Flush() 289 290 fmt.Fprintf(w, `// Copyright 2013 The ql Authors. All rights reserved. 291 // Use of this source code is governed by a BSD-style 292 // license that can be found in the LICENSE file. 293 294 // CAUTION: This file was generated automatically by 295 // 296 // $ go run helper/helper.go -o coerce.go 297 // 298 // DO NOT EDIT! 299 300 package ql 301 302 import ( 303 "math" 304 "math/big" 305 "reflect" 306 "time" 307 ) 308 309 func coerce(a, b interface{}) (x, y interface{}) { 310 if reflect.TypeOf(a) == reflect.TypeOf(b) { 311 return a, b 312 } 313 314 switch a.(type) { 315 case idealComplex, idealFloat, idealInt, idealRune, idealUint: 316 switch b.(type) { 317 case idealComplex, idealFloat, idealInt, idealRune, idealUint: 318 x, y = coerce1(a, b), b 319 if reflect.TypeOf(x) == reflect.TypeOf(y) { 320 return 321 } 322 323 return a, coerce1(b, a) 324 default: 325 return coerce1(a, b), b 326 } 327 default: 328 switch b.(type) { 329 case idealComplex, idealFloat, idealInt, idealRune, idealUint: 330 return a, coerce1(b, a) 331 default: 332 return a, b 333 } 334 } 335 } 336 `) 337 genCoerce(w) 338 }