func (fn *Function) Globals() StringDict {
	m := make(StringDict, len(fn.funcode.Prog.Globals))
	for i, id := range fn.funcode.Prog.Globals {
		if v := fn.globals[i]; v != nil {
			m[id.Name] = v
		}
	}
	return m
}
Globals returns a new, unfrozen StringDict containing all global
variables so far defined in the function's module.
package skylark
import (
	"bytes"
	"fmt"
	"math"
	"math/big"
	"reflect"
	"strconv"
	"strings"
	"unicode/utf8"
	"github.com/google/skylark/internal/compile"
	"github.com/google/skylark/syntax"
)
type Value interface {
	String() string
	Type() string
	Freeze()
	Truth() Bool
	Hash() (uint32, error)
}
type Comparable interface {
	Value
	CompareSameType(op syntax.Token, y Value, depth int) (bool, error)
}
var (
	_ Comparable = None
	_ Comparable = Int{}
	_ Comparable = False
	_ Comparable = Float(0)
	_ Comparable = String("")
	_ Comparable = (*Dict)(nil)
	_ Comparable = (*List)(nil)
	_ Comparable = Tuple(nil)
	_ Comparable = (*Set)(nil)
)
type Callable interface {
	Value
	Name() string
	CallInternal(thread *Thread, args Tuple, kwargs []Tuple) (Value, error)
}
var (
	_ Callable = (*Builtin)(nil)
	_ Callable = (*Function)(nil)
)
type Iterable interface {
	Value
	Iterate() Iterator  
}
type Sequence interface {
	Iterable
	Len() int
}
var (
	_ Sequence = (*Dict)(nil)
	_ Sequence = (*Set)(nil)
)
type Indexable interface {
	Value
	Index(i int) Value  
	Len() int
}
type Sliceable interface {
	Indexable
	Slice(start, end, step int) Value
}
type HasSetIndex interface {
	Indexable
	SetIndex(index int, v Value) error
}
var (
	_ HasSetIndex = (*List)(nil)
	_ Indexable   = Tuple(nil)
	_ Indexable   = String("")
	_ Sliceable   = Tuple(nil)
	_ Sliceable   = String("")
	_ Sliceable   = (*List)(nil)
)
type Iterator interface {
	Next(p *Value) bool
	Done()
}
type Mapping interface {
	Value
	Get(Value) (v Value, found bool, err error)
}
var _ Mapping = (*Dict)(nil)
type HasSetKey interface {
	Mapping
	SetKey(k, v Value) error
}
var _ HasSetKey = (*Dict)(nil)
type HasBinary interface {
	Value
	Binary(op syntax.Token, y Value, side Side) (Value, error)
}
type Side bool
const (
	Left  Side = false
	Right Side = true
)
type HasAttrs interface {
	Value
	Attr(name string) (Value, error)  
	AttrNames() []string              
}
var (
	_ HasAttrs = String("")
	_ HasAttrs = new(List)
	_ HasAttrs = new(Dict)
	_ HasAttrs = new(Set)
)
type HasSetField interface {
	HasAttrs
	SetField(name string, val Value) error
}
type NoneType byte
const None = NoneType(0)
func (NoneType) String() string        { return "None" }
func (NoneType) Type() string          { return "NoneType" }
func (NoneType) Freeze()               {}  
func (NoneType) Truth() Bool           { return False }
func (NoneType) Hash() (uint32, error) { return 0, nil }
func (NoneType) CompareSameType(op syntax.Token, y Value, depth int) (bool, error) {
	return threeway(op, 0), nil
}
type Bool bool
const (
	False Bool = false
	True  Bool = true
)
func (b Bool) String() string {
	if b {
		return "True"
	} else {
		return "False"
	}
}
func (b Bool) Type() string          { return "bool" }
func (b Bool) Freeze()               {}  
func (b Bool) Truth() Bool           { return b }
func (b Bool) Hash() (uint32, error) { return uint32(b2i(bool(b))), nil }
func (x Bool) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {
	y := y_.(Bool)
	return threeway(op, b2i(bool(x))-b2i(bool(y))), nil
}
type Float float64
func (f Float) String() string { return strconv.FormatFloat(float64(f), 'g', 6, 64) }
func (f Float) Type() string   { return "float" }
func (f Float) Freeze()        {}  
func (f Float) Truth() Bool    { return f != 0.0 }
func (f Float) Hash() (uint32, error) {
	if isFinite(float64(f)) {
		return finiteFloatToInt(f).Hash()
	}
	return 1618033, nil  
}
func floor(f Float) Float { return Float(math.Floor(float64(f))) }
func isFinite(f float64) bool {
	return math.Abs(f) <= math.MaxFloat64
}
func (x Float) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {
	y := y_.(Float)
	switch op {
	case syntax.EQL:
		return x == y, nil
	case syntax.NEQ:
		return x != y, nil
	case syntax.LE:
		return x <= y, nil
	case syntax.LT:
		return x < y, nil
	case syntax.GE:
		return x >= y, nil
	case syntax.GT:
		return x > y, nil
	}
	panic(op)
}
func (f Float) rational() *big.Rat { return new(big.Rat).SetFloat64(float64(f)) }
func AsFloat(x Value) (f float64, ok bool) {
	switch x := x.(type) {
	case Float:
		return float64(x), true
	case Int:
		return float64(x.Float()), true
	}
	return 0, false
}
func (x Float) Mod(y Float) Float { return Float(math.Mod(float64(x), float64(y))) }
type String string
func (s String) String() string        { return strconv.Quote(string(s)) }
func (s String) GoString() string      { return string(s) }
func (s String) Type() string          { return "string" }
func (s String) Freeze()               {}  
func (s String) Truth() Bool           { return len(s) > 0 }
func (s String) Hash() (uint32, error) { return hashString(string(s)), nil }
func (s String) Len() int              { return len(s) }  
func (s String) Index(i int) Value     { return s[i : i+1] }
func (s String) Slice(start, end, step int) Value {
	if step == 1 {
		return String(s[start:end])
	}
	sign := signum(step)
	var str []byte
	for i := start; signum(end-i) == sign; i += step {
		str = append(str, s[i])
	}
	return String(str)
}
func (s String) Attr(name string) (Value, error) { return builtinAttr(s, name, stringMethods) }
func (s String) AttrNames() []string             { return builtinAttrNames(stringMethods) }
func (x String) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {
	y := y_.(String)
	return threeway(op, strings.Compare(string(x), string(y))), nil
}
func AsString(x Value) (string, bool) { v, ok := x.(String); return string(v), ok }
type stringIterable struct {
	s          String
	ords       bool
	codepoints bool
}
var _ Iterable = (*stringIterable)(nil)
func (si stringIterable) String() string {
	var etype string
	if si.codepoints {
		etype = "codepoint"
	} else {
		etype = "elem"
	}
	if si.ords {
		return si.s.String() + "." + etype + "_ords()"
	} else {
		return si.s.String() + "." + etype + "s()"
	}
}
func (si stringIterable) Type() string {
	if si.codepoints {
		return "codepoints"
	} else {
		return "elems"
	}
}
func (si stringIterable) Freeze()               {}  
func (si stringIterable) Truth() Bool           { return True }
func (si stringIterable) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: %s", si.Type()) }
func (si stringIterable) Iterate() Iterator     { return &stringIterator{si, 0} }
type stringIterator struct {
	si stringIterable
	i  int
}
func (it *stringIterator) Next(p *Value) bool {
	s := it.si.s[it.i:]
	if s == "" {
		return false
	}
	if it.si.codepoints {
		r, sz := utf8.DecodeRuneInString(string(s))
		if !it.si.ords {
			*p = s[:sz]
		} else {
			*p = MakeInt(int(r))
		}
		it.i += sz
	} else {
		b := int(s[0])
		if !it.si.ords {
			*p = s[:1]
		} else {
			*p = MakeInt(b)
		}
		it.i += 1
	}
	return true
}
func (*stringIterator) Done() {}
type Function struct {
	funcode  *compile.Funcode
	defaults Tuple
	freevars Tuple
	predeclared StringDict
	globals     []Value
	constants   []Value
}
func (fn *Function) Name() string          { return fn.funcode.Name }  
func (fn *Function) Hash() (uint32, error) { return hashString(fn.funcode.Name), nil }
func (fn *Function) Freeze()               { fn.defaults.Freeze(); fn.freevars.Freeze() }
func (fn *Function) String() string        { return toString(fn) }
func (fn *Function) Type() string          { return "function" }
func (fn *Function) Truth() Bool           { return true }