github.com/k14s/starlark-go@v0.0.0-20200720175618-3a5c849cc368/starlark/value.go (about)

     1  // Copyright 2017 The Bazel Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package starlark provides a Starlark interpreter.
     6  //
     7  // Starlark values are represented by the Value interface.
     8  // The following built-in Value types are known to the evaluator:
     9  //
    10  //      NoneType        -- NoneType
    11  //      Bool            -- bool
    12  //      Int             -- int
    13  //      Float           -- float
    14  //      String          -- string
    15  //      *List           -- list
    16  //      Tuple           -- tuple
    17  //      *Dict           -- dict
    18  //      *Set            -- set
    19  //      *Function       -- function (implemented in Starlark)
    20  //      *Builtin        -- builtin_function_or_method (function or method implemented in Go)
    21  //
    22  // Client applications may define new data types that satisfy at least
    23  // the Value interface.  Such types may provide additional operations by
    24  // implementing any of these optional interfaces:
    25  //
    26  //      Callable        -- value is callable like a function
    27  //      Comparable      -- value defines its own comparison operations
    28  //      Iterable        -- value is iterable using 'for' loops
    29  //      Sequence        -- value is iterable sequence of known length
    30  //      Indexable       -- value is sequence with efficient random access
    31  //      Mapping         -- value maps from keys to values, like a dictionary
    32  //      HasBinary       -- value defines binary operations such as * and +
    33  //      HasAttrs        -- value has readable fields or methods x.f
    34  //      HasSetField     -- value has settable fields x.f
    35  //      HasSetIndex     -- value supports element update using x[i]=y
    36  //      HasSetKey       -- value supports map update using x[k]=v
    37  //      HasUnary        -- value defines unary operations such as + and -
    38  //
    39  // Client applications may also define domain-specific functions in Go
    40  // and make them available to Starlark programs.  Use NewBuiltin to
    41  // construct a built-in value that wraps a Go function.  The
    42  // implementation of the Go function may use UnpackArgs to make sense of
    43  // the positional and keyword arguments provided by the caller.
    44  //
    45  // Starlark's None value is not equal to Go's nil, but nil may be
    46  // assigned to a Starlark Value.  Be careful to avoid allowing Go nil
    47  // values to leak into Starlark data structures.
    48  //
    49  // The Compare operation requires two arguments of the same
    50  // type, but this constraint cannot be expressed in Go's type system.
    51  // (This is the classic "binary method problem".)
    52  // So, each Value type's CompareSameType method is a partial function
    53  // that compares a value only against others of the same type.
    54  // Use the package's standalone Compare (or Equal) function to compare
    55  // an arbitrary pair of values.
    56  //
    57  // To parse and evaluate a Starlark source file, use ExecFile.  The Eval
    58  // function evaluates a single expression.  All evaluator functions
    59  // require a Thread parameter which defines the "thread-local storage"
    60  // of a Starlark thread and may be used to plumb application state
    61  // through Sklyark code and into callbacks.  When evaluation fails it
    62  // returns an EvalError from which the application may obtain a
    63  // backtrace of active Starlark calls.
    64  //
    65  package starlark // import "github.com/k14s/starlark-go/starlark"
    66  
    67  // This file defines the data types of Starlark and their basic operations.
    68  
    69  import (
    70  	"fmt"
    71  	"math"
    72  	"math/big"
    73  	"reflect"
    74  	"strconv"
    75  	"strings"
    76  	"unicode/utf8"
    77  
    78  	"github.com/k14s/starlark-go/internal/compile"
    79  	"github.com/k14s/starlark-go/syntax"
    80  )
    81  
    82  // Value is a value in the Starlark interpreter.
    83  type Value interface {
    84  	// String returns the string representation of the value.
    85  	// Starlark string values are quoted as if by Python's repr.
    86  	String() string
    87  
    88  	// Type returns a short string describing the value's type.
    89  	Type() string
    90  
    91  	// Freeze causes the value, and all values transitively
    92  	// reachable from it through collections and closures, to be
    93  	// marked as frozen.  All subsequent mutations to the data
    94  	// structure through this API will fail dynamically, making the
    95  	// data structure immutable and safe for publishing to other
    96  	// Starlark interpreters running concurrently.
    97  	Freeze()
    98  
    99  	// Truth returns the truth value of an object.
   100  	Truth() Bool
   101  
   102  	// Hash returns a function of x such that Equals(x, y) => Hash(x) == Hash(y).
   103  	// Hash may fail if the value's type is not hashable, or if the value
   104  	// contains a non-hashable value. The hash is used only by dictionaries and
   105  	// is not exposed to the Starlark program.
   106  	Hash() (uint32, error)
   107  }
   108  
   109  // A Comparable is a value that defines its own equivalence relation and
   110  // perhaps ordered comparisons.
   111  type Comparable interface {
   112  	Value
   113  	// CompareSameType compares one value to another of the same Type().
   114  	// The comparison operation must be one of EQL, NEQ, LT, LE, GT, or GE.
   115  	// CompareSameType returns an error if an ordered comparison was
   116  	// requested for a type that does not support it.
   117  	//
   118  	// Implementations that recursively compare subcomponents of
   119  	// the value should use the CompareDepth function, not Compare, to
   120  	// avoid infinite recursion on cyclic structures.
   121  	//
   122  	// The depth parameter is used to bound comparisons of cyclic
   123  	// data structures.  Implementations should decrement depth
   124  	// before calling CompareDepth and should return an error if depth
   125  	// < 1.
   126  	//
   127  	// Client code should not call this method.  Instead, use the
   128  	// standalone Compare or Equals functions, which are defined for
   129  	// all pairs of operands.
   130  	CompareSameType(op syntax.Token, y Value, depth int) (bool, error)
   131  }
   132  
   133  var (
   134  	_ Comparable = None
   135  	_ Comparable = Int{}
   136  	_ Comparable = False
   137  	_ Comparable = Float(0)
   138  	_ Comparable = String("")
   139  	_ Comparable = (*Dict)(nil)
   140  	_ Comparable = (*List)(nil)
   141  	_ Comparable = Tuple(nil)
   142  	_ Comparable = (*Set)(nil)
   143  )
   144  
   145  // A Callable value f may be the operand of a function call, f(x).
   146  //
   147  // Clients should use the Call function, never the CallInternal method.
   148  type Callable interface {
   149  	Value
   150  	Name() string
   151  	CallInternal(thread *Thread, args Tuple, kwargs []Tuple) (Value, error)
   152  }
   153  
   154  type callableWithPosition interface {
   155  	Callable
   156  	Position() syntax.Position
   157  }
   158  
   159  var (
   160  	_ Callable             = (*Builtin)(nil)
   161  	_ Callable             = (*Function)(nil)
   162  	_ callableWithPosition = (*Function)(nil)
   163  )
   164  
   165  // An Iterable abstracts a sequence of values.
   166  // An iterable value may be iterated over by a 'for' loop or used where
   167  // any other Starlark iterable is allowed.  Unlike a Sequence, the length
   168  // of an Iterable is not necessarily known in advance of iteration.
   169  type Iterable interface {
   170  	Value
   171  	Iterate() Iterator // must be followed by call to Iterator.Done
   172  }
   173  
   174  // A Sequence is a sequence of values of known length.
   175  type Sequence interface {
   176  	Iterable
   177  	Len() int
   178  }
   179  
   180  var (
   181  	_ Sequence = (*Dict)(nil)
   182  	_ Sequence = (*Set)(nil)
   183  )
   184  
   185  // An Indexable is a sequence of known length that supports efficient random access.
   186  // It is not necessarily iterable.
   187  type Indexable interface {
   188  	Value
   189  	Index(i int) Value // requires 0 <= i < Len()
   190  	Len() int
   191  }
   192  
   193  // A Sliceable is a sequence that can be cut into pieces with the slice operator (x[i:j:step]).
   194  //
   195  // All native indexable objects are sliceable.
   196  // This is a separate interface for backwards-compatibility.
   197  type Sliceable interface {
   198  	Indexable
   199  	// For positive strides (step > 0), 0 <= start <= end <= n.
   200  	// For negative strides (step < 0), -1 <= end <= start < n.
   201  	// The caller must ensure that the start and end indices are valid
   202  	// and that step is non-zero.
   203  	Slice(start, end, step int) Value
   204  }
   205  
   206  // A HasSetIndex is an Indexable value whose elements may be assigned (x[i] = y).
   207  //
   208  // The implementation should not add Len to a negative index as the
   209  // evaluator does this before the call.
   210  type HasSetIndex interface {
   211  	Indexable
   212  	SetIndex(index int, v Value) error
   213  }
   214  
   215  var (
   216  	_ HasSetIndex = (*List)(nil)
   217  	_ Indexable   = Tuple(nil)
   218  	_ Indexable   = String("")
   219  	_ Sliceable   = Tuple(nil)
   220  	_ Sliceable   = String("")
   221  	_ Sliceable   = (*List)(nil)
   222  )
   223  
   224  // An Iterator provides a sequence of values to the caller.
   225  //
   226  // The caller must call Done when the iterator is no longer needed.
   227  // Operations that modify a sequence will fail if it has active iterators.
   228  //
   229  // Example usage:
   230  //
   231  // 	iter := iterable.Iterator()
   232  //	defer iter.Done()
   233  //	var x Value
   234  //	for iter.Next(&x) {
   235  //		...
   236  //	}
   237  //
   238  type Iterator interface {
   239  	// If the iterator is exhausted, Next returns false.
   240  	// Otherwise it sets *p to the current element of the sequence,
   241  	// advances the iterator, and returns true.
   242  	Next(p *Value) bool
   243  	Done()
   244  }
   245  
   246  // A Mapping is a mapping from keys to values, such as a dictionary.
   247  //
   248  // If a type satisfies both Mapping and Iterable, the iterator yields
   249  // the keys of the mapping.
   250  type Mapping interface {
   251  	Value
   252  	// Get returns the value corresponding to the specified key,
   253  	// or !found if the mapping does not contain the key.
   254  	//
   255  	// Get also defines the behavior of "v in mapping".
   256  	// The 'in' operator reports the 'found' component, ignoring errors.
   257  	Get(Value) (v Value, found bool, err error)
   258  }
   259  
   260  // An IterableMapping is a mapping that supports key enumeration.
   261  type IterableMapping interface {
   262  	Mapping
   263  	Iterate() Iterator // see Iterable interface
   264  	Items() []Tuple    // a new slice containing all key/value pairs
   265  }
   266  
   267  var _ IterableMapping = (*Dict)(nil)
   268  
   269  // A HasSetKey supports map update using x[k]=v syntax, like a dictionary.
   270  type HasSetKey interface {
   271  	Mapping
   272  	SetKey(k, v Value) error
   273  }
   274  
   275  var _ HasSetKey = (*Dict)(nil)
   276  
   277  // A HasBinary value may be used as either operand of these binary operators:
   278  //     +   -   *   /   //   %   in   not in   |   &   ^   <<   >>
   279  //
   280  // The Side argument indicates whether the receiver is the left or right operand.
   281  //
   282  // An implementation may decline to handle an operation by returning (nil, nil).
   283  // For this reason, clients should always call the standalone Binary(op, x, y)
   284  // function rather than calling the method directly.
   285  type HasBinary interface {
   286  	Value
   287  	Binary(op syntax.Token, y Value, side Side) (Value, error)
   288  }
   289  
   290  type Side bool
   291  
   292  const (
   293  	Left  Side = false
   294  	Right Side = true
   295  )
   296  
   297  // A HasUnary value may be used as the operand of these unary operators:
   298  //     +   -   ~
   299  //
   300  // An implementation may decline to handle an operation by returning (nil, nil).
   301  // For this reason, clients should always call the standalone Unary(op, x)
   302  // function rather than calling the method directly.
   303  type HasUnary interface {
   304  	Value
   305  	Unary(op syntax.Token) (Value, error)
   306  }
   307  
   308  // A HasAttrs value has fields or methods that may be read by a dot expression (y = x.f).
   309  // Attribute names may be listed using the built-in 'dir' function.
   310  //
   311  // For implementation convenience, a result of (nil, nil) from Attr is
   312  // interpreted as a "no such field or method" error. Implementations are
   313  // free to return a more precise error.
   314  type HasAttrs interface {
   315  	Value
   316  	Attr(name string) (Value, error) // returns (nil, nil) if attribute not present
   317  	AttrNames() []string             // callers must not modify the result.
   318  }
   319  
   320  var (
   321  	_ HasAttrs = String("")
   322  	_ HasAttrs = new(List)
   323  	_ HasAttrs = new(Dict)
   324  	_ HasAttrs = new(Set)
   325  )
   326  
   327  // A HasSetField value has fields that may be written by a dot expression (x.f = y).
   328  //
   329  // An implementation of SetField may return a NoSuchAttrError,
   330  // in which case the runtime may augment the error message to
   331  // warn of possible misspelling.
   332  type HasSetField interface {
   333  	HasAttrs
   334  	SetField(name string, val Value) error
   335  }
   336  
   337  // A NoSuchAttrError may be returned by an implementation of
   338  // HasAttrs.Attr or HasSetField.SetField to indicate that no such field
   339  // exists. In that case the runtime may augment the error message to
   340  // warn of possible misspelling.
   341  type NoSuchAttrError string
   342  
   343  func (e NoSuchAttrError) Error() string { return string(e) }
   344  
   345  // NoneType is the type of None.  Its only legal value is None.
   346  // (We represent it as a number, not struct{}, so that None may be constant.)
   347  type NoneType byte
   348  
   349  const None = NoneType(0)
   350  
   351  func (NoneType) String() string        { return "None" }
   352  func (NoneType) Type() string          { return "NoneType" }
   353  func (NoneType) Freeze()               {} // immutable
   354  func (NoneType) Truth() Bool           { return False }
   355  func (NoneType) Hash() (uint32, error) { return 0, nil }
   356  func (NoneType) CompareSameType(op syntax.Token, y Value, depth int) (bool, error) {
   357  	return threeway(op, 0), nil
   358  }
   359  
   360  // Bool is the type of a Starlark bool.
   361  type Bool bool
   362  
   363  const (
   364  	False Bool = false
   365  	True  Bool = true
   366  )
   367  
   368  func (b Bool) String() string {
   369  	if b {
   370  		return "True"
   371  	} else {
   372  		return "False"
   373  	}
   374  }
   375  func (b Bool) Type() string          { return "bool" }
   376  func (b Bool) Freeze()               {} // immutable
   377  func (b Bool) Truth() Bool           { return b }
   378  func (b Bool) Hash() (uint32, error) { return uint32(b2i(bool(b))), nil }
   379  func (x Bool) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {
   380  	y := y_.(Bool)
   381  	return threeway(op, b2i(bool(x))-b2i(bool(y))), nil
   382  }
   383  
   384  // Float is the type of a Starlark float.
   385  type Float float64
   386  
   387  func (f Float) String() string { return strconv.FormatFloat(float64(f), 'g', 6, 64) }
   388  func (f Float) Type() string   { return "float" }
   389  func (f Float) Freeze()        {} // immutable
   390  func (f Float) Truth() Bool    { return f != 0.0 }
   391  func (f Float) Hash() (uint32, error) {
   392  	// Equal float and int values must yield the same hash.
   393  	// TODO(adonovan): opt: if f is non-integral, and thus not equal
   394  	// to any Int, we can avoid the Int conversion and use a cheaper hash.
   395  	if isFinite(float64(f)) {
   396  		return finiteFloatToInt(f).Hash()
   397  	}
   398  	return 1618033, nil // NaN, +/-Inf
   399  }
   400  
   401  func floor(f Float) Float { return Float(math.Floor(float64(f))) }
   402  
   403  // isFinite reports whether f represents a finite rational value.
   404  // It is equivalent to !math.IsNan(f) && !math.IsInf(f, 0).
   405  func isFinite(f float64) bool {
   406  	return math.Abs(f) <= math.MaxFloat64
   407  }
   408  
   409  func (x Float) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {
   410  	y := y_.(Float)
   411  	switch op {
   412  	case syntax.EQL:
   413  		return x == y, nil
   414  	case syntax.NEQ:
   415  		return x != y, nil
   416  	case syntax.LE:
   417  		return x <= y, nil
   418  	case syntax.LT:
   419  		return x < y, nil
   420  	case syntax.GE:
   421  		return x >= y, nil
   422  	case syntax.GT:
   423  		return x > y, nil
   424  	}
   425  	panic(op)
   426  }
   427  
   428  func (f Float) rational() *big.Rat { return new(big.Rat).SetFloat64(float64(f)) }
   429  
   430  // AsFloat returns the float64 value closest to x.
   431  // The f result is undefined if x is not a float or int.
   432  func AsFloat(x Value) (f float64, ok bool) {
   433  	switch x := x.(type) {
   434  	case Float:
   435  		return float64(x), true
   436  	case Int:
   437  		return float64(x.Float()), true
   438  	}
   439  	return 0, false
   440  }
   441  
   442  func (x Float) Mod(y Float) Float { return Float(math.Mod(float64(x), float64(y))) }
   443  
   444  // Unary implements the operations +float and -float.
   445  func (f Float) Unary(op syntax.Token) (Value, error) {
   446  	switch op {
   447  	case syntax.MINUS:
   448  		return -f, nil
   449  	case syntax.PLUS:
   450  		return +f, nil
   451  	}
   452  	return nil, nil
   453  }
   454  
   455  // String is the type of a Starlark string.
   456  //
   457  // A String encapsulates an an immutable sequence of bytes,
   458  // but strings are not directly iterable. Instead, iterate
   459  // over the result of calling one of these four methods:
   460  // codepoints, codepoint_ords, elems, elem_ords.
   461  //
   462  // Warning: the contract of the Value interface's String method is that
   463  // it returns the value printed in Starlark notation,
   464  // so s.String() or fmt.Sprintf("%s", s) returns a quoted string.
   465  // Use string(s) or s.GoString() or fmt.Sprintf("%#v", s) to obtain the raw contents
   466  // of a Starlark string as a Go string.
   467  type String string
   468  
   469  func (s String) String() string        { return strconv.Quote(string(s)) }
   470  func (s String) GoString() string      { return string(s) }
   471  func (s String) Type() string          { return "string" }
   472  func (s String) Freeze()               {} // immutable
   473  func (s String) Truth() Bool           { return len(s) > 0 }
   474  func (s String) Hash() (uint32, error) { return hashString(string(s)), nil }
   475  func (s String) Len() int              { return len(s) } // bytes
   476  func (s String) Index(i int) Value     { return s[i : i+1] }
   477  
   478  func (s String) Slice(start, end, step int) Value {
   479  	if step == 1 {
   480  		return s[start:end]
   481  	}
   482  
   483  	sign := signum(step)
   484  	var str []byte
   485  	for i := start; signum(end-i) == sign; i += step {
   486  		str = append(str, s[i])
   487  	}
   488  	return String(str)
   489  }
   490  
   491  func (s String) Attr(name string) (Value, error) { return builtinAttr(s, name, stringMethods) }
   492  func (s String) AttrNames() []string             { return builtinAttrNames(stringMethods) }
   493  
   494  func (x String) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {
   495  	y := y_.(String)
   496  	return threeway(op, strings.Compare(string(x), string(y))), nil
   497  }
   498  
   499  func AsString(x Value) (string, bool) { v, ok := x.(String); return string(v), ok }
   500  
   501  // A stringIterable is an iterable whose iterator yields a sequence of
   502  // either Unicode code points or elements (bytes),
   503  // either numerically or as successive substrings.
   504  type stringIterable struct {
   505  	s          String
   506  	ords       bool
   507  	codepoints bool
   508  }
   509  
   510  var _ Iterable = (*stringIterable)(nil)
   511  
   512  func (si stringIterable) String() string {
   513  	var etype string
   514  	if si.codepoints {
   515  		etype = "codepoint"
   516  	} else {
   517  		etype = "elem"
   518  	}
   519  	if si.ords {
   520  		return si.s.String() + "." + etype + "_ords()"
   521  	} else {
   522  		return si.s.String() + "." + etype + "s()"
   523  	}
   524  }
   525  func (si stringIterable) Type() string {
   526  	if si.codepoints {
   527  		return "codepoints"
   528  	} else {
   529  		return "elems"
   530  	}
   531  }
   532  func (si stringIterable) Freeze()               {} // immutable
   533  func (si stringIterable) Truth() Bool           { return True }
   534  func (si stringIterable) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: %s", si.Type()) }
   535  func (si stringIterable) Iterate() Iterator     { return &stringIterator{si, 0} }
   536  
   537  type stringIterator struct {
   538  	si stringIterable
   539  	i  int
   540  }
   541  
   542  func (it *stringIterator) Next(p *Value) bool {
   543  	s := it.si.s[it.i:]
   544  	if s == "" {
   545  		return false
   546  	}
   547  	if it.si.codepoints {
   548  		r, sz := utf8.DecodeRuneInString(string(s))
   549  		if !it.si.ords {
   550  			*p = s[:sz]
   551  		} else {
   552  			*p = MakeInt(int(r))
   553  		}
   554  		it.i += sz
   555  	} else {
   556  		b := int(s[0])
   557  		if !it.si.ords {
   558  			*p = s[:1]
   559  		} else {
   560  			*p = MakeInt(b)
   561  		}
   562  		it.i += 1
   563  	}
   564  	return true
   565  }
   566  
   567  func (*stringIterator) Done() {}
   568  
   569  // A Function is a function defined by a Starlark def statement or lambda expression.
   570  // The initialization behavior of a Starlark module is also represented by a Function.
   571  type Function struct {
   572  	funcode  *compile.Funcode
   573  	module   *module
   574  	defaults Tuple
   575  	freevars Tuple
   576  }
   577  
   578  // A module is the dynamic counterpart to a Program.
   579  // All functions in the same program share a module.
   580  type module struct {
   581  	program     *compile.Program
   582  	predeclared StringDict
   583  	globals     []Value
   584  	constants   []Value
   585  }
   586  
   587  // makeGlobalDict returns a new, unfrozen StringDict containing all global
   588  // variables so far defined in the module.
   589  func (m *module) makeGlobalDict() StringDict {
   590  	r := make(StringDict, len(m.program.Globals))
   591  	for i, id := range m.program.Globals {
   592  		if v := m.globals[i]; v != nil {
   593  			r[id.Name] = v
   594  		}
   595  	}
   596  	return r
   597  }
   598  
   599  func (fn *Function) Name() string          { return fn.funcode.Name } // "lambda" for anonymous functions
   600  func (fn *Function) Doc() string           { return fn.funcode.Doc }
   601  func (fn *Function) Hash() (uint32, error) { return hashString(fn.funcode.Name), nil }
   602  func (fn *Function) Freeze()               { fn.defaults.Freeze(); fn.freevars.Freeze() }
   603  func (fn *Function) String() string        { return toString(fn) }
   604  func (fn *Function) Type() string          { return "function" }
   605  func (fn *Function) Truth() Bool           { return true }
   606  
   607  // Globals returns a new, unfrozen StringDict containing all global
   608  // variables so far defined in the function's module.
   609  func (fn *Function) Globals() StringDict { return fn.module.makeGlobalDict() }
   610  
   611  func (fn *Function) Position() syntax.Position { return fn.funcode.Pos }
   612  func (fn *Function) NumParams() int            { return fn.funcode.NumParams }
   613  func (fn *Function) NumKwonlyParams() int      { return fn.funcode.NumKwonlyParams }
   614  
   615  // Param returns the name and position of the ith parameter,
   616  // where 0 <= i < NumParams().
   617  // The *args and **kwargs parameters are at the end
   618  // even if there were optional parameters after *args.
   619  func (fn *Function) Param(i int) (string, syntax.Position) {
   620  	if i >= fn.NumParams() {
   621  		panic(i)
   622  	}
   623  	id := fn.funcode.Locals[i]
   624  	return id.Name, id.Pos
   625  }
   626  func (fn *Function) HasVarargs() bool { return fn.funcode.HasVarargs }
   627  func (fn *Function) HasKwargs() bool  { return fn.funcode.HasKwargs }
   628  
   629  // A Builtin is a function implemented in Go.
   630  type Builtin struct {
   631  	name string
   632  	fn   func(thread *Thread, fn *Builtin, args Tuple, kwargs []Tuple) (Value, error)
   633  	recv Value // for bound methods (e.g. "".startswith)
   634  }
   635  
   636  func (b *Builtin) Name() string { return b.name }
   637  func (b *Builtin) Freeze() {
   638  	if b.recv != nil {
   639  		b.recv.Freeze()
   640  	}
   641  }
   642  func (b *Builtin) Hash() (uint32, error) {
   643  	h := hashString(b.name)
   644  	if b.recv != nil {
   645  		h ^= 5521
   646  	}
   647  	return h, nil
   648  }
   649  func (b *Builtin) Receiver() Value { return b.recv }
   650  func (b *Builtin) String() string  { return toString(b) }
   651  func (b *Builtin) Type() string    { return "builtin_function_or_method" }
   652  func (b *Builtin) CallInternal(thread *Thread, args Tuple, kwargs []Tuple) (Value, error) {
   653  	return b.fn(thread, b, args, kwargs)
   654  }
   655  func (b *Builtin) Truth() Bool { return true }
   656  
   657  // NewBuiltin returns a new 'builtin_function_or_method' value with the specified name
   658  // and implementation.  It compares unequal with all other values.
   659  func NewBuiltin(name string, fn func(thread *Thread, fn *Builtin, args Tuple, kwargs []Tuple) (Value, error)) *Builtin {
   660  	return &Builtin{name: name, fn: fn}
   661  }
   662  
   663  // BindReceiver returns a new Builtin value representing a method
   664  // closure, that is, a built-in function bound to a receiver value.
   665  //
   666  // In the example below, the value of f is the string.index
   667  // built-in method bound to the receiver value "abc":
   668  //
   669  //     f = "abc".index; f("a"); f("b")
   670  //
   671  // In the common case, the receiver is bound only during the call,
   672  // but this still results in the creation of a temporary method closure:
   673  //
   674  //     "abc".index("a")
   675  //
   676  func (b *Builtin) BindReceiver(recv Value) *Builtin {
   677  	return &Builtin{name: b.name, fn: b.fn, recv: recv}
   678  }
   679  
   680  // A *Dict represents a Starlark dictionary.
   681  // The zero value of Dict is a valid empty dictionary.
   682  // If you know the exact final number of entries,
   683  // it is more efficient to call NewDict.
   684  type Dict struct {
   685  	ht hashtable
   686  }
   687  
   688  // NewDict returns a set with initial space for
   689  // at least size insertions before rehashing.
   690  func NewDict(size int) *Dict {
   691  	dict := new(Dict)
   692  	dict.ht.init(size)
   693  	return dict
   694  }
   695  
   696  func (d *Dict) Clear() error                                    { return d.ht.clear() }
   697  func (d *Dict) Delete(k Value) (v Value, found bool, err error) { return d.ht.delete(k) }
   698  func (d *Dict) Get(k Value) (v Value, found bool, err error)    { return d.ht.lookup(k) }
   699  func (d *Dict) Items() []Tuple                                  { return d.ht.items() }
   700  func (d *Dict) Keys() []Value                                   { return d.ht.keys() }
   701  func (d *Dict) Len() int                                        { return int(d.ht.len) }
   702  func (d *Dict) Iterate() Iterator                               { return d.ht.iterate() }
   703  func (d *Dict) SetKey(k, v Value) error                         { return d.ht.insert(k, v) }
   704  func (d *Dict) String() string                                  { return toString(d) }
   705  func (d *Dict) Type() string                                    { return "dict" }
   706  func (d *Dict) Freeze()                                         { d.ht.freeze() }
   707  func (d *Dict) Truth() Bool                                     { return d.Len() > 0 }
   708  func (d *Dict) Hash() (uint32, error)                           { return 0, fmt.Errorf("unhashable type: dict") }
   709  
   710  func (d *Dict) Attr(name string) (Value, error) { return builtinAttr(d, name, dictMethods) }
   711  func (d *Dict) AttrNames() []string             { return builtinAttrNames(dictMethods) }
   712  
   713  func (x *Dict) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {
   714  	y := y_.(*Dict)
   715  	switch op {
   716  	case syntax.EQL:
   717  		ok, err := dictsEqual(x, y, depth)
   718  		return ok, err
   719  	case syntax.NEQ:
   720  		ok, err := dictsEqual(x, y, depth)
   721  		return !ok, err
   722  	default:
   723  		return false, fmt.Errorf("%s %s %s not implemented", x.Type(), op, y.Type())
   724  	}
   725  }
   726  
   727  func dictsEqual(x, y *Dict, depth int) (bool, error) {
   728  	if x.Len() != y.Len() {
   729  		return false, nil
   730  	}
   731  	for _, xitem := range x.Items() {
   732  		key, xval := xitem[0], xitem[1]
   733  
   734  		if yval, found, _ := y.Get(key); !found {
   735  			return false, nil
   736  		} else if eq, err := EqualDepth(xval, yval, depth-1); err != nil {
   737  			return false, err
   738  		} else if !eq {
   739  			return false, nil
   740  		}
   741  	}
   742  	return true, nil
   743  }
   744  
   745  // A *List represents a Starlark list value.
   746  type List struct {
   747  	elems     []Value
   748  	frozen    bool
   749  	itercount uint32 // number of active iterators (ignored if frozen)
   750  }
   751  
   752  // NewList returns a list containing the specified elements.
   753  // Callers should not subsequently modify elems.
   754  func NewList(elems []Value) *List { return &List{elems: elems} }
   755  
   756  func (l *List) Freeze() {
   757  	if !l.frozen {
   758  		l.frozen = true
   759  		for _, elem := range l.elems {
   760  			elem.Freeze()
   761  		}
   762  	}
   763  }
   764  
   765  // checkMutable reports an error if the list should not be mutated.
   766  // verb+" list" should describe the operation.
   767  func (l *List) checkMutable(verb string) error {
   768  	if l.frozen {
   769  		return fmt.Errorf("cannot %s frozen list", verb)
   770  	}
   771  	if l.itercount > 0 {
   772  		return fmt.Errorf("cannot %s list during iteration", verb)
   773  	}
   774  	return nil
   775  }
   776  
   777  func (l *List) String() string        { return toString(l) }
   778  func (l *List) Type() string          { return "list" }
   779  func (l *List) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable type: list") }
   780  func (l *List) Truth() Bool           { return l.Len() > 0 }
   781  func (l *List) Len() int              { return len(l.elems) }
   782  func (l *List) Index(i int) Value     { return l.elems[i] }
   783  
   784  func (l *List) Slice(start, end, step int) Value {
   785  	if step == 1 {
   786  		elems := append([]Value{}, l.elems[start:end]...)
   787  		return NewList(elems)
   788  	}
   789  
   790  	sign := signum(step)
   791  	var list []Value
   792  	for i := start; signum(end-i) == sign; i += step {
   793  		list = append(list, l.elems[i])
   794  	}
   795  	return NewList(list)
   796  }
   797  
   798  func (l *List) Attr(name string) (Value, error) { return builtinAttr(l, name, listMethods) }
   799  func (l *List) AttrNames() []string             { return builtinAttrNames(listMethods) }
   800  
   801  func (l *List) Iterate() Iterator {
   802  	if !l.frozen {
   803  		l.itercount++
   804  	}
   805  	return &listIterator{l: l}
   806  }
   807  
   808  func (x *List) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {
   809  	y := y_.(*List)
   810  	// It's tempting to check x == y as an optimization here,
   811  	// but wrong because a list containing NaN is not equal to itself.
   812  	return sliceCompare(op, x.elems, y.elems, depth)
   813  }
   814  
   815  func sliceCompare(op syntax.Token, x, y []Value, depth int) (bool, error) {
   816  	// Fast path: check length.
   817  	if len(x) != len(y) && (op == syntax.EQL || op == syntax.NEQ) {
   818  		return op == syntax.NEQ, nil
   819  	}
   820  
   821  	// Find first element that is not equal in both lists.
   822  	for i := 0; i < len(x) && i < len(y); i++ {
   823  		if eq, err := EqualDepth(x[i], y[i], depth-1); err != nil {
   824  			return false, err
   825  		} else if !eq {
   826  			switch op {
   827  			case syntax.EQL:
   828  				return false, nil
   829  			case syntax.NEQ:
   830  				return true, nil
   831  			default:
   832  				return CompareDepth(op, x[i], y[i], depth-1)
   833  			}
   834  		}
   835  	}
   836  
   837  	return threeway(op, len(x)-len(y)), nil
   838  }
   839  
   840  type listIterator struct {
   841  	l *List
   842  	i int
   843  }
   844  
   845  func (it *listIterator) Next(p *Value) bool {
   846  	if it.i < it.l.Len() {
   847  		*p = it.l.elems[it.i]
   848  		it.i++
   849  		return true
   850  	}
   851  	return false
   852  }
   853  
   854  func (it *listIterator) Done() {
   855  	if !it.l.frozen {
   856  		it.l.itercount--
   857  	}
   858  }
   859  
   860  func (l *List) SetIndex(i int, v Value) error {
   861  	if err := l.checkMutable("assign to element of"); err != nil {
   862  		return err
   863  	}
   864  	l.elems[i] = v
   865  	return nil
   866  }
   867  
   868  func (l *List) Append(v Value) error {
   869  	if err := l.checkMutable("append to"); err != nil {
   870  		return err
   871  	}
   872  	l.elems = append(l.elems, v)
   873  	return nil
   874  }
   875  
   876  func (l *List) Clear() error {
   877  	if err := l.checkMutable("clear"); err != nil {
   878  		return err
   879  	}
   880  	for i := range l.elems {
   881  		l.elems[i] = nil // aid GC
   882  	}
   883  	l.elems = l.elems[:0]
   884  	return nil
   885  }
   886  
   887  // A Tuple represents a Starlark tuple value.
   888  type Tuple []Value
   889  
   890  func (t Tuple) Len() int          { return len(t) }
   891  func (t Tuple) Index(i int) Value { return t[i] }
   892  
   893  func (t Tuple) Slice(start, end, step int) Value {
   894  	if step == 1 {
   895  		return t[start:end]
   896  	}
   897  
   898  	sign := signum(step)
   899  	var tuple Tuple
   900  	for i := start; signum(end-i) == sign; i += step {
   901  		tuple = append(tuple, t[i])
   902  	}
   903  	return tuple
   904  }
   905  
   906  func (t Tuple) Iterate() Iterator { return &tupleIterator{elems: t} }
   907  func (t Tuple) Freeze() {
   908  	for _, elem := range t {
   909  		elem.Freeze()
   910  	}
   911  }
   912  func (t Tuple) String() string { return toString(t) }
   913  func (t Tuple) Type() string   { return "tuple" }
   914  func (t Tuple) Truth() Bool    { return len(t) > 0 }
   915  
   916  func (x Tuple) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {
   917  	y := y_.(Tuple)
   918  	return sliceCompare(op, x, y, depth)
   919  }
   920  
   921  func (t Tuple) Hash() (uint32, error) {
   922  	// Use same algorithm as Python.
   923  	var x, mult uint32 = 0x345678, 1000003
   924  	for _, elem := range t {
   925  		y, err := elem.Hash()
   926  		if err != nil {
   927  			return 0, err
   928  		}
   929  		x = x ^ y*mult
   930  		mult += 82520 + uint32(len(t)+len(t))
   931  	}
   932  	return x, nil
   933  }
   934  
   935  type tupleIterator struct{ elems Tuple }
   936  
   937  func (it *tupleIterator) Next(p *Value) bool {
   938  	if len(it.elems) > 0 {
   939  		*p = it.elems[0]
   940  		it.elems = it.elems[1:]
   941  		return true
   942  	}
   943  	return false
   944  }
   945  
   946  func (it *tupleIterator) Done() {}
   947  
   948  // A Set represents a Starlark set value.
   949  // The zero value of Set is a valid empty set.
   950  // If you know the exact final number of elements,
   951  // it is more efficient to call NewSet.
   952  type Set struct {
   953  	ht hashtable // values are all None
   954  }
   955  
   956  // NewSet returns a dictionary with initial space for
   957  // at least size insertions before rehashing.
   958  func NewSet(size int) *Set {
   959  	set := new(Set)
   960  	set.ht.init(size)
   961  	return set
   962  }
   963  
   964  func (s *Set) Delete(k Value) (found bool, err error) { _, found, err = s.ht.delete(k); return }
   965  func (s *Set) Clear() error                           { return s.ht.clear() }
   966  func (s *Set) Has(k Value) (found bool, err error)    { _, found, err = s.ht.lookup(k); return }
   967  func (s *Set) Insert(k Value) error                   { return s.ht.insert(k, None) }
   968  func (s *Set) Len() int                               { return int(s.ht.len) }
   969  func (s *Set) Iterate() Iterator                      { return s.ht.iterate() }
   970  func (s *Set) String() string                         { return toString(s) }
   971  func (s *Set) Type() string                           { return "set" }
   972  func (s *Set) elems() []Value                         { return s.ht.keys() }
   973  func (s *Set) Freeze()                                { s.ht.freeze() }
   974  func (s *Set) Hash() (uint32, error)                  { return 0, fmt.Errorf("unhashable type: set") }
   975  func (s *Set) Truth() Bool                            { return s.Len() > 0 }
   976  
   977  func (s *Set) Attr(name string) (Value, error) { return builtinAttr(s, name, setMethods) }
   978  func (s *Set) AttrNames() []string             { return builtinAttrNames(setMethods) }
   979  
   980  func (x *Set) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {
   981  	y := y_.(*Set)
   982  	switch op {
   983  	case syntax.EQL:
   984  		ok, err := setsEqual(x, y, depth)
   985  		return ok, err
   986  	case syntax.NEQ:
   987  		ok, err := setsEqual(x, y, depth)
   988  		return !ok, err
   989  	default:
   990  		return false, fmt.Errorf("%s %s %s not implemented", x.Type(), op, y.Type())
   991  	}
   992  }
   993  
   994  func setsEqual(x, y *Set, depth int) (bool, error) {
   995  	if x.Len() != y.Len() {
   996  		return false, nil
   997  	}
   998  	for _, elem := range x.elems() {
   999  		if found, _ := y.Has(elem); !found {
  1000  			return false, nil
  1001  		}
  1002  	}
  1003  	return true, nil
  1004  }
  1005  
  1006  func (s *Set) Union(iter Iterator) (Value, error) {
  1007  	set := new(Set)
  1008  	for _, elem := range s.elems() {
  1009  		set.Insert(elem) // can't fail
  1010  	}
  1011  	var x Value
  1012  	for iter.Next(&x) {
  1013  		if err := set.Insert(x); err != nil {
  1014  			return nil, err
  1015  		}
  1016  	}
  1017  	return set, nil
  1018  }
  1019  
  1020  // toString returns the string form of value v.
  1021  // It may be more efficient than v.String() for larger values.
  1022  func toString(v Value) string {
  1023  	buf := new(strings.Builder)
  1024  	writeValue(buf, v, nil)
  1025  	return buf.String()
  1026  }
  1027  
  1028  // writeValue writes x to out.
  1029  //
  1030  // path is used to detect cycles.
  1031  // It contains the list of *List and *Dict values we're currently printing.
  1032  // (These are the only potentially cyclic structures.)
  1033  // Callers should generally pass nil for path.
  1034  // It is safe to re-use the same path slice for multiple calls.
  1035  func writeValue(out *strings.Builder, x Value, path []Value) {
  1036  	switch x := x.(type) {
  1037  	case nil:
  1038  		out.WriteString("<nil>") // indicates a bug
  1039  
  1040  	case NoneType:
  1041  		out.WriteString("None")
  1042  
  1043  	case Int:
  1044  		out.WriteString(x.String())
  1045  
  1046  	case Bool:
  1047  		if x {
  1048  			out.WriteString("True")
  1049  		} else {
  1050  			out.WriteString("False")
  1051  		}
  1052  
  1053  	case String:
  1054  		fmt.Fprintf(out, "%q", string(x))
  1055  
  1056  	case *List:
  1057  		out.WriteByte('[')
  1058  		if pathContains(path, x) {
  1059  			out.WriteString("...") // list contains itself
  1060  		} else {
  1061  			for i, elem := range x.elems {
  1062  				if i > 0 {
  1063  					out.WriteString(", ")
  1064  				}
  1065  				writeValue(out, elem, append(path, x))
  1066  			}
  1067  		}
  1068  		out.WriteByte(']')
  1069  
  1070  	case Tuple:
  1071  		out.WriteByte('(')
  1072  		for i, elem := range x {
  1073  			if i > 0 {
  1074  				out.WriteString(", ")
  1075  			}
  1076  			writeValue(out, elem, path)
  1077  		}
  1078  		if len(x) == 1 {
  1079  			out.WriteByte(',')
  1080  		}
  1081  		out.WriteByte(')')
  1082  
  1083  	case *Function:
  1084  		fmt.Fprintf(out, "<function %s>", x.Name())
  1085  
  1086  	case *Builtin:
  1087  		if x.recv != nil {
  1088  			fmt.Fprintf(out, "<built-in method %s of %s value>", x.Name(), x.recv.Type())
  1089  		} else {
  1090  			fmt.Fprintf(out, "<built-in function %s>", x.Name())
  1091  		}
  1092  
  1093  	case *Dict:
  1094  		out.WriteByte('{')
  1095  		if pathContains(path, x) {
  1096  			out.WriteString("...") // dict contains itself
  1097  		} else {
  1098  			sep := ""
  1099  			for _, item := range x.Items() {
  1100  				k, v := item[0], item[1]
  1101  				out.WriteString(sep)
  1102  				writeValue(out, k, path)
  1103  				out.WriteString(": ")
  1104  				writeValue(out, v, append(path, x)) // cycle check
  1105  				sep = ", "
  1106  			}
  1107  		}
  1108  		out.WriteByte('}')
  1109  
  1110  	case *Set:
  1111  		out.WriteString("set([")
  1112  		for i, elem := range x.elems() {
  1113  			if i > 0 {
  1114  				out.WriteString(", ")
  1115  			}
  1116  			writeValue(out, elem, path)
  1117  		}
  1118  		out.WriteString("])")
  1119  
  1120  	default:
  1121  		out.WriteString(x.String())
  1122  	}
  1123  }
  1124  
  1125  func pathContains(path []Value, x Value) bool {
  1126  	for _, y := range path {
  1127  		if x == y {
  1128  			return true
  1129  		}
  1130  	}
  1131  	return false
  1132  }
  1133  
  1134  const maxdepth = 10
  1135  
  1136  // Equal reports whether two Starlark values are equal.
  1137  func Equal(x, y Value) (bool, error) {
  1138  	if x, ok := x.(String); ok {
  1139  		return x == y, nil // fast path for an important special case
  1140  	}
  1141  	return EqualDepth(x, y, maxdepth)
  1142  }
  1143  
  1144  // EqualDepth reports whether two Starlark values are equal.
  1145  //
  1146  // Recursive comparisons by implementations of Value.CompareSameType
  1147  // should use EqualDepth to prevent infinite recursion.
  1148  func EqualDepth(x, y Value, depth int) (bool, error) {
  1149  	return CompareDepth(syntax.EQL, x, y, depth)
  1150  }
  1151  
  1152  // Compare compares two Starlark values.
  1153  // The comparison operation must be one of EQL, NEQ, LT, LE, GT, or GE.
  1154  // Compare returns an error if an ordered comparison was
  1155  // requested for a type that does not support it.
  1156  //
  1157  // Recursive comparisons by implementations of Value.CompareSameType
  1158  // should use CompareDepth to prevent infinite recursion.
  1159  func Compare(op syntax.Token, x, y Value) (bool, error) {
  1160  	return CompareDepth(op, x, y, maxdepth)
  1161  }
  1162  
  1163  // CompareDepth compares two Starlark values.
  1164  // The comparison operation must be one of EQL, NEQ, LT, LE, GT, or GE.
  1165  // CompareDepth returns an error if an ordered comparison was
  1166  // requested for a pair of values that do not support it.
  1167  //
  1168  // The depth parameter limits the maximum depth of recursion
  1169  // in cyclic data structures.
  1170  func CompareDepth(op syntax.Token, x, y Value, depth int) (bool, error) {
  1171  	if depth < 1 {
  1172  		return false, fmt.Errorf("comparison exceeded maximum recursion depth")
  1173  	}
  1174  	if sameType(x, y) {
  1175  		if xcomp, ok := x.(Comparable); ok {
  1176  			return xcomp.CompareSameType(op, y, depth)
  1177  		}
  1178  
  1179  		// use identity comparison
  1180  		switch op {
  1181  		case syntax.EQL:
  1182  			return x == y, nil
  1183  		case syntax.NEQ:
  1184  			return x != y, nil
  1185  		}
  1186  		return false, fmt.Errorf("%s %s %s not implemented", x.Type(), op, y.Type())
  1187  	}
  1188  
  1189  	// different types
  1190  
  1191  	// int/float ordered comparisons
  1192  	switch x := x.(type) {
  1193  	case Int:
  1194  		if y, ok := y.(Float); ok {
  1195  			if y != y {
  1196  				return false, nil // y is NaN
  1197  			}
  1198  			var cmp int
  1199  			if !math.IsInf(float64(y), 0) {
  1200  				cmp = x.rational().Cmp(y.rational()) // y is finite
  1201  			} else if y > 0 {
  1202  				cmp = -1 // y is +Inf
  1203  			} else {
  1204  				cmp = +1 // y is -Inf
  1205  			}
  1206  			return threeway(op, cmp), nil
  1207  		}
  1208  	case Float:
  1209  		if y, ok := y.(Int); ok {
  1210  			if x != x {
  1211  				return false, nil // x is NaN
  1212  			}
  1213  			var cmp int
  1214  			if !math.IsInf(float64(x), 0) {
  1215  				cmp = x.rational().Cmp(y.rational()) // x is finite
  1216  			} else if x > 0 {
  1217  				cmp = -1 // x is +Inf
  1218  			} else {
  1219  				cmp = +1 // x is -Inf
  1220  			}
  1221  			return threeway(op, cmp), nil
  1222  		}
  1223  	}
  1224  
  1225  	// All other values of different types compare unequal.
  1226  	switch op {
  1227  	case syntax.EQL:
  1228  		return false, nil
  1229  	case syntax.NEQ:
  1230  		return true, nil
  1231  	}
  1232  	return false, fmt.Errorf("%s %s %s not implemented", x.Type(), op, y.Type())
  1233  }
  1234  
  1235  func sameType(x, y Value) bool {
  1236  	return reflect.TypeOf(x) == reflect.TypeOf(y) || x.Type() == y.Type()
  1237  }
  1238  
  1239  // threeway interprets a three-way comparison value cmp (-1, 0, +1)
  1240  // as a boolean comparison (e.g. x < y).
  1241  func threeway(op syntax.Token, cmp int) bool {
  1242  	switch op {
  1243  	case syntax.EQL:
  1244  		return cmp == 0
  1245  	case syntax.NEQ:
  1246  		return cmp != 0
  1247  	case syntax.LE:
  1248  		return cmp <= 0
  1249  	case syntax.LT:
  1250  		return cmp < 0
  1251  	case syntax.GE:
  1252  		return cmp >= 0
  1253  	case syntax.GT:
  1254  		return cmp > 0
  1255  	}
  1256  	panic(op)
  1257  }
  1258  
  1259  func b2i(b bool) int {
  1260  	if b {
  1261  		return 1
  1262  	} else {
  1263  		return 0
  1264  	}
  1265  }
  1266  
  1267  // Len returns the length of a string or sequence value,
  1268  // and -1 for all others.
  1269  //
  1270  // Warning: Len(x) >= 0 does not imply Iterate(x) != nil.
  1271  // A string has a known length but is not directly iterable.
  1272  func Len(x Value) int {
  1273  	switch x := x.(type) {
  1274  	case String:
  1275  		return x.Len()
  1276  	case Sequence:
  1277  		return x.Len()
  1278  	}
  1279  	return -1
  1280  }
  1281  
  1282  // Iterate return a new iterator for the value if iterable, nil otherwise.
  1283  // If the result is non-nil, the caller must call Done when finished with it.
  1284  //
  1285  // Warning: Iterate(x) != nil does not imply Len(x) >= 0.
  1286  // Some iterables may have unknown length.
  1287  func Iterate(x Value) Iterator {
  1288  	if x, ok := x.(Iterable); ok {
  1289  		return x.Iterate()
  1290  	}
  1291  	return nil
  1292  }