feat: add support for builtin copy (#126)

This commit is contained in:
Marc Vertes
2019-03-19 01:19:43 +01:00
committed by Ludovic Fernandez
parent a1bfe7c989
commit b8927e3ca6
5 changed files with 67 additions and 2 deletions

14
_test/copy0.go Normal file
View File

@@ -0,0 +1,14 @@
package main
import "fmt"
func main() {
a := []int{10, 20, 30}
b := [4]int{}
c := b[:]
copy(c, a)
fmt.Println(c)
}
// Output:
// [10 20 30 0]

View File

@@ -532,7 +532,7 @@ func (interp *Interpreter) Cfg(root *Node) ([]*Node, error) {
if n.typ = scope.getType(n.child[1].ident); n.typ == nil {
n.typ, err = nodeType(interp, scope, n.child[1])
}
case "cap", "len":
case "cap", "copy", "len":
n.typ = scope.getType("int")
case "make":
if n.typ = scope.getType(n.child[1].ident); n.typ == nil {
@@ -1088,7 +1088,20 @@ func (interp *Interpreter) Cfg(root *Node) ([]*Node, error) {
n.gen = nop
}
case SliceExpr, UnaryExpr:
case SliceExpr:
wireChild(n)
if ctyp := n.child[0].typ; ctyp.size != 0 {
// Create a slice type from an array type
n.typ = &Type{}
*n.typ = *ctyp
n.typ.size = 0
n.typ.rtype = nil
} else {
n.typ = ctyp
}
n.findex = scope.add(n.typ)
case UnaryExpr:
wireChild(n)
n.typ = n.child[0].typ
// TODO: Optimisation: avoid allocation if boolean branch op (i.e. '!' in an 'if' expr)

View File

@@ -154,6 +154,7 @@ func initUniverse() *Scope {
"append": &Symbol{kind: Bltn, builtin: _append},
"cap": &Symbol{kind: Bltn, builtin: _cap},
"close": &Symbol{kind: Bltn, builtin: _close},
"copy": &Symbol{kind: Bltn, builtin: _copy},
"len": &Symbol{kind: Bltn, builtin: _len},
"make": &Symbol{kind: Bltn, builtin: _make},
"new": &Symbol{kind: Bltn, builtin: _new},

View File

@@ -1764,6 +1764,31 @@ func main() {
// world
}
func Example_copy0() {
src := `
package main
import "fmt"
func main() {
a := []int{10, 20, 30}
b := [4]int{}
c := b[:]
copy(c, a)
fmt.Println(c)
}
`
i := interp.New(interp.Opt{Entry: "main"})
i.Use(stdlib.Value)
_, err := i.Eval(src)
if err != nil {
panic(err)
}
// Output:
// [10 20 30 0]
}
func Example_defer0() {
src := `
package main

View File

@@ -1300,6 +1300,18 @@ func _cap(n *Node) {
}
}
func _copy(n *Node) {
i := n.findex
value0 := genValue(n.child[1])
value1 := genValue(n.child[2])
next := getExec(n.tnext)
n.exec = func(f *Frame) Builtin {
f.data[i].SetInt(int64(reflect.Copy(value0(f), value1(f))))
return next
}
}
func _close(n *Node) {
value := genValue(n.child[1])
next := getExec(n.tnext)