github.com/switchupcb/yaegi@v0.10.2/internal/cmd/genop/genop.go (about)

     1  package main
     2  
     3  import (
     4  	"bytes"
     5  	"go/format"
     6  	"io/ioutil"
     7  	"log"
     8  	"strings"
     9  	"text/template"
    10  )
    11  
    12  const model = `package interp
    13  
    14  // Code generated by 'go run ../internal/cmd/genop/genop.go'. DO NOT EDIT.
    15  
    16  import (
    17  	"go/constant"
    18  	"go/token"
    19  	"reflect"
    20  )
    21  
    22  // Arithmetic operators
    23  {{range $name, $op := .Arithmetic}}
    24  func {{$name}}(n *node) {
    25  	next := getExec(n.tnext)
    26  	typ := n.typ.concrete().TypeOf()
    27  	isInterface := n.typ.TypeOf().Kind() == reflect.Interface
    28  	dest := genValueOutput(n, typ)
    29  	c0, c1 := n.child[0], n.child[1]
    30  
    31  	switch typ.Kind() {
    32  	{{- if $op.Str}}
    33  	case reflect.String:
    34  		switch {
    35  		case isInterface:
    36  			v0 := genValue(c0)
    37  			v1 := genValue(c1)
    38  			n.exec = func(f *frame) bltn {
    39  				dest(f).Set(reflect.ValueOf(v0(f).String() {{$op.Name}} v1(f).String()).Convert(typ))
    40  				return next
    41  			}
    42  		case c0.rval.IsValid():
    43  			s0 := vString(c0.rval)
    44  			v1 := genValue(c1)
    45  			n.exec = func(f *frame) bltn {
    46  				dest(f).SetString(s0 {{$op.Name}} v1(f).String())
    47  				return next
    48  			}
    49  		case c1.rval.IsValid():
    50  			v0 := genValue(c0)
    51  			s1 :=  vString(c1.rval)
    52  			n.exec = func(f *frame) bltn {
    53  				dest(f).SetString(v0(f).String() {{$op.Name}} s1)
    54  				return next
    55  			}
    56  		default:
    57  			v0 := genValue(c0)
    58  			v1 := genValue(c1)
    59  			n.exec = func(f *frame) bltn {
    60  				dest(f).SetString(v0(f).String() {{$op.Name}} v1(f).String())
    61  				return next
    62  			}
    63  		}
    64  	{{- end}}
    65  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    66  		switch {
    67  		case isInterface:
    68  			v0 := genValueInt(c0)
    69  			{{- if $op.Shift}}
    70  			v1 := genValueUint(c1)
    71  			{{else}}
    72  			v1 := genValueInt(c1)
    73  			{{end -}}
    74  			n.exec = func(f *frame) bltn {
    75  				_, i := v0(f)
    76  				_, j := v1(f)
    77  				dest(f).Set(reflect.ValueOf(i {{$op.Name}} j).Convert(typ))
    78  				return next
    79  			}
    80  		case c0.rval.IsValid():
    81  			i := vInt(c0.rval)
    82  			{{- if $op.Shift}}
    83  			v1 := genValueUint(c1)
    84  			{{else}}
    85  			v1 := genValueInt(c1)
    86  			{{end -}}
    87  			n.exec = func(f *frame) bltn {
    88  				_, j := v1(f)
    89  				dest(f).SetInt(i {{$op.Name}} j)
    90  				return next
    91  			}
    92  		case c1.rval.IsValid():
    93  			v0 := genValueInt(c0)
    94  			{{- if $op.Shift}}
    95  			j := vUint(c1.rval)
    96  			{{else}}
    97  			j := vInt(c1.rval)
    98  			{{end -}}
    99  			n.exec = func(f *frame) bltn {
   100  				_, i := v0(f)
   101  				dest(f).SetInt(i {{$op.Name}} j)
   102  				return next
   103  			}
   104  		default:
   105  			v0 := genValueInt(c0)
   106  			{{- if $op.Shift}}
   107  			v1 := genValueUint(c1)
   108  			{{else}}
   109  			v1 := genValueInt(c1)
   110  			{{end -}}
   111  			n.exec = func(f *frame) bltn {
   112  				_, i := v0(f)
   113  				_, j := v1(f)
   114  				dest(f).SetInt(i {{$op.Name}} j)
   115  				return next
   116  			}
   117  		}
   118  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   119  		switch {
   120  		case isInterface:
   121  			v0 := genValueUint(c0)
   122  			v1 := genValueUint(c1)
   123  			n.exec = func(f *frame) bltn {
   124  				_, i := v0(f)
   125  				_, j := v1(f)
   126  				dest(f).Set(reflect.ValueOf(i {{$op.Name}} j).Convert(typ))
   127  				return next
   128  			}
   129  		case c0.rval.IsValid():
   130  			i := vUint(c0.rval)
   131  			v1 := genValueUint(c1)
   132  			n.exec = func(f *frame) bltn {
   133  				_, j := v1(f)
   134  				dest(f).SetUint(i {{$op.Name}} j)
   135  				return next
   136  			}
   137  		case c1.rval.IsValid():
   138  			j := vUint(c1.rval)
   139  			v0 := genValueUint(c0)
   140  			n.exec = func(f *frame) bltn {
   141  				_, i := v0(f)
   142  				dest(f).SetUint(i {{$op.Name}} j)
   143  				return next
   144  			}
   145  		default:
   146  			v0 := genValueUint(c0)
   147  			v1 := genValueUint(c1)
   148  			n.exec = func(f *frame) bltn {
   149  				_, i := v0(f)
   150  				_, j := v1(f)
   151  				dest(f).SetUint(i {{$op.Name}} j)
   152  				return next
   153  			}
   154  		}
   155  	{{- if $op.Float}}
   156  	case reflect.Float32, reflect.Float64:
   157  		switch {
   158  		case isInterface:
   159  			v0 := genValueFloat(c0)
   160  			v1 := genValueFloat(c1)
   161  			n.exec = func(f *frame) bltn {
   162  				_, i := v0(f)
   163  				_, j := v1(f)
   164  				dest(f).Set(reflect.ValueOf(i {{$op.Name}} j).Convert(typ))
   165  				return next
   166  			}
   167  		case c0.rval.IsValid():
   168  			i := vFloat(c0.rval)
   169  			v1 := genValueFloat(c1)
   170  			n.exec = func(f *frame) bltn {
   171  				_, j := v1(f)
   172  				dest(f).SetFloat(i {{$op.Name}} j)
   173  				return next
   174  			}
   175  		case c1.rval.IsValid():
   176  			j := vFloat(c1.rval)
   177  			v0 := genValueFloat(c0)
   178  			n.exec = func(f *frame) bltn {
   179  				_, i := v0(f)
   180  				dest(f).SetFloat(i {{$op.Name}} j)
   181  				return next
   182  			}
   183  		default:
   184  			v0 := genValueFloat(c0)
   185  			v1 := genValueFloat(c1)
   186  			n.exec = func(f *frame) bltn {
   187  				_, i := v0(f)
   188  				_, j := v1(f)
   189  				dest(f).SetFloat(i {{$op.Name}} j)
   190  				return next
   191  			}
   192  		}
   193  	case reflect.Complex64, reflect.Complex128:
   194  		switch {
   195  		case isInterface:
   196  			v0 := genComplex(c0)
   197  			v1 := genComplex(c1)
   198  			n.exec = func(f *frame) bltn {
   199  				dest(f).Set(reflect.ValueOf(v0(f) {{$op.Name}} v1(f)).Convert(typ))
   200  				return next
   201  			}
   202  		case c0.rval.IsValid():
   203  			r0 := vComplex(c0.rval)
   204  			v1 := genComplex(c1)
   205  			n.exec = func(f *frame) bltn {
   206  				dest(f).SetComplex(r0 {{$op.Name}} v1(f))
   207  				return next
   208  			}
   209  		case c1.rval.IsValid():
   210  			r1 := vComplex(c1.rval)
   211  			v0 := genComplex(c0)
   212  			n.exec = func(f *frame) bltn {
   213  				dest(f).SetComplex(v0(f) {{$op.Name}} r1)
   214  				return next
   215  			}
   216  		default:
   217  			v0 := genComplex(c0)
   218  			v1 := genComplex(c1)
   219  			n.exec = func(f *frame) bltn {
   220  				dest(f).SetComplex(v0(f) {{$op.Name}} v1(f))
   221  				return next
   222  			}
   223  		}
   224  	{{- end}}
   225  	}
   226  }
   227  
   228  func {{$name}}Const(n *node) {
   229  	v0, v1 := n.child[0].rval, n.child[1].rval
   230  	{{- if $op.Shift}}
   231  	isConst := (v0.IsValid() && isConstantValue(v0.Type()))
   232  	{{- else}}
   233  	isConst := (v0.IsValid() && isConstantValue(v0.Type())) && (v1.IsValid() && isConstantValue(v1.Type()))
   234  	{{- end}}
   235  	t := n.typ.rtype
   236  	if isConst {
   237  		t = constVal
   238  	}
   239  	n.rval = reflect.New(t).Elem()
   240  	switch {
   241  	case isConst:
   242  		{{- if $op.Shift}}
   243  		v := constant.Shift(vConstantValue(v0), token.{{tokenFromName $name}}, uint(vUint(v1)))
   244  		n.rval.Set(reflect.ValueOf(v))
   245  		{{- else if (eq $op.Name "/")}}
   246  		var operator token.Token
   247  		// When the result of the operation is expected to be an int (because both
   248  		// operands are ints), we want to force the type of the whole expression to be an
   249  		// int (and not a float), which is achieved by using the QUO_ASSIGN operator.
   250  		if n.typ.untyped && isInt(n.typ.rtype) {
   251  			operator = token.QUO_ASSIGN
   252  		} else {
   253  			operator = token.QUO
   254  		}
   255  		v := constant.BinaryOp(vConstantValue(v0), operator, vConstantValue(v1))
   256  		n.rval.Set(reflect.ValueOf(v))
   257  		{{- else}}
   258  		{{- if $op.Int}}
   259  		v := constant.BinaryOp(constant.ToInt(vConstantValue(v0)), token.{{tokenFromName $name}}, constant.ToInt(vConstantValue(v1)))
   260  		{{- else}}
   261  		v := constant.BinaryOp(vConstantValue(v0), token.{{tokenFromName $name}}, vConstantValue(v1))
   262  		{{- end}}
   263  		n.rval.Set(reflect.ValueOf(v))
   264  		{{- end}}
   265  	{{- if $op.Str}}
   266  	case isString(t):
   267  		n.rval.SetString(vString(v0) {{$op.Name}} vString(v1))
   268  	{{- end}}
   269  	{{- if $op.Float}}
   270  	case isComplex(t):
   271  		n.rval.SetComplex(vComplex(v0) {{$op.Name}} vComplex(v1))
   272  	case isFloat(t):
   273  		n.rval.SetFloat(vFloat(v0) {{$op.Name}} vFloat(v1))
   274  	{{- end}}
   275  	case isUint(t):
   276  		n.rval.SetUint(vUint(v0) {{$op.Name}} vUint(v1))
   277  	case isInt(t):
   278  		{{- if $op.Shift}}
   279  		n.rval.SetInt(vInt(v0) {{$op.Name}} vUint(v1))
   280  		{{- else}}
   281  		n.rval.SetInt(vInt(v0) {{$op.Name}} vInt(v1))
   282  		{{- end}}
   283  	}
   284  }
   285  {{end}}
   286  // Assign operators
   287  {{range $name, $op := .Arithmetic}}
   288  func {{$name}}Assign(n *node) {
   289  	next := getExec(n.tnext)
   290  	typ := n.typ.TypeOf()
   291  	c0, c1 := n.child[0], n.child[1]
   292  	setMap := isMapEntry(c0)
   293  	var mapValue, indexValue func(*frame) reflect.Value
   294  
   295  	if setMap {
   296          mapValue = genValue(c0.child[0])
   297          indexValue = genValue(c0.child[1])
   298      }
   299  
   300  	if c1.rval.IsValid() {
   301  		switch typ.Kind() {
   302  		{{- if $op.Str}}
   303  		case reflect.String:
   304  			v0 := genValueString(c0)
   305  			v1 := vString(c1.rval)
   306  			n.exec = func(f *frame) bltn {
   307  				v, s := v0(f)
   308  				v.SetString(s {{$op.Name}} v1)
   309  				if setMap {
   310  					mapValue(f).SetMapIndex(indexValue(f), v)
   311  				}
   312  				return next
   313  			}
   314  		{{- end}}
   315  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   316  			v0 := genValueInt(c0)
   317  			{{- if $op.Shift}}
   318  			j := vUint(c1.rval)
   319  			{{else}}
   320  			j := vInt(c1.rval)
   321  			{{end -}}
   322  			n.exec = func(f *frame) bltn {
   323  				v, i := v0(f)
   324  				v.SetInt(i {{$op.Name}} j)
   325  				if setMap {
   326  					mapValue(f).SetMapIndex(indexValue(f), v)
   327  				}
   328  				return next
   329  			}
   330  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   331  			v0 := genValueUint(c0)
   332  			j := vUint(c1.rval)
   333  			n.exec = func(f *frame) bltn {
   334  				v, i := v0(f)
   335  				v.SetUint(i {{$op.Name}} j)
   336  				if setMap {
   337  					mapValue(f).SetMapIndex(indexValue(f), v)
   338  				}
   339  				return next
   340  			}
   341  		{{- if $op.Float}}
   342  		case reflect.Float32, reflect.Float64:
   343  			v0 := genValueFloat(c0)
   344  			j := vFloat(c1.rval)
   345  			n.exec = func(f *frame) bltn {
   346  				v, i := v0(f)
   347  				v.SetFloat(i {{$op.Name}} j)
   348  				if setMap {
   349  					mapValue(f).SetMapIndex(indexValue(f), v)
   350  				}
   351  				return next
   352  			}
   353  		case reflect.Complex64, reflect.Complex128:
   354  			v0 := genValue(c0)
   355  			v1 := vComplex(c1.rval)
   356  			n.exec = func(f *frame) bltn {
   357  				v := v0(f)
   358  				v.SetComplex(v.Complex() {{$op.Name}} v1)
   359  				if setMap {
   360  					mapValue(f).SetMapIndex(indexValue(f), v)
   361  				}
   362  				return next
   363  			}
   364  		{{- end}}
   365  		}
   366  	} else {
   367  		switch typ.Kind() {
   368  		{{- if $op.Str}}
   369  		case reflect.String:
   370  			v0 := genValueString(c0)
   371  			v1 := genValue(c1)
   372  			n.exec = func(f *frame) bltn {
   373  				v, s := v0(f)
   374  				v.SetString(s {{$op.Name}} v1(f).String())
   375  				if setMap {
   376  					mapValue(f).SetMapIndex(indexValue(f), v)
   377  				}
   378  				return next
   379  			}
   380  		{{- end}}
   381  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   382  			v0 := genValueInt(c0)
   383  			{{- if $op.Shift}}
   384  			v1 := genValueUint(c1)
   385  			{{else}}
   386  			v1 := genValueInt(c1)
   387  			{{end -}}
   388  			n.exec = func(f *frame) bltn {
   389  				v, i := v0(f)
   390  				_, j := v1(f)
   391  				v.SetInt(i {{$op.Name}} j)
   392  				if setMap {
   393  					mapValue(f).SetMapIndex(indexValue(f), v)
   394  				}
   395  				return next
   396  			}
   397  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   398  			v0 := genValueUint(c0)
   399  			v1 := genValueUint(c1)
   400  			n.exec = func(f *frame) bltn {
   401  				v, i := v0(f)
   402  				_, j := v1(f)
   403  				v.SetUint(i {{$op.Name}} j)
   404  				if setMap {
   405  					mapValue(f).SetMapIndex(indexValue(f), v)
   406  				}
   407  				return next
   408  			}
   409  		{{- if $op.Float}}
   410  		case reflect.Float32, reflect.Float64:
   411  			v0 := genValueFloat(c0)
   412  			v1 := genValueFloat(c1)
   413  			n.exec = func(f *frame) bltn {
   414  				v, i := v0(f)
   415  				_, j := v1(f)
   416  				v.SetFloat(i {{$op.Name}} j)
   417  				if setMap {
   418  					mapValue(f).SetMapIndex(indexValue(f), v)
   419  				}
   420  				return next
   421  			}
   422  		case reflect.Complex64, reflect.Complex128:
   423  			v0 := genValue(c0)
   424  			v1 := genValue(c1)
   425  			n.exec = func(f *frame) bltn {
   426  				v := v0(f)
   427  				v.SetComplex(v.Complex() {{$op.Name}} v1(f).Complex())
   428  				if setMap {
   429  					mapValue(f).SetMapIndex(indexValue(f), v)
   430  				}
   431  				return next
   432  			}
   433  		{{- end}}
   434  		}
   435  	}
   436  }
   437  {{end}}
   438  {{range $name, $op := .IncDec}}
   439  func {{$name}}(n *node) {
   440  	next := getExec(n.tnext)
   441  	typ := n.typ.TypeOf()
   442  	c0 := n.child[0]
   443  	setMap := isMapEntry(c0)
   444  	var mapValue, indexValue func(*frame) reflect.Value
   445  
   446  	if setMap {
   447          mapValue = genValue(c0.child[0])
   448          indexValue = genValue(c0.child[1])
   449      }
   450  
   451  	switch typ.Kind() {
   452  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   453  		v0 := genValueInt(c0)
   454  		n.exec = func(f *frame) bltn {
   455  			v, i := v0(f)
   456  			v.SetInt(i {{$op.Name}} 1)
   457  			if setMap {
   458                  mapValue(f).SetMapIndex(indexValue(f), v)
   459              }
   460  			return next
   461  		}
   462  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   463  		v0 := genValueUint(c0)
   464  		n.exec = func(f *frame) bltn {
   465  			v, i := v0(f)
   466  			v.SetUint(i {{$op.Name}} 1)
   467  			if setMap {
   468                  mapValue(f).SetMapIndex(indexValue(f), v)
   469              }
   470  			return next
   471  		}
   472  	case reflect.Float32, reflect.Float64:
   473  		v0 := genValueFloat(c0)
   474  		n.exec = func(f *frame) bltn {
   475  			v, i := v0(f)
   476  			v.SetFloat(i {{$op.Name}} 1)
   477  			if setMap {
   478                  mapValue(f).SetMapIndex(indexValue(f), v)
   479              }
   480  			return next
   481  		}
   482  	case reflect.Complex64, reflect.Complex128:
   483  		v0 := genValue(c0)
   484  		n.exec = func(f *frame) bltn {
   485  			v := v0(f)
   486  			v.SetComplex(v.Complex() {{$op.Name}} 1)
   487  			if setMap {
   488                  mapValue(f).SetMapIndex(indexValue(f), v)
   489              }
   490  			return next
   491  		}
   492  	}
   493  }
   494  {{end}}
   495  {{range $name, $op := .Unary}}
   496  func {{$name}}Const(n *node) {
   497  	v0 := n.child[0].rval
   498  	isConst := v0.IsValid() && isConstantValue(v0.Type())
   499  	t := n.typ.rtype
   500  	if isConst {
   501  		t = constVal
   502  	}
   503  	n.rval = reflect.New(t).Elem()
   504  
   505  	{{- if $op.Bool}}
   506  	if isConst {
   507  		v := constant.UnaryOp(token.{{tokenFromName $name}}, vConstantValue(v0), 0)
   508  		n.rval.Set(reflect.ValueOf(v))
   509  	} else {
   510  		n.rval.SetBool({{$op.Name}} v0.Bool())
   511  	}
   512  	{{- else}}
   513  	switch {
   514  	case isConst:
   515  		v := constant.UnaryOp(token.{{tokenFromName $name}}, vConstantValue(v0), 0)
   516  		n.rval.Set(reflect.ValueOf(v))
   517  	case isUint(t):
   518  		n.rval.SetUint({{$op.Name}} v0.Uint())
   519  	case isInt(t):
   520  		n.rval.SetInt({{$op.Name}} v0.Int())
   521  	{{- if $op.Float}}
   522  	case isFloat(t):
   523  		n.rval.SetFloat({{$op.Name}} v0.Float())
   524  	case isComplex(t):
   525  		n.rval.SetComplex({{$op.Name}} v0.Complex())
   526  	{{- end}}
   527  	}
   528  	{{- end}}
   529  }
   530  {{end}}
   531  {{range $name, $op := .Comparison}}
   532  func {{$name}}(n *node) {
   533  	tnext := getExec(n.tnext)
   534  	dest := genValueOutput(n, reflect.TypeOf(true))
   535  	typ := n.typ.concrete().TypeOf()
   536  	isInterface := n.typ.TypeOf().Kind() == reflect.Interface
   537  	c0, c1 := n.child[0], n.child[1]
   538  
   539  	{{- if or (eq $op.Name "==") (eq $op.Name "!=") }}
   540  
   541  	if c0.typ.cat == aliasT || c1.typ.cat == aliasT {
   542  		switch {
   543  		case isInterface:
   544  			v0 := genValue(c0)
   545  			v1 := genValue(c1)
   546  			dest := genValue(n)
   547  			n.exec = func(f *frame) bltn {
   548  				i0 := v0(f).Interface()
   549  				i1 := v1(f).Interface()
   550  				dest(f).Set(reflect.ValueOf(i0 {{$op.Name}} i1).Convert(typ))
   551  				return tnext
   552  			}
   553  		case c0.rval.IsValid():
   554  			i0 := c0.rval.Interface()
   555  			v1 := genValue(c1)
   556  			if n.fnext != nil {
   557  				fnext := getExec(n.fnext)
   558  				n.exec = func(f *frame) bltn {
   559  					i1 := v1(f).Interface()
   560  					if i0 != i1 {
   561  						dest(f).SetBool(true)
   562  						return tnext
   563  					}
   564  					dest(f).SetBool(false)
   565  					return fnext
   566  				}
   567  			} else {
   568  				dest := genValue(n)
   569  				n.exec = func(f *frame) bltn {
   570  					i1 := v1(f).Interface()
   571  					dest(f).SetBool(i0 {{$op.Name}} i1)
   572  					return tnext
   573  				}
   574  			}
   575  		case c1.rval.IsValid():
   576  			i1 := c1.rval.Interface()
   577  			v0 := genValue(c0)
   578  			if n.fnext != nil {
   579  				fnext := getExec(n.fnext)
   580  				n.exec = func(f *frame) bltn {
   581  					i0 := v0(f).Interface()
   582  					if i0 != i1 {
   583  						dest(f).SetBool(true)
   584  						return tnext
   585  					}
   586  					dest(f).SetBool(false)
   587  					return fnext
   588  				}
   589  			} else {
   590  				dest := genValue(n)
   591  				n.exec = func(f *frame) bltn {
   592  					i0 := v0(f).Interface()
   593  					dest(f).SetBool(i0 {{$op.Name}} i1)
   594  					return tnext
   595  				}
   596  			}
   597  		default:
   598  			v0 := genValue(c0)
   599  			v1 := genValue(c1)
   600  			if n.fnext != nil {
   601  				fnext := getExec(n.fnext)
   602  				n.exec = func(f *frame) bltn {
   603  					i0 := v0(f).Interface()
   604  					i1 := v1(f).Interface()
   605  					if i0 != i1 {
   606  						dest(f).SetBool(true)
   607  						return tnext
   608  					}
   609  					dest(f).SetBool(false)
   610  					return fnext
   611  				}
   612  			} else {
   613  				dest := genValue(n)
   614  				n.exec = func(f *frame) bltn {
   615  					i0 := v0(f).Interface()
   616  					i1 := v1(f).Interface()
   617  					dest(f).SetBool(i0 {{$op.Name}} i1)
   618  					return tnext
   619  				}
   620  			}
   621  		}
   622  		return
   623  	}
   624  	{{- end}}
   625  
   626  	switch t0, t1 := c0.typ.TypeOf(), c1.typ.TypeOf(); {
   627  	case isString(t0) || isString(t1):
   628  		switch {
   629  		case isInterface:
   630  			v0 := genValueString(c0)
   631  			v1 := genValueString(c1)
   632  			n.exec = func(f *frame) bltn {
   633  				_, s0 := v0(f)
   634  				_, s1 := v1(f)
   635  				dest(f).Set(reflect.ValueOf(s0 {{$op.Name}} s1).Convert(typ))
   636  				return tnext
   637  			}
   638  		case c0.rval.IsValid():
   639  			s0 :=  vString(c0.rval)
   640  			v1 := genValueString(c1)
   641  			if n.fnext != nil {
   642  				fnext := getExec(n.fnext)
   643  				n.exec = func(f *frame) bltn {
   644  					_, s1 := v1(f)
   645  					if s0 {{$op.Name}} s1 {
   646  						dest(f).SetBool(true)
   647  						return tnext
   648  					}
   649  					dest(f).SetBool(false)
   650  					return fnext
   651  				}
   652  			} else {
   653  				n.exec = func(f *frame) bltn {
   654  					_, s1 := v1(f)
   655  					dest(f).SetBool(s0 {{$op.Name}} s1)
   656  					return tnext
   657  				}
   658  			}
   659  		case c1.rval.IsValid():
   660  			s1 :=  vString(c1.rval)
   661  			v0 := genValueString(c0)
   662  			if n.fnext != nil {
   663  				fnext := getExec(n.fnext)
   664  				n.exec = func(f *frame) bltn {
   665  					_, s0 := v0(f)
   666  					if s0 {{$op.Name}} s1 {
   667  						dest(f).SetBool(true)
   668  						return tnext
   669  					}
   670  					dest(f).SetBool(false)
   671  					return fnext
   672  				}
   673  			} else {
   674  				n.exec = func(f *frame) bltn {
   675  					_, s0 := v0(f)
   676  					dest(f).SetBool(s0 {{$op.Name}} s1)
   677  					return tnext
   678  				}
   679  			}
   680  		default:
   681  			v0 := genValueString(c0)
   682  			v1 := genValueString(c1)
   683  			if n.fnext != nil {
   684  				fnext := getExec(n.fnext)
   685  				n.exec = func(f *frame) bltn {
   686  					_, s0 := v0(f)
   687  					_, s1 := v1(f)
   688  					if s0 {{$op.Name}} s1 {
   689  						dest(f).SetBool(true)
   690  						return tnext
   691  					}
   692  					dest(f).SetBool(false)
   693  					return fnext
   694  				}
   695  			} else {
   696  				n.exec = func(f *frame) bltn {
   697  					_, s0 := v0(f)
   698  					_, s1 := v1(f)
   699  					dest(f).SetBool(s0 {{$op.Name}} s1)
   700  					return tnext
   701  				}
   702  			}
   703  		}
   704  	case isFloat(t0) || isFloat(t1):
   705  		switch {
   706  		case isInterface:
   707  			v0 := genValueFloat(c0)
   708  			v1 := genValueFloat(c1)
   709  			n.exec = func(f *frame) bltn {
   710  				_, s0 := v0(f)
   711  				_, s1 := v1(f)
   712  				dest(f).Set(reflect.ValueOf(s0 {{$op.Name}} s1).Convert(typ))
   713  				return tnext
   714  			}
   715  		case c0.rval.IsValid():
   716  			s0 := vFloat(c0.rval)
   717  			v1 := genValueFloat(c1)
   718  			if n.fnext != nil {
   719  				fnext := getExec(n.fnext)
   720  				n.exec = func(f *frame) bltn {
   721  					_, s1 := v1(f)
   722  					if s0 {{$op.Name}} s1 {
   723  						dest(f).SetBool(true)
   724  						return tnext
   725  					}
   726  					dest(f).SetBool(false)
   727  					return fnext
   728  				}
   729  			} else {
   730  				n.exec = func(f *frame) bltn {
   731  					_, s1 := v1(f)
   732  					dest(f).SetBool(s0 {{$op.Name}} s1)
   733  					return tnext
   734  				}
   735  			}
   736  		case c1.rval.IsValid():
   737  			s1 := vFloat(c1.rval)
   738  			v0 := genValueFloat(c0)
   739  			if n.fnext != nil {
   740  				fnext := getExec(n.fnext)
   741  				n.exec = func(f *frame) bltn {
   742  					_, s0 := v0(f)
   743  					if s0 {{$op.Name}} s1 {
   744  						dest(f).SetBool(true)
   745  						return tnext
   746  					}
   747  					dest(f).SetBool(false)
   748  					return fnext
   749  				}
   750  			} else {
   751  				dest := genValue(n)
   752  				n.exec = func(f *frame) bltn {
   753  					_, s0 := v0(f)
   754  					dest(f).SetBool(s0 {{$op.Name}} s1)
   755  					return tnext
   756  				}
   757  			}
   758  		default:
   759  			v0 := genValueFloat(c0)
   760  			v1 := genValueFloat(c1)
   761  			if n.fnext != nil {
   762  				fnext := getExec(n.fnext)
   763  				n.exec = func(f *frame) bltn {
   764  					_, s0 := v0(f)
   765  					_, s1 := v1(f)
   766  					if s0 {{$op.Name}} s1 {
   767  						dest(f).SetBool(true)
   768  						return tnext
   769  					}
   770  					dest(f).SetBool(false)
   771  					return fnext
   772  				}
   773  			} else {
   774  				dest := genValue(n)
   775  				n.exec = func(f *frame) bltn {
   776  					_, s0 := v0(f)
   777  					_, s1 := v1(f)
   778  					dest(f).SetBool(s0 {{$op.Name}} s1)
   779  					return tnext
   780  				}
   781  			}
   782  		}
   783  	case isUint(t0) || isUint(t1):
   784  		switch {
   785  		case isInterface:
   786  			v0 := genValueUint(c0)
   787  			v1 := genValueUint(c1)
   788  			n.exec = func(f *frame) bltn {
   789  				_, s0 := v0(f)
   790  				_, s1 := v1(f)
   791  				dest(f).Set(reflect.ValueOf(s0 {{$op.Name}} s1).Convert(typ))
   792  				return tnext
   793  			}
   794  		case c0.rval.IsValid():
   795  			s0 := vUint(c0.rval)
   796  			v1 := genValueUint(c1)
   797  			if n.fnext != nil {
   798  				fnext := getExec(n.fnext)
   799  				n.exec = func(f *frame) bltn {
   800  					_, s1 := v1(f)
   801  					if s0 {{$op.Name}} s1 {
   802  						dest(f).SetBool(true)
   803  						return tnext
   804  					}
   805  					dest(f).SetBool(false)
   806  					return fnext
   807  				}
   808  			} else {
   809  				dest := genValue(n)
   810  				n.exec = func(f *frame) bltn {
   811  					_, s1 := v1(f)
   812  					dest(f).SetBool(s0 {{$op.Name}} s1)
   813  					return tnext
   814  				}
   815  			}
   816  		case c1.rval.IsValid():
   817  			s1 := vUint(c1.rval)
   818  			v0 := genValueUint(c0)
   819  			if n.fnext != nil {
   820  				fnext := getExec(n.fnext)
   821  				n.exec = func(f *frame) bltn {
   822  					_, s0 := v0(f)
   823  					if s0 {{$op.Name}} s1 {
   824  						dest(f).SetBool(true)
   825  						return tnext
   826  					}
   827  					dest(f).SetBool(false)
   828  					return fnext
   829  				}
   830  			} else {
   831  				dest := genValue(n)
   832  				n.exec = func(f *frame) bltn {
   833  					_, s0 := v0(f)
   834  					dest(f).SetBool(s0 {{$op.Name}} s1)
   835  					return tnext
   836  				}
   837  			}
   838  		default:
   839  			v0 := genValueUint(c0)
   840  			v1 := genValueUint(c1)
   841  			if n.fnext != nil {
   842  				fnext := getExec(n.fnext)
   843  				n.exec = func(f *frame) bltn {
   844  					_, s0 := v0(f)
   845  					_, s1 := v1(f)
   846  					if s0 {{$op.Name}} s1 {
   847  						dest(f).SetBool(true)
   848  						return tnext
   849  					}
   850  					dest(f).SetBool(false)
   851  					return fnext
   852  				}
   853  			} else {
   854  				dest := genValue(n)
   855  				n.exec = func(f *frame) bltn {
   856  					_, s0 := v0(f)
   857  					_, s1 := v1(f)
   858  					dest(f).SetBool(s0 {{$op.Name}} s1)
   859  					return tnext
   860  				}
   861  			}
   862  		}
   863  	case isInt(t0) || isInt(t1):
   864  		switch {
   865  		case isInterface:
   866  			v0 := genValueInt(c0)
   867  			v1 := genValueInt(c1)
   868  			n.exec = func(f *frame) bltn {
   869  				_, s0 := v0(f)
   870  				_, s1 := v1(f)
   871  				dest(f).Set(reflect.ValueOf(s0 {{$op.Name}} s1).Convert(typ))
   872  				return tnext
   873  			}
   874  		case c0.rval.IsValid():
   875  			s0 := vInt(c0.rval)
   876  			v1 := genValueInt(c1)
   877  			if n.fnext != nil {
   878  				fnext := getExec(n.fnext)
   879  				n.exec = func(f *frame) bltn {
   880  					_, s1 := v1(f)
   881  					if s0 {{$op.Name}} s1 {
   882  						dest(f).SetBool(true)
   883  						return tnext
   884  					}
   885  					dest(f).SetBool(false)
   886  					return fnext
   887  				}
   888  			} else {
   889  				dest := genValue(n)
   890  				n.exec = func(f *frame) bltn {
   891  					_, s1 := v1(f)
   892  					dest(f).SetBool(s0 {{$op.Name}} s1)
   893  					return tnext
   894  				}
   895  			}
   896  		case c1.rval.IsValid():
   897  			s1 := vInt(c1.rval)
   898  			v0 := genValueInt(c0)
   899  			if n.fnext != nil {
   900  				fnext := getExec(n.fnext)
   901  				n.exec = func(f *frame) bltn {
   902  					_, s0 := v0(f)
   903  					if s0 {{$op.Name}} s1 {
   904  						dest(f).SetBool(true)
   905  						return tnext
   906  					}
   907  					dest(f).SetBool(false)
   908  					return fnext
   909  				}
   910  			} else {
   911  				dest := genValue(n)
   912  				n.exec = func(f *frame) bltn {
   913  					_, s0 := v0(f)
   914  					dest(f).SetBool(s0 {{$op.Name}} s1)
   915  					return tnext
   916  				}
   917  			}
   918  		default:
   919  			v0 := genValueInt(c0)
   920  			v1 := genValueInt(c1)
   921  			if n.fnext != nil {
   922  				fnext := getExec(n.fnext)
   923  				n.exec = func(f *frame) bltn {
   924  					_, s0 := v0(f)
   925  					_, s1 := v1(f)
   926  					if s0 {{$op.Name}} s1 {
   927  						dest(f).SetBool(true)
   928  						return tnext
   929  					}
   930  					dest(f).SetBool(false)
   931  					return fnext
   932  				}
   933  			} else {
   934  				dest := genValue(n)
   935  				n.exec = func(f *frame) bltn {
   936  					_, s0 := v0(f)
   937  					_, s1 := v1(f)
   938  					dest(f).SetBool(s0 {{$op.Name}} s1)
   939  					return tnext
   940  				}
   941  			}
   942  		}
   943  	{{- if $op.Complex}}
   944  	case isComplex(t0) || isComplex(t1):
   945  		switch {
   946  		case isInterface:
   947  			v0 := genComplex(c0)
   948  			v1 := genComplex(c1)
   949  			n.exec = func(f *frame) bltn {
   950  				s0 := v0(f)
   951  				s1 := v1(f)
   952  				dest(f).Set(reflect.ValueOf(s0 {{$op.Name}} s1).Convert(typ))
   953  				return tnext
   954  			}
   955  		case c0.rval.IsValid():
   956  			s0 := vComplex(c0.rval)
   957  			v1 := genComplex(c1)
   958  			if n.fnext != nil {
   959  				fnext := getExec(n.fnext)
   960  				n.exec = func(f *frame) bltn {
   961  					s1 := v1(f)
   962  					if s0 {{$op.Name}} s1 {
   963  						dest(f).SetBool(true)
   964  						return tnext
   965  					}
   966  					dest(f).SetBool(false)
   967  					return fnext
   968  				}
   969  			} else {
   970  				n.exec = func(f *frame) bltn {
   971  					s1 := v1(f)
   972  					dest(f).SetBool(s0 {{$op.Name}} s1)
   973  					return tnext
   974  				}
   975  			}
   976  		case c1.rval.IsValid():
   977  			s1 := vComplex(c1.rval)
   978  			v0 := genComplex(c0)
   979  			if n.fnext != nil {
   980  				fnext := getExec(n.fnext)
   981  				n.exec = func(f *frame) bltn {
   982  					s0 := v0(f)
   983  					if s0 {{$op.Name}} s1 {
   984  						dest(f).SetBool(true)
   985  						return tnext
   986  					}
   987  					dest(f).SetBool(false)
   988  					return fnext
   989  				}
   990  			} else {
   991  				dest := genValue(n)
   992  				n.exec = func(f *frame) bltn {
   993  					s0 := v0(f)
   994  					dest(f).SetBool(s0 {{$op.Name}} s1)
   995  					return tnext
   996  				}
   997  			}
   998  		default:
   999  			v0 := genComplex(c0)
  1000  			v1 := genComplex(c1)
  1001  			if n.fnext != nil {
  1002  				fnext := getExec(n.fnext)
  1003  				n.exec = func(f *frame) bltn {
  1004  					s0 := v0(f)
  1005  					s1 := v1(f)
  1006  					if s0 {{$op.Name}} s1 {
  1007  						dest(f).SetBool(true)
  1008  						return tnext
  1009  					}
  1010  					dest(f).SetBool(false)
  1011  					return fnext
  1012  				}
  1013  			} else {
  1014  				n.exec = func(f *frame) bltn {
  1015  					s0 := v0(f)
  1016  					s1 := v1(f)
  1017  					dest(f).SetBool(s0 {{$op.Name}} s1)
  1018  					return tnext
  1019  				}
  1020  			}
  1021  		}
  1022  	default:
  1023  		switch {
  1024  		case isInterface:
  1025  			v0 := genValue(c0)
  1026  			v1 := genValue(c1)
  1027  			n.exec = func(f *frame) bltn {
  1028  				i0 := v0(f).Interface()
  1029  				i1 := v1(f).Interface()
  1030  				dest(f).Set(reflect.ValueOf(i0 {{$op.Name}} i1).Convert(typ))
  1031  				return tnext
  1032  			}
  1033  		case c0.rval.IsValid():
  1034  			i0 := c0.rval.Interface()
  1035  			v1 := genValue(c1)
  1036  			if n.fnext != nil {
  1037  				fnext := getExec(n.fnext)
  1038  				n.exec = func(f *frame) bltn {
  1039  					i1 := v1(f).Interface()
  1040  					if i0 {{$op.Name}} i1 {
  1041  						dest(f).SetBool(true)
  1042  						return tnext
  1043  					}
  1044  					dest(f).SetBool(false)
  1045  					return fnext
  1046  				}
  1047  			} else {
  1048  				dest := genValue(n)
  1049  				n.exec = func(f *frame) bltn {
  1050  					i1 := v1(f).Interface()
  1051  					dest(f).SetBool(i0 {{$op.Name}} i1)
  1052  					return tnext
  1053  				}
  1054  			}
  1055  		case c1.rval.IsValid():
  1056  			i1 := c1.rval.Interface()
  1057  			v0 := genValue(c0)
  1058  			if n.fnext != nil {
  1059  				fnext := getExec(n.fnext)
  1060  				n.exec = func(f *frame) bltn {
  1061  					i0 := v0(f).Interface()
  1062  					if i0 {{$op.Name}} i1 {
  1063  						dest(f).SetBool(true)
  1064  						return tnext
  1065  					}
  1066  					dest(f).SetBool(false)
  1067  					return fnext
  1068  				}
  1069  			} else {
  1070  				dest := genValue(n)
  1071  				n.exec = func(f *frame) bltn {
  1072  					i0 := v0(f).Interface()
  1073  					dest(f).SetBool(i0 {{$op.Name}} i1)
  1074  					return tnext
  1075  				}
  1076  			}
  1077  		default:
  1078  			v0 := genValue(c0)
  1079  			v1 := genValue(c1)
  1080  			if n.fnext != nil {
  1081  				fnext := getExec(n.fnext)
  1082  				n.exec = func(f *frame) bltn {
  1083  					i0 := v0(f).Interface()
  1084  					i1 := v1(f).Interface()
  1085  					if i0 {{$op.Name}} i1 {
  1086  						dest(f).SetBool(true)
  1087  						return tnext
  1088  					}
  1089  					dest(f).SetBool(false)
  1090  					return fnext
  1091  				}
  1092  			} else {
  1093  				dest := genValue(n)
  1094  				n.exec = func(f *frame) bltn {
  1095  					i0 := v0(f).Interface()
  1096  					i1 := v1(f).Interface()
  1097  					dest(f).SetBool(i0 {{$op.Name}} i1)
  1098  					return tnext
  1099  				}
  1100  			}
  1101  		}
  1102  	{{- end}}
  1103  	}
  1104  }
  1105  {{end}}
  1106  `
  1107  
  1108  // Op define operator name and properties.
  1109  type Op struct {
  1110  	Name    string // +, -, ...
  1111  	Str     bool   // true if operator applies to string
  1112  	Float   bool   // true if operator applies to float
  1113  	Complex bool   // true if operator applies to complex
  1114  	Shift   bool   // true if operator is a shift operation
  1115  	Bool    bool   // true if operator applies to bool
  1116  	Int     bool   // true if operator applies to int only
  1117  }
  1118  
  1119  func main() {
  1120  	base := template.New("genop")
  1121  	base.Funcs(template.FuncMap{
  1122  		"tokenFromName": func(name string) string {
  1123  			switch name {
  1124  			case "andNot":
  1125  				return "AND_NOT"
  1126  			case "neg":
  1127  				return "SUB"
  1128  			case "pos":
  1129  				return "ADD"
  1130  			case "bitNot":
  1131  				return "XOR"
  1132  			default:
  1133  				return strings.ToUpper(name)
  1134  			}
  1135  		},
  1136  	})
  1137  	parse, err := base.Parse(model)
  1138  	if err != nil {
  1139  		log.Fatal(err)
  1140  	}
  1141  
  1142  	b := &bytes.Buffer{}
  1143  	data := map[string]interface{}{
  1144  		"Arithmetic": map[string]Op{
  1145  			"add":    {"+", true, true, true, false, false, false},
  1146  			"sub":    {"-", false, true, true, false, false, false},
  1147  			"mul":    {"*", false, true, true, false, false, false},
  1148  			"quo":    {"/", false, true, true, false, false, false},
  1149  			"rem":    {"%", false, false, false, false, false, true},
  1150  			"shl":    {"<<", false, false, false, true, false, true},
  1151  			"shr":    {">>", false, false, false, true, false, true},
  1152  			"and":    {"&", false, false, false, false, false, true},
  1153  			"or":     {"|", false, false, false, false, false, true},
  1154  			"xor":    {"^", false, false, false, false, false, true},
  1155  			"andNot": {"&^", false, false, false, false, false, true},
  1156  		},
  1157  		"IncDec": map[string]Op{
  1158  			"inc": {Name: "+"},
  1159  			"dec": {Name: "-"},
  1160  		},
  1161  		"Comparison": map[string]Op{
  1162  			"equal":        {Name: "==", Complex: true},
  1163  			"greater":      {Name: ">", Complex: false},
  1164  			"greaterEqual": {Name: ">=", Complex: false},
  1165  			"lower":        {Name: "<", Complex: false},
  1166  			"lowerEqual":   {Name: "<=", Complex: false},
  1167  			"notEqual":     {Name: "!=", Complex: true},
  1168  		},
  1169  		"Unary": map[string]Op{
  1170  			"not":    {Name: "!", Float: false, Bool: true},
  1171  			"neg":    {Name: "-", Float: true, Bool: false},
  1172  			"pos":    {Name: "+", Float: true, Bool: false},
  1173  			"bitNot": {Name: "^", Float: false, Bool: false, Int: true},
  1174  		},
  1175  	}
  1176  	if err = parse.Execute(b, data); err != nil {
  1177  		log.Fatal(err)
  1178  	}
  1179  
  1180  	// gofmt
  1181  	source, err := format.Source(b.Bytes())
  1182  	if err != nil {
  1183  		log.Fatal(err)
  1184  	}
  1185  
  1186  	if err = ioutil.WriteFile("op.go", source, 0o666); err != nil {
  1187  		log.Fatal(err)
  1188  	}
  1189  }