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  }