diff --git a/interp/interp_test.go b/interp/interp_test.go index 7e331b01..3492e28b 100644 --- a/interp/interp_test.go +++ b/interp/interp_test.go @@ -1,9 +1,12 @@ package interp import ( + "go/constant" "log" "reflect" "testing" + + "github.com/traefik/yaegi/stdlib" ) func init() { log.SetFlags(log.Lshortfile) } @@ -19,13 +22,13 @@ func TestIsNatural(t *testing.T) { n: &node{ typ: &itype{ rtype: func() reflect.Type { - var x uint = 3 - return reflect.TypeOf(x) + var a uint = 3 + return reflect.TypeOf(a) }(), }, rval: func() reflect.Value { - var x uint = 3 - return reflect.ValueOf(x) + var a uint = 3 + return reflect.ValueOf(a) }(), }, expected: true, @@ -35,13 +38,13 @@ func TestIsNatural(t *testing.T) { n: &node{ typ: &itype{ rtype: func() reflect.Type { - x := 3 - return reflect.TypeOf(x) + a := 3 + return reflect.TypeOf(a) }(), }, rval: func() reflect.Value { - x := 3 - return reflect.ValueOf(x) + a := 3 + return reflect.ValueOf(a) }(), }, expected: true, @@ -51,13 +54,13 @@ func TestIsNatural(t *testing.T) { n: &node{ typ: &itype{ rtype: func() reflect.Type { - var x int = 3 - return reflect.TypeOf(x) + var a int = 3 + return reflect.TypeOf(a) }(), }, rval: func() reflect.Value { - var x int = 3 - return reflect.ValueOf(x) + var a int = 3 + return reflect.ValueOf(a) }(), }, expected: true, @@ -67,13 +70,13 @@ func TestIsNatural(t *testing.T) { n: &node{ typ: &itype{ rtype: func() reflect.Type { - var x float64 = 3.0 - return reflect.TypeOf(x) + var a float64 = 3.0 + return reflect.TypeOf(a) }(), }, rval: func() reflect.Value { - var x float64 = 3.0 - return reflect.ValueOf(x) + var a float64 = 3.0 + return reflect.ValueOf(a) }(), }, expected: true, @@ -83,13 +86,13 @@ func TestIsNatural(t *testing.T) { n: &node{ typ: &itype{ rtype: func() reflect.Type { - var x float64 = 3.14 - return reflect.TypeOf(x) + var a float64 = 3.14 + return reflect.TypeOf(a) }(), }, rval: func() reflect.Value { - var x float64 = 3.14 - return reflect.ValueOf(x) + var a float64 = 3.14 + return reflect.ValueOf(a) }(), }, expected: false, @@ -99,13 +102,13 @@ func TestIsNatural(t *testing.T) { n: &node{ typ: &itype{ rtype: func() reflect.Type { - var x int = -3 - return reflect.TypeOf(x) + var a int = -3 + return reflect.TypeOf(a) }(), }, rval: func() reflect.Value { - var x int = -3 - return reflect.ValueOf(x) + var a int = -3 + return reflect.ValueOf(a) }(), }, expected: false, @@ -188,3 +191,42 @@ func TestIsNatural(t *testing.T) { } } } + +func TestGlobals(t *testing.T) { + i := New(Options{}) + if err := i.Use(stdlib.Symbols); err != nil { + t.Fatal(err) + } + if _, err := i.Eval("var a = 1"); err != nil { + t.Fatal(err) + } + if _, err := i.Eval("b := 2"); err != nil { + t.Fatal(err) + } + if _, err := i.Eval("const c = 3"); err != nil { + t.Fatal(err) + } + + g := i.Globals() + a := g["a"] + if !a.IsValid() { + t.Fatal("a not found") + } + if a := a.Interface(); a != 1 { + t.Fatalf("wrong a: want (%[1]T) %[1]v, have (%[2]T) %[2]v", 1, a) + } + b := g["b"] + if !b.IsValid() { + t.Fatal("b not found") + } + if b := b.Interface(); b != 2 { + t.Fatalf("wrong b: want (%[1]T) %[1]v, have (%[2]T) %[2]v", 2, b) + } + c := g["c"] + if !c.IsValid() { + t.Fatal("c not found") + } + if cc, ok := c.Interface().(constant.Value); ok && constant.MakeInt64(3) != cc { + t.Fatalf("wrong c: want (%[1]T) %[1]v, have (%[2]T) %[2]v", constant.MakeInt64(3), cc) + } +} diff --git a/interp/scope.go b/interp/scope.go index 6f362ac2..b0c0c76b 100644 --- a/interp/scope.go +++ b/interp/scope.go @@ -241,3 +241,26 @@ func (interp *Interpreter) initScopePkg(pkgID, pkgName string) *scope { interp.mutex.Unlock() return sc } + +// Globals returns a map of global variables and constants in the main package. +func (interp *Interpreter) Globals() map[string]reflect.Value { + syms := map[string]reflect.Value{} + interp.mutex.RLock() + defer interp.mutex.RUnlock() + + v, ok := interp.srcPkg["main"] + if !ok { + return syms + } + + for n, s := range v { + switch s.kind { + case constSym: + syms[n] = s.rval + case varSym: + syms[n] = interp.frame.data[s.index] + } + } + + return syms +}