Files
moxa/internal/genop/genop.go
Ludovic Fernandez 470960aa93 chore: Move commands (#235)
* chore: move genop to internal.

* chore: move yaegi command.
2019-07-03 17:57:46 +02:00

847 lines
19 KiB
Go

package main
import (
"bytes"
"go/format"
"io/ioutil"
"log"
"text/template"
)
const model = `package interp
// Code generated by 'go run ../cmd/genop/genop.go'. DO NOT EDIT.
import "reflect"
// Arithmetic operators
{{range $name, $op := .Arithmetic}}
func {{$name}}(n *node) {
dest := genValue(n)
next := getExec(n.tnext)
typ := n.typ.TypeOf()
c0, c1 := n.child[0], n.child[1]
switch typ.Kind() {
{{- if $op.Str}}
case reflect.String:
switch {
case c0.rval.IsValid():
s0 := c0.rval.String()
v1 := genValue(c1)
n.exec = func(f *frame) bltn {
dest(f).SetString(s0 {{$op.Name}} v1(f).String())
return next
}
case c1.rval.IsValid():
v0 := genValue(c0)
s1 := c1.rval.String()
n.exec = func(f *frame) bltn {
dest(f).SetString(v0(f).String() {{$op.Name}} s1)
return next
}
default:
v0 := genValue(c0)
v1 := genValue(c1)
n.exec = func(f *frame) bltn {
dest(f).SetString(v0(f).String() {{$op.Name}} v1(f).String())
return next
}
}
{{- end}}
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
switch {
case c0.rval.IsValid():
i := vInt(c0.rval)
{{- if $op.Shift}}
v1 := genValueUint(c1)
{{else}}
v1 := genValueInt(c1)
{{end -}}
n.exec = func(f *frame) bltn {
_, j := v1(f)
dest(f).SetInt(i {{$op.Name}} j)
return next
}
case c1.rval.IsValid():
v0 := genValueInt(c0)
{{- if $op.Shift}}
j := vUint(c1.rval)
{{else}}
j := vInt(c1.rval)
{{end -}}
n.exec = func(f *frame) bltn {
_, i := v0(f)
dest(f).SetInt(i {{$op.Name}} j)
return next
}
default:
v0 := genValueInt(c0)
{{- if $op.Shift}}
v1 := genValueUint(c1)
{{else}}
v1 := genValueInt(c1)
{{end -}}
n.exec = func(f *frame) bltn {
_, i := v0(f)
_, j := v1(f)
dest(f).SetInt(i {{$op.Name}} j)
return next
}
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
switch {
case c0.rval.IsValid():
i := vUint(c0.rval)
v1 := genValueUint(c1)
n.exec = func(f *frame) bltn {
_, j := v1(f)
dest(f).SetUint(i {{$op.Name}} j)
return next
}
case c1.rval.IsValid():
j := vUint(c1.rval)
v0 := genValueUint(c0)
n.exec = func(f *frame) bltn {
_, i := v0(f)
dest(f).SetUint(i {{$op.Name}} j)
return next
}
default:
v0 := genValueUint(c0)
v1 := genValueUint(c1)
n.exec = func(f *frame) bltn {
_, i := v0(f)
_, j := v1(f)
dest(f).SetUint(i {{$op.Name}} j)
return next
}
}
{{- if $op.Float}}
case reflect.Float32, reflect.Float64:
switch {
case c0.rval.IsValid():
i := vFloat(c0.rval)
v1 := genValueFloat(c1)
n.exec = func(f *frame) bltn {
_, j := v1(f)
dest(f).SetFloat(i {{$op.Name}} j)
return next
}
case c1.rval.IsValid():
j := vFloat(c1.rval)
v0 := genValueFloat(c0)
n.exec = func(f *frame) bltn {
_, i := v0(f)
dest(f).SetFloat(i {{$op.Name}} j)
return next
}
default:
v0 := genValueFloat(c0)
v1 := genValueFloat(c1)
n.exec = func(f *frame) bltn {
_, i := v0(f)
_, j := v1(f)
dest(f).SetFloat(i {{$op.Name}} j)
return next
}
}
case reflect.Complex64, reflect.Complex128:
switch {
case c0.rval.IsValid():
r0 := vComplex(c0.rval)
v1 := genValue(c1)
n.exec = func(f *frame) bltn {
dest(f).SetComplex(r0 {{$op.Name}} v1(f).Complex())
return next
}
case c1.rval.IsValid():
r1 := vComplex(c1.rval)
v0 := genValue(c0)
n.exec = func(f *frame) bltn {
dest(f).SetComplex(v0(f).Complex() {{$op.Name}} r1)
return next
}
default:
v0 := genValue(c0)
v1 := genValue(c1)
n.exec = func(f *frame) bltn {
dest(f).SetComplex(v0(f).Complex() {{$op.Name}} v1(f).Complex())
return next
}
}
{{- end}}
}
}
func {{$name}}Const(n *node) {
v0, v1 := n.child[0].rval, n.child[1].rval
t := n.typ.rtype
n.rval = reflect.New(t).Elem()
switch {
{{- if $op.Str}}
case isString(t):
n.rval.SetString(v0.String() {{$op.Name}} v1.String())
{{- end}}
{{- if $op.Float}}
case isComplex(t):
n.rval.SetComplex(vComplex(v0) {{$op.Name}} vComplex(v1))
case isFloat(t):
n.rval.SetFloat(vFloat(v0) {{$op.Name}} vFloat(v1))
{{- end}}
case isUint(t):
n.rval.SetUint(vUint(v0) {{$op.Name}} vUint(v1))
case isInt(t):
{{- if $op.Shift}}
n.rval.SetInt(vInt(v0) {{$op.Name}} vUint(v1))
{{- else}}
n.rval.SetInt(vInt(v0) {{$op.Name}} vInt(v1))
{{- end}}
}
}
{{end}}
// Assign operators
{{range $name, $op := .Arithmetic}}
func {{$name}}Assign(n *node) {
next := getExec(n.tnext)
typ := n.typ.TypeOf()
c0, c1 := n.child[0], n.child[1]
if c1.rval.IsValid() {
switch typ.Kind() {
{{- if $op.Str}}
case reflect.String:
v0 := genValueString(c0)
v1 := c1.rval.String()
n.exec = func(f *frame) bltn {
v, s := v0(f)
v.SetString(s {{$op.Name}} v1)
return next
}
{{- end}}
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
v0 := genValueInt(c0)
{{- if $op.Shift}}
j := vUint(c1.rval)
{{else}}
j := vInt(c1.rval)
{{end -}}
n.exec = func(f *frame) bltn {
v, i := v0(f)
v.SetInt(i {{$op.Name}} j)
return next
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
v0 := genValueUint(c0)
j := vUint(c1.rval)
n.exec = func(f *frame) bltn {
v, i := v0(f)
v.SetUint(i {{$op.Name}} j)
return next
}
{{- if $op.Float}}
case reflect.Float32, reflect.Float64:
v0 := genValueFloat(c0)
j := vFloat(c1.rval)
n.exec = func(f *frame) bltn {
v, i := v0(f)
v.SetFloat(i {{$op.Name}} j)
return next
}
case reflect.Complex64, reflect.Complex128:
v0 := genValue(c0)
v1 := vComplex(c1.rval)
n.exec = func(f *frame) bltn {
v := v0(f)
v.SetComplex(v.Complex() {{$op.Name}} v1)
return next
}
{{- end}}
}
} else {
switch typ.Kind() {
{{- if $op.Str}}
case reflect.String:
v0 := genValueString(c0)
v1 := genValue(c1)
n.exec = func(f *frame) bltn {
v, s := v0(f)
v.SetString(s {{$op.Name}} v1(f).String())
return next
}
{{- end}}
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
v0 := genValueInt(c0)
{{- if $op.Shift}}
v1 := genValueUint(c1)
{{else}}
v1 := genValueInt(c1)
{{end -}}
n.exec = func(f *frame) bltn {
v, i := v0(f)
_, j := v1(f)
v.SetInt(i {{$op.Name}} j)
return next
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
v0 := genValueUint(c0)
v1 := genValueUint(c1)
n.exec = func(f *frame) bltn {
v, i := v0(f)
_, j := v1(f)
v.SetUint(i {{$op.Name}} j)
return next
}
{{- if $op.Float}}
case reflect.Float32, reflect.Float64:
v0 := genValueFloat(c0)
v1 := genValueFloat(c1)
n.exec = func(f *frame) bltn {
v, i := v0(f)
_, j := v1(f)
v.SetFloat(i {{$op.Name}} j)
return next
}
case reflect.Complex64, reflect.Complex128:
v0 := genValue(c0)
v1 := genValue(c1)
n.exec = func(f *frame) bltn {
v := v0(f)
v.SetComplex(v.Complex() {{$op.Name}} v1(f).Complex())
return next
}
{{- end}}
}
}
}
{{end}}
{{range $name, $op := .IncDec}}
func {{$name}}(n *node) {
next := getExec(n.tnext)
typ := n.typ.TypeOf()
switch typ.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
v0 := genValueInt(n.child[0])
n.exec = func(f *frame) bltn {
v, i := v0(f)
v.SetInt(i {{$op.Name}} 1)
return next
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
v0 := genValueUint(n.child[0])
n.exec = func(f *frame) bltn {
v, i := v0(f)
v.SetUint(i {{$op.Name}} 1)
return next
}
case reflect.Float32, reflect.Float64:
v0 := genValueFloat(n.child[0])
n.exec = func(f *frame) bltn {
v, i := v0(f)
v.SetFloat(i {{$op.Name}} 1)
return next
}
case reflect.Complex64, reflect.Complex128:
v0 := genValue(n.child[0])
n.exec = func(f *frame) bltn {
v := v0(f)
v.SetComplex(v.Complex() {{$op.Name}} 1)
return next
}
}
}
{{end}}
{{range $name, $op := .Comparison}}
func {{$name}}(n *node) {
tnext := getExec(n.tnext)
dest := genValue(n)
c0, c1 := n.child[0], n.child[1]
switch t0, t1 := c0.typ.TypeOf(), c1.typ.TypeOf(); {
case isString(t0) || isString(t1):
switch {
case c0.rval.IsValid():
s0 := c0.rval.String()
v1 := genValueString(n.child[1])
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
_, s1 := v1(f)
if s0 {{$op.Name}} s1 {
dest(f).SetBool(true)
return tnext
}
dest(f).SetBool(false)
return fnext
}
} else {
n.exec = func(f *frame) bltn {
_, s1 := v1(f)
dest(f).SetBool(s0 {{$op.Name}} s1)
return tnext
}
}
case c1.rval.IsValid():
s1 := c1.rval.String()
v0 := genValueString(n.child[0])
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
if s0 {{$op.Name}} s1 {
dest(f).SetBool(true)
return tnext
}
dest(f).SetBool(false)
return fnext
}
} else {
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
dest(f).SetBool(s0 {{$op.Name}} s1)
return tnext
}
}
default:
v0 := genValueString(n.child[0])
v1 := genValueString(n.child[1])
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
_, s1 := v1(f)
if s0 {{$op.Name}} s1 {
dest(f).SetBool(true)
return tnext
}
dest(f).SetBool(false)
return fnext
}
} else {
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
_, s1 := v1(f)
dest(f).SetBool(s0 {{$op.Name}} s1)
return tnext
}
}
}
{{- if $op.Complex}}
case isComplex(t0) || isComplex(t1):
switch {
case c0.rval.IsValid():
s0 := vComplex(c0.rval)
v1 := genValueComplex(c1)
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
_, s1 := v1(f)
if s0 {{$op.Name}} s1 {
dest(f).SetBool(true)
return tnext
}
dest(f).SetBool(false)
return fnext
}
} else {
n.exec = func(f *frame) bltn {
_, s1 := v1(f)
dest(f).SetBool(s0 {{$op.Name}} s1)
return tnext
}
}
case c1.rval.IsValid():
s1 := vComplex(c1.rval)
v0 := genValueComplex(c0)
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
if s0 {{$op.Name}} s1 {
dest(f).SetBool(true)
return tnext
}
dest(f).SetBool(false)
return fnext
}
} else {
dest := genValue(n)
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
dest(f).SetBool(s0 {{$op.Name}} s1)
return tnext
}
}
default:
v0 := genValueComplex(n.child[0])
v1 := genValueComplex(n.child[1])
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
_, s1 := v1(f)
if s0 {{$op.Name}} s1 {
dest(f).SetBool(true)
return tnext
}
dest(f).SetBool(false)
return fnext
}
} else {
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
_, s1 := v1(f)
dest(f).SetBool(s0 {{$op.Name}} s1)
return tnext
}
}
}
default:
switch {
case c0.rval.IsValid():
i0 := c0.rval.Interface()
v1 := genValue(c1)
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
i1 := v1(f).Interface()
if i0 {{$op.Name}} i1 {
dest(f).SetBool(true)
return tnext
}
dest(f).SetBool(false)
return fnext
}
} else {
dest := genValue(n)
n.exec = func(f *frame) bltn {
i1 := v1(f).Interface()
dest(f).SetBool(i0 {{$op.Name}} i1)
return tnext
}
}
case c1.rval.IsValid():
i1 := c1.rval.Interface()
v0 := genValue(c0)
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
i0 := v0(f).Interface()
if i0 {{$op.Name}} i1 {
dest(f).SetBool(true)
return tnext
}
dest(f).SetBool(false)
return fnext
}
} else {
dest := genValue(n)
n.exec = func(f *frame) bltn {
i0 := v0(f).Interface()
dest(f).SetBool(i0 {{$op.Name}} i1)
return tnext
}
}
default:
v0 := genValue(c0)
v1 := genValue(c1)
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
i0 := v0(f).Interface()
i1 := v1(f).Interface()
if i0 {{$op.Name}} i1 {
dest(f).SetBool(true)
return tnext
}
dest(f).SetBool(false)
return fnext
}
} else {
dest := genValue(n)
n.exec = func(f *frame) bltn {
i0 := v0(f).Interface()
i1 := v1(f).Interface()
dest(f).SetBool(i0 {{$op.Name}} i1)
return tnext
}
}
}
{{- end}}
case isFloat(t0) || isFloat(t1):
switch {
case c0.rval.IsValid():
s0 := vFloat(c0.rval)
v1 := genValueFloat(c1)
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
_, s1 := v1(f)
if s0 {{$op.Name}} s1 {
dest(f).SetBool(true)
return tnext
}
dest(f).SetBool(false)
return fnext
}
} else {
n.exec = func(f *frame) bltn {
_, s1 := v1(f)
dest(f).SetBool(s0 {{$op.Name}} s1)
return tnext
}
}
case c1.rval.IsValid():
s1 := vFloat(c1.rval)
v0 := genValueFloat(c0)
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
if s0 {{$op.Name}} s1 {
dest(f).SetBool(true)
return tnext
}
dest(f).SetBool(false)
return fnext
}
} else {
dest := genValue(n)
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
dest(f).SetBool(s0 {{$op.Name}} s1)
return tnext
}
}
default:
v0 := genValueFloat(c0)
v1 := genValueFloat(c1)
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
_, s1 := v1(f)
if s0 {{$op.Name}} s1 {
dest(f).SetBool(true)
return tnext
}
dest(f).SetBool(false)
return fnext
}
} else {
dest := genValue(n)
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
_, s1 := v1(f)
dest(f).SetBool(s0 {{$op.Name}} s1)
return tnext
}
}
}
case isUint(t0) || isUint(t1):
switch {
case c0.rval.IsValid():
s0 := vUint(c0.rval)
v1 := genValueUint(c1)
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
_, s1 := v1(f)
if s0 {{$op.Name}} s1 {
dest(f).SetBool(true)
return tnext
}
dest(f).SetBool(false)
return fnext
}
} else {
dest := genValue(n)
n.exec = func(f *frame) bltn {
_, s1 := v1(f)
dest(f).SetBool(s0 {{$op.Name}} s1)
return tnext
}
}
case c1.rval.IsValid():
s1 := vUint(c1.rval)
v0 := genValueUint(c0)
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
if s0 {{$op.Name}} s1 {
dest(f).SetBool(true)
return tnext
}
dest(f).SetBool(false)
return fnext
}
} else {
dest := genValue(n)
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
dest(f).SetBool(s0 {{$op.Name}} s1)
return tnext
}
}
default:
v0 := genValueUint(c0)
v1 := genValueUint(c1)
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
_, s1 := v1(f)
if s0 {{$op.Name}} s1 {
dest(f).SetBool(true)
return tnext
}
dest(f).SetBool(false)
return fnext
}
} else {
dest := genValue(n)
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
_, s1 := v1(f)
dest(f).SetBool(s0 {{$op.Name}} s1)
return tnext
}
}
}
case isInt(t0) || isInt(t1):
switch {
case c0.rval.IsValid():
s0 := vInt(c0.rval)
v1 := genValueInt(c1)
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
_, s1 := v1(f)
if s0 {{$op.Name}} s1 {
dest(f).SetBool(true)
return tnext
}
dest(f).SetBool(false)
return fnext
}
} else {
dest := genValue(n)
n.exec = func(f *frame) bltn {
_, s1 := v1(f)
dest(f).SetBool(s0 {{$op.Name}} s1)
return tnext
}
}
case c1.rval.IsValid():
s1 := vInt(c1.rval)
v0 := genValueInt(c0)
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
if s0 {{$op.Name}} s1 {
dest(f).SetBool(true)
return tnext
}
dest(f).SetBool(false)
return fnext
}
} else {
dest := genValue(n)
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
dest(f).SetBool(s0 {{$op.Name}} s1)
return tnext
}
}
default:
v0 := genValueInt(c0)
v1 := genValueInt(c1)
if n.fnext != nil {
fnext := getExec(n.fnext)
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
_, s1 := v1(f)
if s0 {{$op.Name}} s1 {
dest(f).SetBool(true)
return tnext
}
dest(f).SetBool(false)
return fnext
}
} else {
dest := genValue(n)
n.exec = func(f *frame) bltn {
_, s0 := v0(f)
_, s1 := v1(f)
dest(f).SetBool(s0 {{$op.Name}} s1)
return tnext
}
}
}
}
}
{{end}}
`
// Op define operator name and properties
type Op struct {
Name string // +, -, ...
Str bool // true if operator applies to string
Float bool // true if operator applies to float
Complex bool // true if operator applies to complex
Shift bool // true if operator is a shift operation
}
func main() {
base := template.New("goexports")
parse, err := base.Parse(model)
if err != nil {
log.Fatal(err)
}
b := &bytes.Buffer{}
data := map[string]interface{}{
"Arithmetic": map[string]Op{
"add": {"+", true, true, true, false},
"sub": {"-", false, true, true, false},
"mul": {"*", false, true, true, false},
"quo": {"/", false, true, true, false},
"rem": {"%", false, false, false, false},
"shl": {"<<", false, false, false, true},
"shr": {">>", false, false, false, true},
"and": {"&", false, false, false, false},
"or": {"|", false, false, false, false},
"xor": {"^", false, false, false, false},
"andNot": {"&^", false, false, false, false},
},
"IncDec": map[string]Op{
"inc": {Name: "+"},
"dec": {Name: "-"},
},
"Comparison": map[string]Op{
"equal": {Name: "==", Complex: true},
"greater": {Name: ">", Complex: false},
"greaterEqual": {Name: ">=", Complex: false},
"lower": {Name: "<", Complex: false},
"lowerEqual": {Name: "<=", Complex: false},
"notEqual": {Name: "!=", Complex: true},
},
}
if err = parse.Execute(b, data); err != nil {
log.Fatal(err)
}
// gofmt
source, err := format.Source(b.Bytes())
if err != nil {
log.Fatal(err)
}
if err = ioutil.WriteFile("op.go", source, 0666); err != nil {
log.Fatal(err)
}
}