feat: Add support for missing assign operators (#30)
This commit is contained in:
committed by
Ludovic Fernandez
parent
83c21d4bc0
commit
2619434b64
@@ -14,7 +14,8 @@ const model = `package interp
|
||||
|
||||
import "reflect"
|
||||
|
||||
{{range $name, $op := .Ops}}
|
||||
// Arithmetic opertators
|
||||
{{range $name, $op := .Arithmetic}}
|
||||
func {{$name}}(n *Node) {
|
||||
i := n.findex
|
||||
next := getExec(n.tnext)
|
||||
@@ -67,14 +68,68 @@ func {{$name}}(n *Node) {
|
||||
}
|
||||
}
|
||||
{{end}}
|
||||
// Assign operators
|
||||
{{range $name, $op := .Arithmetic}}
|
||||
func {{$name}}Assign(n *Node) {
|
||||
next := getExec(n.tnext)
|
||||
typ := n.typ.TypeOf()
|
||||
value := genValue(n.child[0])
|
||||
|
||||
switch typ.Kind() {
|
||||
{{- if $op.Str}}
|
||||
case reflect.String:
|
||||
v0 := genValue(n.child[0])
|
||||
v1 := genValue(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetString(v0(f).String() {{$op.Name}} v1(f).String())
|
||||
return next
|
||||
}
|
||||
{{- end}}
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
v0 := genValueInt(n.child[0])
|
||||
{{- if $op.Shift}}
|
||||
v1 := genValueUint(n.child[1])
|
||||
{{else}}
|
||||
v1 := genValueInt(n.child[1])
|
||||
{{end -}}
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetInt(v0(f) {{$op.Name}} v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
v0 := genValueUint(n.child[0])
|
||||
v1 := genValueUint(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetUint(v0(f) {{$op.Name}} v1(f))
|
||||
return next
|
||||
}
|
||||
{{- if $op.Float}}
|
||||
case reflect.Float32, reflect.Float64:
|
||||
v0 := genValueFloat(n.child[0])
|
||||
v1 := genValueFloat(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetFloat(v0(f) {{$op.Name}} v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Complex64, reflect.Complex128:
|
||||
v0 := genValue(n.child[0])
|
||||
v1 := genValue(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetComplex(v0(f).Complex() {{$op.Name}} v1(f).Complex())
|
||||
return next
|
||||
}
|
||||
{{- end}}
|
||||
}
|
||||
}
|
||||
{{end}}
|
||||
`
|
||||
|
||||
// Op FIXME
|
||||
// Op define operator name and properties
|
||||
type Op struct {
|
||||
Name string
|
||||
Str bool
|
||||
Float bool
|
||||
Shift bool
|
||||
Name string // +, -, ...
|
||||
Str bool // true if operator applies to string
|
||||
Float bool // true if operator applies to float
|
||||
Shift bool // true if operator is a shift operation
|
||||
}
|
||||
|
||||
func main() {
|
||||
@@ -86,7 +141,7 @@ func main() {
|
||||
|
||||
b := &bytes.Buffer{}
|
||||
data := map[string]interface{}{
|
||||
"Ops": map[string]Op{
|
||||
"Arithmetic": map[string]Op{
|
||||
"add": {"+", true, true, false},
|
||||
"sub": {"-", false, true, false},
|
||||
"mul": {"*", false, true, false},
|
||||
|
||||
@@ -188,8 +188,11 @@ const (
|
||||
Assign
|
||||
AssignX
|
||||
Add
|
||||
AddAssign
|
||||
And
|
||||
AndAssign
|
||||
AndNot
|
||||
AndNotAssign
|
||||
Call
|
||||
Case
|
||||
CompositeLit
|
||||
@@ -203,25 +206,34 @@ const (
|
||||
Land
|
||||
Lor
|
||||
Lower
|
||||
Lshift
|
||||
Mul
|
||||
MulAssign
|
||||
Negate
|
||||
Not
|
||||
NotEqual
|
||||
Quotient
|
||||
Or
|
||||
OrAssign
|
||||
Quo
|
||||
QuoAssign
|
||||
Range
|
||||
Recv
|
||||
Remain
|
||||
Rem
|
||||
RemAssign
|
||||
Return
|
||||
Rshift
|
||||
Select
|
||||
Send
|
||||
Shl
|
||||
ShlAssign
|
||||
Shr
|
||||
ShrAssign
|
||||
Slice
|
||||
Slice0
|
||||
Star
|
||||
Sub
|
||||
SubAssign
|
||||
TypeAssert
|
||||
Xor
|
||||
XorAssign
|
||||
)
|
||||
|
||||
var actions = [...]string{
|
||||
@@ -230,8 +242,11 @@ var actions = [...]string{
|
||||
Assign: "=",
|
||||
AssignX: "X=",
|
||||
Add: "+",
|
||||
AddAssign: "+=",
|
||||
And: "&",
|
||||
AndAssign: "&=",
|
||||
AndNot: "&^",
|
||||
AndNotAssign: "&^=",
|
||||
Call: "call",
|
||||
Case: "case",
|
||||
CompositeLit: "compositeLit",
|
||||
@@ -245,24 +260,31 @@ var actions = [...]string{
|
||||
Land: "&&",
|
||||
Lor: "||",
|
||||
Lower: "<",
|
||||
Lshift: "<<",
|
||||
Mul: "*",
|
||||
MulAssign: "*=",
|
||||
Negate: "-",
|
||||
Not: "!",
|
||||
NotEqual: "!=",
|
||||
Quotient: "/",
|
||||
Quo: "/",
|
||||
QuoAssign: "/=",
|
||||
Range: "range",
|
||||
Recv: "<-",
|
||||
Remain: "%",
|
||||
Rem: "%",
|
||||
RemAssign: "%=",
|
||||
Return: "return",
|
||||
Rshift: ">>",
|
||||
Send: "<~",
|
||||
Shl: "<<",
|
||||
ShlAssign: "<<=",
|
||||
Shr: ">>",
|
||||
ShrAssign: ">>=",
|
||||
Slice: "slice",
|
||||
Slice0: "slice0",
|
||||
Star: "*",
|
||||
Sub: "-",
|
||||
SubAssign: "-=",
|
||||
TypeAssert: "TypeAssert",
|
||||
Xor: "^",
|
||||
XorAssign: "^=",
|
||||
}
|
||||
|
||||
func (a Action) String() string {
|
||||
@@ -402,13 +424,37 @@ func (interp *Interpreter) ast(src, name string) (string, *Node, error) {
|
||||
}
|
||||
action = AssignX
|
||||
} else {
|
||||
if a.Tok == token.DEFINE {
|
||||
kind = Define
|
||||
} else {
|
||||
kind = AssignStmt
|
||||
}
|
||||
action = Assign
|
||||
nbAssign = len(a.Lhs)
|
||||
kind = AssignStmt
|
||||
switch a.Tok {
|
||||
case token.ASSIGN:
|
||||
action = Assign
|
||||
case token.ADD_ASSIGN:
|
||||
action = AddAssign
|
||||
case token.AND_ASSIGN:
|
||||
action = AndAssign
|
||||
case token.AND_NOT_ASSIGN:
|
||||
action = AndNotAssign
|
||||
case token.DEFINE:
|
||||
kind = Define
|
||||
action = Assign
|
||||
case token.SHL_ASSIGN:
|
||||
action = ShlAssign
|
||||
case token.SHR_ASSIGN:
|
||||
action = ShrAssign
|
||||
case token.MUL_ASSIGN:
|
||||
action = MulAssign
|
||||
case token.OR_ASSIGN:
|
||||
action = OrAssign
|
||||
case token.QUO_ASSIGN:
|
||||
action = QuoAssign
|
||||
case token.REM_ASSIGN:
|
||||
action = RemAssign
|
||||
case token.SUB_ASSIGN:
|
||||
action = SubAssign
|
||||
case token.XOR_ASSIGN:
|
||||
action = XorAssign
|
||||
}
|
||||
}
|
||||
st.push(addChild(&root, anc, pos, kind, action))
|
||||
|
||||
@@ -457,16 +503,18 @@ func (interp *Interpreter) ast(src, name string) (string, *Node, error) {
|
||||
action = Mul
|
||||
case token.NEQ:
|
||||
action = NotEqual
|
||||
case token.OR:
|
||||
action = Or
|
||||
case token.REM:
|
||||
action = Remain
|
||||
action = Rem
|
||||
case token.SUB:
|
||||
action = Sub
|
||||
case token.SHL:
|
||||
action = Lshift
|
||||
action = Shl
|
||||
case token.SHR:
|
||||
action = Rshift
|
||||
action = Shr
|
||||
case token.QUO:
|
||||
action = Quotient
|
||||
action = Quo
|
||||
case token.XOR:
|
||||
action = Xor
|
||||
}
|
||||
|
||||
@@ -291,6 +291,7 @@ func (interp *Interpreter) Cfg(root *Node) ([]*Node, error) {
|
||||
// TODO: perform constant folding and propagation here
|
||||
// Convert literal value to destination type
|
||||
src.val = reflect.ValueOf(src.val).Convert(dest.typ.TypeOf())
|
||||
src.typ = dest.typ
|
||||
}
|
||||
n.typ = dest.typ
|
||||
if sym != nil {
|
||||
|
||||
320
interp/op.go
320
interp/op.go
@@ -4,6 +4,8 @@ package interp
|
||||
|
||||
import "reflect"
|
||||
|
||||
// Arithmetic opertators
|
||||
|
||||
func add(n *Node) {
|
||||
i := n.findex
|
||||
next := getExec(n.tnext)
|
||||
@@ -319,3 +321,321 @@ func xor(n *Node) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assign operators
|
||||
|
||||
func addAssign(n *Node) {
|
||||
next := getExec(n.tnext)
|
||||
typ := n.typ.TypeOf()
|
||||
value := genValue(n.child[0])
|
||||
|
||||
switch typ.Kind() {
|
||||
case reflect.String:
|
||||
v0 := genValue(n.child[0])
|
||||
v1 := genValue(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetString(v0(f).String() + v1(f).String())
|
||||
return next
|
||||
}
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
v0 := genValueInt(n.child[0])
|
||||
v1 := genValueInt(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetInt(v0(f) + v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
v0 := genValueUint(n.child[0])
|
||||
v1 := genValueUint(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetUint(v0(f) + v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Float32, reflect.Float64:
|
||||
v0 := genValueFloat(n.child[0])
|
||||
v1 := genValueFloat(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetFloat(v0(f) + v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Complex64, reflect.Complex128:
|
||||
v0 := genValue(n.child[0])
|
||||
v1 := genValue(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetComplex(v0(f).Complex() + v1(f).Complex())
|
||||
return next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func andAssign(n *Node) {
|
||||
next := getExec(n.tnext)
|
||||
typ := n.typ.TypeOf()
|
||||
value := genValue(n.child[0])
|
||||
|
||||
switch typ.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
v0 := genValueInt(n.child[0])
|
||||
v1 := genValueInt(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetInt(v0(f) & v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
v0 := genValueUint(n.child[0])
|
||||
v1 := genValueUint(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetUint(v0(f) & v1(f))
|
||||
return next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func andnotAssign(n *Node) {
|
||||
next := getExec(n.tnext)
|
||||
typ := n.typ.TypeOf()
|
||||
value := genValue(n.child[0])
|
||||
|
||||
switch typ.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
v0 := genValueInt(n.child[0])
|
||||
v1 := genValueInt(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetInt(v0(f) &^ v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
v0 := genValueUint(n.child[0])
|
||||
v1 := genValueUint(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetUint(v0(f) &^ v1(f))
|
||||
return next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mulAssign(n *Node) {
|
||||
next := getExec(n.tnext)
|
||||
typ := n.typ.TypeOf()
|
||||
value := genValue(n.child[0])
|
||||
|
||||
switch typ.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
v0 := genValueInt(n.child[0])
|
||||
v1 := genValueInt(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetInt(v0(f) * v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
v0 := genValueUint(n.child[0])
|
||||
v1 := genValueUint(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetUint(v0(f) * v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Float32, reflect.Float64:
|
||||
v0 := genValueFloat(n.child[0])
|
||||
v1 := genValueFloat(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetFloat(v0(f) * v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Complex64, reflect.Complex128:
|
||||
v0 := genValue(n.child[0])
|
||||
v1 := genValue(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetComplex(v0(f).Complex() * v1(f).Complex())
|
||||
return next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func orAssign(n *Node) {
|
||||
next := getExec(n.tnext)
|
||||
typ := n.typ.TypeOf()
|
||||
value := genValue(n.child[0])
|
||||
|
||||
switch typ.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
v0 := genValueInt(n.child[0])
|
||||
v1 := genValueInt(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetInt(v0(f) | v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
v0 := genValueUint(n.child[0])
|
||||
v1 := genValueUint(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetUint(v0(f) | v1(f))
|
||||
return next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func quoAssign(n *Node) {
|
||||
next := getExec(n.tnext)
|
||||
typ := n.typ.TypeOf()
|
||||
value := genValue(n.child[0])
|
||||
|
||||
switch typ.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
v0 := genValueInt(n.child[0])
|
||||
v1 := genValueInt(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetInt(v0(f) / v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
v0 := genValueUint(n.child[0])
|
||||
v1 := genValueUint(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetUint(v0(f) / v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Float32, reflect.Float64:
|
||||
v0 := genValueFloat(n.child[0])
|
||||
v1 := genValueFloat(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetFloat(v0(f) / v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Complex64, reflect.Complex128:
|
||||
v0 := genValue(n.child[0])
|
||||
v1 := genValue(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetComplex(v0(f).Complex() / v1(f).Complex())
|
||||
return next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func remAssign(n *Node) {
|
||||
next := getExec(n.tnext)
|
||||
typ := n.typ.TypeOf()
|
||||
value := genValue(n.child[0])
|
||||
|
||||
switch typ.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
v0 := genValueInt(n.child[0])
|
||||
v1 := genValueInt(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetInt(v0(f) % v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
v0 := genValueUint(n.child[0])
|
||||
v1 := genValueUint(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetUint(v0(f) % v1(f))
|
||||
return next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func shlAssign(n *Node) {
|
||||
next := getExec(n.tnext)
|
||||
typ := n.typ.TypeOf()
|
||||
value := genValue(n.child[0])
|
||||
|
||||
switch typ.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
v0 := genValueInt(n.child[0])
|
||||
v1 := genValueUint(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetInt(v0(f) << v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
v0 := genValueUint(n.child[0])
|
||||
v1 := genValueUint(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetUint(v0(f) << v1(f))
|
||||
return next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func shrAssign(n *Node) {
|
||||
next := getExec(n.tnext)
|
||||
typ := n.typ.TypeOf()
|
||||
value := genValue(n.child[0])
|
||||
|
||||
switch typ.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
v0 := genValueInt(n.child[0])
|
||||
v1 := genValueUint(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetInt(v0(f) >> v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
v0 := genValueUint(n.child[0])
|
||||
v1 := genValueUint(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetUint(v0(f) >> v1(f))
|
||||
return next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func subAssign(n *Node) {
|
||||
next := getExec(n.tnext)
|
||||
typ := n.typ.TypeOf()
|
||||
value := genValue(n.child[0])
|
||||
|
||||
switch typ.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
v0 := genValueInt(n.child[0])
|
||||
v1 := genValueInt(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetInt(v0(f) - v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
v0 := genValueUint(n.child[0])
|
||||
v1 := genValueUint(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetUint(v0(f) - v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Float32, reflect.Float64:
|
||||
v0 := genValueFloat(n.child[0])
|
||||
v1 := genValueFloat(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetFloat(v0(f) - v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Complex64, reflect.Complex128:
|
||||
v0 := genValue(n.child[0])
|
||||
v1 := genValue(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetComplex(v0(f).Complex() - v1(f).Complex())
|
||||
return next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func xorAssign(n *Node) {
|
||||
next := getExec(n.tnext)
|
||||
typ := n.typ.TypeOf()
|
||||
value := genValue(n.child[0])
|
||||
|
||||
switch typ.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
v0 := genValueInt(n.child[0])
|
||||
v1 := genValueInt(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetInt(v0(f) ^ v1(f))
|
||||
return next
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
v0 := genValueUint(n.child[0])
|
||||
v1 := genValueUint(n.child[1])
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
value(f).SetUint(v0(f) ^ v1(f))
|
||||
return next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,11 @@ var builtin = [...]BuiltinGenerator{
|
||||
Assign: assign,
|
||||
AssignX: assignX,
|
||||
Add: add,
|
||||
AddAssign: addAssign,
|
||||
And: and,
|
||||
AndAssign: andAssign,
|
||||
AndNot: andnot,
|
||||
AndNotAssign: andnotAssign,
|
||||
Call: call,
|
||||
Case: _case,
|
||||
CompositeLit: arrayLit,
|
||||
@@ -33,24 +36,33 @@ var builtin = [...]BuiltinGenerator{
|
||||
Land: land,
|
||||
Lor: lor,
|
||||
Lower: lower,
|
||||
Lshift: shl,
|
||||
Mul: mul,
|
||||
MulAssign: mulAssign,
|
||||
Negate: negate,
|
||||
Not: not,
|
||||
NotEqual: notEqual,
|
||||
Quotient: quo,
|
||||
Or: or,
|
||||
OrAssign: orAssign,
|
||||
Quo: quo,
|
||||
QuoAssign: quoAssign,
|
||||
Range: _range,
|
||||
Recv: recv,
|
||||
Remain: rem,
|
||||
Rem: rem,
|
||||
RemAssign: remAssign,
|
||||
Return: _return,
|
||||
Rshift: shr,
|
||||
Send: send,
|
||||
Shl: shl,
|
||||
ShlAssign: shlAssign,
|
||||
Shr: shr,
|
||||
ShrAssign: shrAssign,
|
||||
Slice: slice,
|
||||
Slice0: slice0,
|
||||
Star: deref,
|
||||
Sub: sub,
|
||||
SubAssign: subAssign,
|
||||
TypeAssert: typeAssert,
|
||||
Xor: xor,
|
||||
XorAssign: xorAssign,
|
||||
}
|
||||
|
||||
func (interp *Interpreter) run(n *Node, cf *Frame) {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package interp
|
||||
|
||||
import "reflect"
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func valueGenerator(n *Node, i int) func(*Frame) reflect.Value {
|
||||
switch n.level {
|
||||
|
||||
Reference in New Issue
Block a user