fix: handle append a string to a byte array (#133)
This commit is contained in:
committed by
Ludovic Fernandez
parent
3616fb1b82
commit
e766c272ed
@@ -581,11 +581,15 @@ func (interp *Interpreter) Cfg(root *Node) ([]*Node, error) {
|
||||
n.child[0].typ = &Type{cat: BuiltinT}
|
||||
switch n.child[0].ident {
|
||||
case "append":
|
||||
if n.typ = scope.getType(n.child[1].ident); n.typ == nil {
|
||||
n.typ, err = nodeType(interp, scope, n.child[1])
|
||||
c1, c2 := n.child[1], n.child[2]
|
||||
if n.typ = scope.getType(c1.ident); n.typ == nil {
|
||||
n.typ, err = nodeType(interp, scope, c1)
|
||||
}
|
||||
if c2 := n.child[2]; len(n.child) == 3 && c2.typ.cat == ArrayT && c2.typ.val.id() == n.typ.val.id() {
|
||||
n.gen = appendSlice
|
||||
if len(n.child) == 3 {
|
||||
if c2.typ.cat == ArrayT && c2.typ.val.id() == n.typ.val.id() ||
|
||||
isByteArray(c1.typ) && isString(c2.typ) {
|
||||
n.gen = appendSlice
|
||||
}
|
||||
}
|
||||
case "cap", "copy", "len":
|
||||
n.typ = scope.getType("int")
|
||||
|
||||
@@ -61,6 +61,9 @@ func TestEvalBuiltin(t *testing.T) {
|
||||
{src: `a := []int{}; a = append(a, 1); a`, res: "[1]"},
|
||||
{src: `a := []int{1}; a = append(a, 2, 3); a`, res: "[1 2 3]"},
|
||||
{src: `a := []int{1}; b := []int{2, 3}; a = append(a, b...); a`, res: "[1 2 3]"},
|
||||
{src: `string(append([]byte("hello "), "world"...))`, res: "hello world"},
|
||||
{src: `a := "world"; string(append([]byte("hello "), a...))`, res: "hello world"},
|
||||
{src: `a := []byte("Hello"); copy(a, "world"); string(a)`, res: "world"},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1308,14 +1308,23 @@ func _case(n *Node) {
|
||||
|
||||
func appendSlice(n *Node) {
|
||||
i := n.findex
|
||||
value := genValue(n.child[1])
|
||||
next := getExec(n.tnext)
|
||||
value := genValue(n.child[1])
|
||||
value0 := genValue(n.child[2])
|
||||
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
f.data[i] = reflect.AppendSlice(value(f), value0(f))
|
||||
return next
|
||||
if isString(n.child[2].typ) {
|
||||
typ := reflect.TypeOf([]byte{})
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
f.data[i] = reflect.AppendSlice(value(f), value0(f).Convert(typ))
|
||||
return next
|
||||
}
|
||||
} else {
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
f.data[i] = reflect.AppendSlice(value(f), value0(f))
|
||||
return next
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func _append(n *Node) {
|
||||
|
||||
@@ -580,6 +580,12 @@ func isFloat(t *Type) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func isByteArray(t *Type) bool {
|
||||
r := t.TypeOf()
|
||||
k := r.Kind()
|
||||
return (k == reflect.Array || k == reflect.Slice) && r.Elem().Kind() == reflect.Uint8
|
||||
}
|
||||
|
||||
func isFloat32(t *Type) bool { return t.TypeOf().Kind() == reflect.Float32 }
|
||||
func isFloat64(t *Type) bool { return t.TypeOf().Kind() == reflect.Float64 }
|
||||
func isUntypedNumber(t *Type) bool { return t.untyped && (isInt(t) || isFloat(t)) }
|
||||
|
||||
Reference in New Issue
Block a user