1package main
2
3import (
4	"bytes"
5	"go/format"
6	"io/ioutil"
7	"log"
8	"strings"
9	"text/template"
10)
11
12const model = `package interp
13
14// Code generated by 'go run ../internal/cmd/genop/genop.go'. DO NOT EDIT.
15
16import (
17	"go/constant"
18	"go/token"
19	"reflect"
20)
21
22// Arithmetic operators
23{{range $name, $op := .Arithmetic}}
24func {{$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
228func {{$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}}
288func {{$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}}
439func {{$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}}
496func {{$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}}
532func {{$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.
1109type 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
1119func 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, 0666); err != nil {
1187		log.Fatal(err)
1188	}
1189}
1190