Closed
Description
The following program sample.go
triggers an unexpected result
package main
import (
"fmt"
"os"
"reflect"
"github.com/traefik/yaegi/interp"
)
func main() {
var F float64
i := interp.New(interp.Options{})
if err := i.Use(interp.Exports{
"pkg/pkg": map[string]reflect.Value{
"F": reflect.ValueOf(&F).Elem(),
},
}); err != nil {
panic(err)
}
i.ImportUsed()
res, err := i.Eval("pkg.F++; pkg.F")
if err != nil {
panic(err)
}
if res.Interface().(float64) != 1.0 {
fmt.Printf("F++: expected 1.0, got %v\n", res.Interface())
}
res, err = i.Eval("pkg.F = 4.0; pkg.F")
if err != nil {
fmt.Printf("F = 4.0: err: %v\n", err)
os.Exit(1)
}
if res.Interface().(float64) != 4.0 {
fmt.Printf("F = 4.0: Expected 4.0; got %v\n", res.Interface())
os.Exit(1)
}
}
Expected result
$ go run ./sample.go
// no output expected
Got
$ go run ./sample.go
F = 4.0: err: 1:28: cannot assign to %!s(float64=1) (float64 constant)
Yaegi Version
Additional Notes
In test-case form: add this to the end of interp/interp_eval_test.go:
func TestIssue1623(t *testing.T) {
var F float64
Pf := &F
var ii int
var s string = "foo"
i := interp.New(interp.Options{})
if err := i.Use(interp.Exports{
"pkg/pkg": map[string]reflect.Value{
"F": reflect.ValueOf(&F).Elem(),
"Pf": reflect.ValueOf(&Pf).Elem(),
"II": reflect.ValueOf(&ii).Elem(),
"S": reflect.ValueOf(&s).Elem(),
},
}); err != nil {
t.Fatal(err)
}
i.ImportUsed()
runTests(t, i, []testCase{
// {desc: "F++", src: "pkg.F++; pkg.F", res: "1"},
// {desc: "*Pf = 2", src: "*pkg.Pf = 2; *pkg.Pf", res: "2"},
// {desc: "check F", src: "pkg.F", res: "2"},
// {desc: "*(&F) = 3", src: "*(&pkg.F) = 3; pkg.F", res: "3"},
{desc: "F = 4", src: "pkg.F = 4.0; pkg.F", res: "4"}, // breaks
// {desc: "II++", src: "pkg.II++; pkg.II", res: "1"},
{desc: "II = 2", src: "pkg.II = 2; pkg.II", res: "2"}, // breaks
{desc: `S = "bar"`, src: `pkg.S = "bar"; pkg.S`, res: "bar"}, // breaks
})
}