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