github.com/google/skylark@v0.0.0-20181101142754-a5f7082aabed/eval.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 skylark
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"io"
    11  	"log"
    12  	"math"
    13  	"math/big"
    14  	"sort"
    15  	"strings"
    16  	"unicode"
    17  	"unicode/utf8"
    18  
    19  	"github.com/google/skylark/internal/compile"
    20  	"github.com/google/skylark/resolve"
    21  	"github.com/google/skylark/syntax"
    22  )
    23  
    24  const debug = false
    25  
    26  // A Thread contains the state of a Skylark thread,
    27  // such as its call stack and thread-local storage.
    28  // The Thread is threaded throughout the evaluator.
    29  type Thread struct {
    30  	// frame is the current Skylark execution frame.
    31  	frame *Frame
    32  
    33  	// Print is the client-supplied implementation of the Skylark
    34  	// 'print' function. If nil, fmt.Fprintln(os.Stderr, msg) is
    35  	// used instead.
    36  	Print func(thread *Thread, msg string)
    37  
    38  	// Load is the client-supplied implementation of module loading.
    39  	// Repeated calls with the same module name must return the same
    40  	// module environment or error.
    41  	// The error message need not include the module name.
    42  	//
    43  	// See example_test.go for some example implementations of Load.
    44  	Load func(thread *Thread, module string) (StringDict, error)
    45  
    46  	// locals holds arbitrary "thread-local" Go values belonging to the client.
    47  	// They are accessible to the client but not to any Skylark program.
    48  	locals map[string]interface{}
    49  }
    50  
    51  // SetLocal sets the thread-local value associated with the specified key.
    52  // It must not be called after execution begins.
    53  func (thread *Thread) SetLocal(key string, value interface{}) {
    54  	if thread.locals == nil {
    55  		thread.locals = make(map[string]interface{})
    56  	}
    57  	thread.locals[key] = value
    58  }
    59  
    60  // Local returns the thread-local value associated with the specified key.
    61  func (thread *Thread) Local(key string) interface{} {
    62  	return thread.locals[key]
    63  }
    64  
    65  // Caller returns the frame of the caller of the current function.
    66  // It should only be used in built-ins called from Skylark code.
    67  func (thread *Thread) Caller() *Frame { return thread.frame.parent }
    68  
    69  // TopFrame returns the topmost stack frame.
    70  func (thread *Thread) TopFrame() *Frame { return thread.frame }
    71  
    72  // A StringDict is a mapping from names to values, and represents
    73  // an environment such as the global variables of a module.
    74  // It is not a true skylark.Value.
    75  type StringDict map[string]Value
    76  
    77  func (d StringDict) String() string {
    78  	names := make([]string, 0, len(d))
    79  	for name := range d {
    80  		names = append(names, name)
    81  	}
    82  	sort.Strings(names)
    83  
    84  	var buf bytes.Buffer
    85  	path := make([]Value, 0, 4)
    86  	buf.WriteByte('{')
    87  	sep := ""
    88  	for _, name := range names {
    89  		buf.WriteString(sep)
    90  		buf.WriteString(name)
    91  		buf.WriteString(": ")
    92  		writeValue(&buf, d[name], path)
    93  		sep = ", "
    94  	}
    95  	buf.WriteByte('}')
    96  	return buf.String()
    97  }
    98  
    99  func (d StringDict) Freeze() {
   100  	for _, v := range d {
   101  		v.Freeze()
   102  	}
   103  }
   104  
   105  // Has reports whether the dictionary contains the specified key.
   106  func (d StringDict) Has(key string) bool { _, ok := d[key]; return ok }
   107  
   108  // A Frame records a call to a Skylark function (including module toplevel)
   109  // or a built-in function or method.
   110  type Frame struct {
   111  	parent   *Frame          // caller's frame (or nil)
   112  	callable Callable        // current function (or toplevel) or built-in
   113  	posn     syntax.Position // source position of PC, set during error
   114  	callpc   uint32          // PC of position of active call, set during call
   115  }
   116  
   117  // The Frames of a thread are structured as a spaghetti stack, not a
   118  // slice, so that an EvalError can copy a stack efficiently and immutably.
   119  // In hindsight using a slice would have led to a more convenient API.
   120  
   121  func (fr *Frame) errorf(posn syntax.Position, format string, args ...interface{}) *EvalError {
   122  	fr.posn = posn
   123  	msg := fmt.Sprintf(format, args...)
   124  	return &EvalError{Msg: msg, Frame: fr}
   125  }
   126  
   127  // Position returns the source position of the current point of execution in this frame.
   128  func (fr *Frame) Position() syntax.Position {
   129  	if fr.posn.IsValid() {
   130  		return fr.posn // leaf frame only (the error)
   131  	}
   132  	if fn, ok := fr.callable.(*Function); ok {
   133  		return fn.funcode.Position(fr.callpc) // position of active call
   134  	}
   135  	return syntax.MakePosition(&builtinFilename, 1, 0)
   136  }
   137  
   138  var builtinFilename = "<builtin>"
   139  
   140  // Function returns the frame's function or built-in.
   141  func (fr *Frame) Callable() Callable { return fr.callable }
   142  
   143  // Parent returns the frame of the enclosing function call, if any.
   144  func (fr *Frame) Parent() *Frame { return fr.parent }
   145  
   146  // An EvalError is a Skylark evaluation error and its associated call stack.
   147  type EvalError struct {
   148  	Msg   string
   149  	Frame *Frame
   150  }
   151  
   152  func (e *EvalError) Error() string { return e.Msg }
   153  
   154  // Backtrace returns a user-friendly error message describing the stack
   155  // of calls that led to this error.
   156  func (e *EvalError) Backtrace() string {
   157  	var buf bytes.Buffer
   158  	e.Frame.WriteBacktrace(&buf)
   159  	fmt.Fprintf(&buf, "Error: %s", e.Msg)
   160  	return buf.String()
   161  }
   162  
   163  // WriteBacktrace writes a user-friendly description of the stack to buf.
   164  func (fr *Frame) WriteBacktrace(out *bytes.Buffer) {
   165  	fmt.Fprintf(out, "Traceback (most recent call last):\n")
   166  	var print func(fr *Frame)
   167  	print = func(fr *Frame) {
   168  		if fr != nil {
   169  			print(fr.parent)
   170  			fmt.Fprintf(out, "  %s: in %s\n", fr.Position(), fr.Callable().Name())
   171  		}
   172  	}
   173  	print(fr)
   174  }
   175  
   176  // Stack returns the stack of frames, innermost first.
   177  func (e *EvalError) Stack() []*Frame {
   178  	var stack []*Frame
   179  	for fr := e.Frame; fr != nil; fr = fr.parent {
   180  		stack = append(stack, fr)
   181  	}
   182  	return stack
   183  }
   184  
   185  // A Program is a compiled Skylark program.
   186  //
   187  // Programs are immutable, and contain no Values.
   188  // A Program may be created by parsing a source file (see SourceProgram)
   189  // or by loading a previously saved compiled program (see CompiledProgram).
   190  type Program struct {
   191  	compiled *compile.Program
   192  }
   193  
   194  // CompilerVersion is the version number of the protocol for compiled
   195  // files. Applications must not run programs compiled by one version
   196  // with an interpreter at another version, and should thus incorporate
   197  // the compiler version into the cache key when reusing compiled code.
   198  const CompilerVersion = compile.Version
   199  
   200  // NumLoads returns the number of load statements in the compiled program.
   201  func (prog *Program) NumLoads() int { return len(prog.compiled.Loads) }
   202  
   203  // Load(i) returns the name and position of the i'th module directly
   204  // loaded by this one, where 0 <= i < NumLoads().
   205  // The name is unresolved---exactly as it appears in the source.
   206  func (prog *Program) Load(i int) (string, syntax.Position) {
   207  	id := prog.compiled.Loads[i]
   208  	return id.Name, id.Pos
   209  }
   210  
   211  // WriteTo writes the compiled module to the specified output stream.
   212  func (prog *Program) Write(out io.Writer) error { return prog.compiled.Write(out) }
   213  
   214  // ExecFile parses, resolves, and executes a Skylark file in the
   215  // specified global environment, which may be modified during execution.
   216  //
   217  // Thread is the state associated with the Skylark thread.
   218  //
   219  // The filename and src parameters are as for syntax.Parse:
   220  // filename is the name of the file to execute,
   221  // and the name that appears in error messages;
   222  // src is an optional source of bytes to use
   223  // instead of filename.
   224  //
   225  // predeclared defines the predeclared names specific to this module.
   226  // Execution does not modify this dictionary, though it may mutate
   227  // its values.
   228  //
   229  // If ExecFile fails during evaluation, it returns an *EvalError
   230  // containing a backtrace.
   231  func ExecFile(thread *Thread, filename string, src interface{}, predeclared StringDict) (StringDict, error) {
   232  	// Parse, resolve, and compile a Skylark source file.
   233  	_, mod, err := SourceProgram(filename, src, predeclared.Has)
   234  	if err != nil {
   235  		return nil, err
   236  	}
   237  
   238  	g, err := mod.Init(thread, predeclared)
   239  	g.Freeze()
   240  	return g, err
   241  }
   242  
   243  // SourceProgram produces a new program by parsing, resolving,
   244  // and compiling a Skylark source file.
   245  // On success, it returns the parsed file and the compiled program.
   246  // The filename and src parameters are as for syntax.Parse.
   247  //
   248  // The isPredeclared predicate reports whether a name is
   249  // a pre-declared identifier of the current module.
   250  // Its typical value is predeclared.Has,
   251  // where predeclared is a StringDict of pre-declared values.
   252  func SourceProgram(filename string, src interface{}, isPredeclared func(string) bool) (*syntax.File, *Program, error) {
   253  	f, err := syntax.Parse(filename, src, 0)
   254  	if err != nil {
   255  		return nil, nil, err
   256  	}
   257  
   258  	if err := resolve.File(f, isPredeclared, Universe.Has); err != nil {
   259  		return f, nil, err
   260  	}
   261  
   262  	compiled := compile.File(f.Stmts, f.Locals, f.Globals)
   263  
   264  	return f, &Program{compiled}, nil
   265  }
   266  
   267  // CompiledProgram produces a new program from the representation
   268  // of a compiled program previously saved by Program.Write.
   269  func CompiledProgram(in io.Reader) (*Program, error) {
   270  	prog, err := compile.ReadProgram(in)
   271  	if err != nil {
   272  		return nil, err
   273  	}
   274  	return &Program{prog}, nil
   275  }
   276  
   277  // Init creates a set of global variables for the program,
   278  // executes the toplevel code of the specified program,
   279  // and returns a new, unfrozen dictionary of the globals.
   280  func (prog *Program) Init(thread *Thread, predeclared StringDict) (StringDict, error) {
   281  	toplevel := makeToplevelFunction(prog.compiled.Toplevel, predeclared)
   282  
   283  	_, err := Call(thread, toplevel, nil, nil)
   284  
   285  	// Convert the global environment to a map and freeze it.
   286  	// We return a (partial) map even in case of error.
   287  	return toplevel.Globals(), err
   288  }
   289  
   290  func makeToplevelFunction(funcode *compile.Funcode, predeclared StringDict) *Function {
   291  	// Create the Skylark value denoted by each program constant c.
   292  	constants := make([]Value, len(funcode.Prog.Constants))
   293  	for i, c := range funcode.Prog.Constants {
   294  		var v Value
   295  		switch c := c.(type) {
   296  		case int64:
   297  			v = MakeInt64(c)
   298  		case *big.Int:
   299  			v = Int{c}
   300  		case string:
   301  			v = String(c)
   302  		case float64:
   303  			v = Float(c)
   304  		default:
   305  			log.Fatalf("unexpected constant %T: %v", c, c)
   306  		}
   307  		constants[i] = v
   308  	}
   309  
   310  	return &Function{
   311  		funcode:     funcode,
   312  		predeclared: predeclared,
   313  		globals:     make([]Value, len(funcode.Prog.Globals)),
   314  		constants:   constants,
   315  	}
   316  }
   317  
   318  // Eval parses, resolves, and evaluates an expression within the
   319  // specified (predeclared) environment.
   320  //
   321  // Evaluation cannot mutate the environment dictionary itself,
   322  // though it may modify variables reachable from the dictionary.
   323  //
   324  // The filename and src parameters are as for syntax.Parse.
   325  //
   326  // If Eval fails during evaluation, it returns an *EvalError
   327  // containing a backtrace.
   328  func Eval(thread *Thread, filename string, src interface{}, env StringDict) (Value, error) {
   329  	expr, err := syntax.ParseExpr(filename, src, 0)
   330  	if err != nil {
   331  		return nil, err
   332  	}
   333  
   334  	locals, err := resolve.Expr(expr, env.Has, Universe.Has)
   335  	if err != nil {
   336  		return nil, err
   337  	}
   338  
   339  	fn := makeToplevelFunction(compile.Expr(expr, locals), env)
   340  
   341  	return Call(thread, fn, nil, nil)
   342  }
   343  
   344  // The following functions are primitive operations of the byte code interpreter.
   345  
   346  // list += iterable
   347  func listExtend(x *List, y Iterable) {
   348  	if ylist, ok := y.(*List); ok {
   349  		// fast path: list += list
   350  		x.elems = append(x.elems, ylist.elems...)
   351  	} else {
   352  		iter := y.Iterate()
   353  		defer iter.Done()
   354  		var z Value
   355  		for iter.Next(&z) {
   356  			x.elems = append(x.elems, z)
   357  		}
   358  	}
   359  }
   360  
   361  // getAttr implements x.dot.
   362  func getAttr(fr *Frame, x Value, name string) (Value, error) {
   363  	// field or method?
   364  	if x, ok := x.(HasAttrs); ok {
   365  		if v, err := x.Attr(name); v != nil || err != nil {
   366  			return v, err
   367  		}
   368  	}
   369  
   370  	return nil, fmt.Errorf("%s has no .%s field or method", x.Type(), name)
   371  }
   372  
   373  // setField implements x.name = y.
   374  func setField(fr *Frame, x Value, name string, y Value) error {
   375  	if x, ok := x.(HasSetField); ok {
   376  		err := x.SetField(name, y)
   377  		return err
   378  	}
   379  	return fmt.Errorf("can't assign to .%s field of %s", name, x.Type())
   380  }
   381  
   382  // getIndex implements x[y].
   383  func getIndex(fr *Frame, x, y Value) (Value, error) {
   384  	switch x := x.(type) {
   385  	case Mapping: // dict
   386  		z, found, err := x.Get(y)
   387  		if err != nil {
   388  			return nil, err
   389  		}
   390  		if !found {
   391  			return nil, fmt.Errorf("key %v not in %s", y, x.Type())
   392  		}
   393  		return z, nil
   394  
   395  	case Indexable: // string, list, tuple
   396  		n := x.Len()
   397  		i, err := AsInt32(y)
   398  		if err != nil {
   399  			return nil, fmt.Errorf("%s index: %s", x.Type(), err)
   400  		}
   401  		if i < 0 {
   402  			i += n
   403  		}
   404  		if i < 0 || i >= n {
   405  			return nil, fmt.Errorf("%s index %d out of range [0:%d]",
   406  				x.Type(), i, n)
   407  		}
   408  		return x.Index(i), nil
   409  	}
   410  	return nil, fmt.Errorf("unhandled index operation %s[%s]", x.Type(), y.Type())
   411  }
   412  
   413  // setIndex implements x[y] = z.
   414  func setIndex(fr *Frame, x, y, z Value) error {
   415  	switch x := x.(type) {
   416  	case HasSetKey:
   417  		if err := x.SetKey(y, z); err != nil {
   418  			return err
   419  		}
   420  
   421  	case HasSetIndex:
   422  		i, err := AsInt32(y)
   423  		if err != nil {
   424  			return err
   425  		}
   426  		if i < 0 {
   427  			i += x.Len()
   428  		}
   429  		if i < 0 || i >= x.Len() {
   430  			return fmt.Errorf("%s index %d out of range [0:%d]", x.Type(), i, x.Len())
   431  		}
   432  		return x.SetIndex(i, z)
   433  
   434  	default:
   435  		return fmt.Errorf("%s value does not support item assignment", x.Type())
   436  	}
   437  	return nil
   438  }
   439  
   440  // Unary applies a unary operator (+, -, ~, not) to its operand.
   441  func Unary(op syntax.Token, x Value) (Value, error) {
   442  	switch op {
   443  	case syntax.MINUS:
   444  		switch x := x.(type) {
   445  		case Int:
   446  			return zero.Sub(x), nil
   447  		case Float:
   448  			return -x, nil
   449  		}
   450  	case syntax.PLUS:
   451  		switch x.(type) {
   452  		case Int, Float:
   453  			return x, nil
   454  		}
   455  	case syntax.TILDE:
   456  		if xint, ok := x.(Int); ok {
   457  			return xint.Not(), nil
   458  		}
   459  	case syntax.NOT:
   460  		return !x.Truth(), nil
   461  	}
   462  	return nil, fmt.Errorf("unknown unary op: %s %s", op, x.Type())
   463  }
   464  
   465  // Binary applies a strict binary operator (not AND or OR) to its operands.
   466  // For equality tests or ordered comparisons, use Compare instead.
   467  func Binary(op syntax.Token, x, y Value) (Value, error) {
   468  	switch op {
   469  	case syntax.PLUS:
   470  		switch x := x.(type) {
   471  		case String:
   472  			if y, ok := y.(String); ok {
   473  				return x + y, nil
   474  			}
   475  		case Int:
   476  			switch y := y.(type) {
   477  			case Int:
   478  				return x.Add(y), nil
   479  			case Float:
   480  				return x.Float() + y, nil
   481  			}
   482  		case Float:
   483  			switch y := y.(type) {
   484  			case Float:
   485  				return x + y, nil
   486  			case Int:
   487  				return x + y.Float(), nil
   488  			}
   489  		case *List:
   490  			if y, ok := y.(*List); ok {
   491  				z := make([]Value, 0, x.Len()+y.Len())
   492  				z = append(z, x.elems...)
   493  				z = append(z, y.elems...)
   494  				return NewList(z), nil
   495  			}
   496  		case Tuple:
   497  			if y, ok := y.(Tuple); ok {
   498  				z := make(Tuple, 0, len(x)+len(y))
   499  				z = append(z, x...)
   500  				z = append(z, y...)
   501  				return z, nil
   502  			}
   503  		case *Dict:
   504  			// Python doesn't have dict+dict, and I can't find
   505  			// it documented for Skylark.  But it is used; see:
   506  			//   tools/build_defs/haskell/def.bzl:448
   507  			// TODO(adonovan): clarify spec; see b/36360157.
   508  			if y, ok := y.(*Dict); ok {
   509  				z := new(Dict)
   510  				for _, item := range x.Items() {
   511  					z.SetKey(item[0], item[1])
   512  				}
   513  				for _, item := range y.Items() {
   514  					z.SetKey(item[0], item[1])
   515  				}
   516  				return z, nil
   517  			}
   518  		}
   519  
   520  	case syntax.MINUS:
   521  		switch x := x.(type) {
   522  		case Int:
   523  			switch y := y.(type) {
   524  			case Int:
   525  				return x.Sub(y), nil
   526  			case Float:
   527  				return x.Float() - y, nil
   528  			}
   529  		case Float:
   530  			switch y := y.(type) {
   531  			case Float:
   532  				return x - y, nil
   533  			case Int:
   534  				return x - y.Float(), nil
   535  			}
   536  		}
   537  
   538  	case syntax.STAR:
   539  		switch x := x.(type) {
   540  		case Int:
   541  			switch y := y.(type) {
   542  			case Int:
   543  				return x.Mul(y), nil
   544  			case Float:
   545  				return x.Float() * y, nil
   546  			case String:
   547  				if i, err := AsInt32(x); err == nil {
   548  					if i < 1 {
   549  						return String(""), nil
   550  					}
   551  					return String(strings.Repeat(string(y), i)), nil
   552  				}
   553  			case *List:
   554  				if i, err := AsInt32(x); err == nil {
   555  					return NewList(repeat(y.elems, i)), nil
   556  				}
   557  			case Tuple:
   558  				if i, err := AsInt32(x); err == nil {
   559  					return Tuple(repeat([]Value(y), i)), nil
   560  				}
   561  			}
   562  		case Float:
   563  			switch y := y.(type) {
   564  			case Float:
   565  				return x * y, nil
   566  			case Int:
   567  				return x * y.Float(), nil
   568  			}
   569  		case String:
   570  			if y, ok := y.(Int); ok {
   571  				if i, err := AsInt32(y); err == nil {
   572  					if i < 1 {
   573  						return String(""), nil
   574  					}
   575  					return String(strings.Repeat(string(x), i)), nil
   576  				}
   577  			}
   578  		case *List:
   579  			if y, ok := y.(Int); ok {
   580  				if i, err := AsInt32(y); err == nil {
   581  					return NewList(repeat(x.elems, i)), nil
   582  				}
   583  			}
   584  		case Tuple:
   585  			if y, ok := y.(Int); ok {
   586  				if i, err := AsInt32(y); err == nil {
   587  					return Tuple(repeat([]Value(x), i)), nil
   588  				}
   589  			}
   590  
   591  		}
   592  
   593  	case syntax.SLASH:
   594  		switch x := x.(type) {
   595  		case Int:
   596  			switch y := y.(type) {
   597  			case Int:
   598  				yf := y.Float()
   599  				if yf == 0.0 {
   600  					return nil, fmt.Errorf("real division by zero")
   601  				}
   602  				return x.Float() / yf, nil
   603  			case Float:
   604  				if y == 0.0 {
   605  					return nil, fmt.Errorf("real division by zero")
   606  				}
   607  				return x.Float() / y, nil
   608  			}
   609  		case Float:
   610  			switch y := y.(type) {
   611  			case Float:
   612  				if y == 0.0 {
   613  					return nil, fmt.Errorf("real division by zero")
   614  				}
   615  				return x / y, nil
   616  			case Int:
   617  				yf := y.Float()
   618  				if yf == 0.0 {
   619  					return nil, fmt.Errorf("real division by zero")
   620  				}
   621  				return x / yf, nil
   622  			}
   623  		}
   624  
   625  	case syntax.SLASHSLASH:
   626  		switch x := x.(type) {
   627  		case Int:
   628  			switch y := y.(type) {
   629  			case Int:
   630  				if y.Sign() == 0 {
   631  					return nil, fmt.Errorf("floored division by zero")
   632  				}
   633  				return x.Div(y), nil
   634  			case Float:
   635  				if y == 0.0 {
   636  					return nil, fmt.Errorf("floored division by zero")
   637  				}
   638  				return floor((x.Float() / y)), nil
   639  			}
   640  		case Float:
   641  			switch y := y.(type) {
   642  			case Float:
   643  				if y == 0.0 {
   644  					return nil, fmt.Errorf("floored division by zero")
   645  				}
   646  				return floor(x / y), nil
   647  			case Int:
   648  				yf := y.Float()
   649  				if yf == 0.0 {
   650  					return nil, fmt.Errorf("floored division by zero")
   651  				}
   652  				return floor(x / yf), nil
   653  			}
   654  		}
   655  
   656  	case syntax.PERCENT:
   657  		switch x := x.(type) {
   658  		case Int:
   659  			switch y := y.(type) {
   660  			case Int:
   661  				if y.Sign() == 0 {
   662  					return nil, fmt.Errorf("integer modulo by zero")
   663  				}
   664  				return x.Mod(y), nil
   665  			case Float:
   666  				if y == 0 {
   667  					return nil, fmt.Errorf("float modulo by zero")
   668  				}
   669  				return x.Float().Mod(y), nil
   670  			}
   671  		case Float:
   672  			switch y := y.(type) {
   673  			case Float:
   674  				if y == 0.0 {
   675  					return nil, fmt.Errorf("float modulo by zero")
   676  				}
   677  				return Float(math.Mod(float64(x), float64(y))), nil
   678  			case Int:
   679  				if y.Sign() == 0 {
   680  					return nil, fmt.Errorf("float modulo by zero")
   681  				}
   682  				return x.Mod(y.Float()), nil
   683  			}
   684  		case String:
   685  			return interpolate(string(x), y)
   686  		}
   687  
   688  	case syntax.NOT_IN:
   689  		z, err := Binary(syntax.IN, x, y)
   690  		if err != nil {
   691  			return nil, err
   692  		}
   693  		return !z.Truth(), nil
   694  
   695  	case syntax.IN:
   696  		switch y := y.(type) {
   697  		case *List:
   698  			for _, elem := range y.elems {
   699  				if eq, err := Equal(elem, x); err != nil {
   700  					return nil, err
   701  				} else if eq {
   702  					return True, nil
   703  				}
   704  			}
   705  			return False, nil
   706  		case Tuple:
   707  			for _, elem := range y {
   708  				if eq, err := Equal(elem, x); err != nil {
   709  					return nil, err
   710  				} else if eq {
   711  					return True, nil
   712  				}
   713  			}
   714  			return False, nil
   715  		case Mapping: // e.g. dict
   716  			// Ignore error from Get as we cannot distinguish true
   717  			// errors (value cycle, type error) from "key not found".
   718  			_, found, _ := y.Get(x)
   719  			return Bool(found), nil
   720  		case *Set:
   721  			ok, err := y.Has(x)
   722  			return Bool(ok), err
   723  		case String:
   724  			needle, ok := x.(String)
   725  			if !ok {
   726  				return nil, fmt.Errorf("'in <string>' requires string as left operand, not %s", x.Type())
   727  			}
   728  			return Bool(strings.Contains(string(y), string(needle))), nil
   729  		case rangeValue:
   730  			i, err := NumberToInt(x)
   731  			if err != nil {
   732  				return nil, fmt.Errorf("'in <range>' requires integer as left operand, not %s", x.Type())
   733  			}
   734  			return Bool(y.contains(i)), nil
   735  		}
   736  
   737  	case syntax.PIPE:
   738  		switch x := x.(type) {
   739  		case Int:
   740  			if y, ok := y.(Int); ok {
   741  				return x.Or(y), nil
   742  			}
   743  		case *Set: // union
   744  			if y, ok := y.(*Set); ok {
   745  				iter := Iterate(y)
   746  				defer iter.Done()
   747  				return x.Union(iter)
   748  			}
   749  		}
   750  
   751  	case syntax.AMP:
   752  		switch x := x.(type) {
   753  		case Int:
   754  			if y, ok := y.(Int); ok {
   755  				return x.And(y), nil
   756  			}
   757  		case *Set: // intersection
   758  			if y, ok := y.(*Set); ok {
   759  				set := new(Set)
   760  				if x.Len() > y.Len() {
   761  					x, y = y, x // opt: range over smaller set
   762  				}
   763  				for _, xelem := range x.elems() {
   764  					// Has, Insert cannot fail here.
   765  					if found, _ := y.Has(xelem); found {
   766  						set.Insert(xelem)
   767  					}
   768  				}
   769  				return set, nil
   770  			}
   771  		}
   772  
   773  	case syntax.CIRCUMFLEX:
   774  		switch x := x.(type) {
   775  		case Int:
   776  			if y, ok := y.(Int); ok {
   777  				return x.Xor(y), nil
   778  			}
   779  		case *Set: // symmetric difference
   780  			if y, ok := y.(*Set); ok {
   781  				set := new(Set)
   782  				for _, xelem := range x.elems() {
   783  					if found, _ := y.Has(xelem); !found {
   784  						set.Insert(xelem)
   785  					}
   786  				}
   787  				for _, yelem := range y.elems() {
   788  					if found, _ := x.Has(yelem); !found {
   789  						set.Insert(yelem)
   790  					}
   791  				}
   792  				return set, nil
   793  			}
   794  		}
   795  
   796  	case syntax.LTLT, syntax.GTGT:
   797  		if x, ok := x.(Int); ok {
   798  			y, err := AsInt32(y)
   799  			if err != nil {
   800  				return nil, err
   801  			}
   802  			if y < 0 {
   803  				return nil, fmt.Errorf("negative shift count: %v", y)
   804  			}
   805  			if op == syntax.LTLT {
   806  				if y >= 512 {
   807  					return nil, fmt.Errorf("shift count too large: %v", y)
   808  				}
   809  				return x.Lsh(uint(y)), nil
   810  			} else {
   811  				return x.Rsh(uint(y)), nil
   812  			}
   813  		}
   814  
   815  	default:
   816  		// unknown operator
   817  		goto unknown
   818  	}
   819  
   820  	// user-defined types
   821  	if x, ok := x.(HasBinary); ok {
   822  		z, err := x.Binary(op, y, Left)
   823  		if z != nil || err != nil {
   824  			return z, err
   825  		}
   826  	}
   827  	if y, ok := y.(HasBinary); ok {
   828  		z, err := y.Binary(op, x, Right)
   829  		if z != nil || err != nil {
   830  			return z, err
   831  		}
   832  	}
   833  
   834  	// unsupported operand types
   835  unknown:
   836  	return nil, fmt.Errorf("unknown binary op: %s %s %s", x.Type(), op, y.Type())
   837  }
   838  
   839  func repeat(elems []Value, n int) (res []Value) {
   840  	if n > 0 {
   841  		res = make([]Value, 0, len(elems)*n)
   842  		for i := 0; i < n; i++ {
   843  			res = append(res, elems...)
   844  		}
   845  	}
   846  	return res
   847  }
   848  
   849  // Call calls the function fn with the specified positional and keyword arguments.
   850  func Call(thread *Thread, fn Value, args Tuple, kwargs []Tuple) (Value, error) {
   851  	c, ok := fn.(Callable)
   852  	if !ok {
   853  		return nil, fmt.Errorf("invalid call of non-function (%s)", fn.Type())
   854  	}
   855  
   856  	thread.frame = &Frame{parent: thread.frame, callable: c}
   857  	result, err := c.CallInternal(thread, args, kwargs)
   858  	thread.frame = thread.frame.parent
   859  
   860  	// Sanity check: nil is not a valid Skylark value.
   861  	if result == nil && err == nil {
   862  		return nil, fmt.Errorf("internal error: nil (not None) returned from %s", fn)
   863  	}
   864  
   865  	return result, err
   866  }
   867  
   868  func slice(x, lo, hi, step_ Value) (Value, error) {
   869  	sliceable, ok := x.(Sliceable)
   870  	if !ok {
   871  		return nil, fmt.Errorf("invalid slice operand %s", x.Type())
   872  	}
   873  
   874  	n := sliceable.Len()
   875  	step := 1
   876  	if step_ != None {
   877  		var err error
   878  		step, err = AsInt32(step_)
   879  		if err != nil {
   880  			return nil, fmt.Errorf("got %s for slice step, want int", step_.Type())
   881  		}
   882  		if step == 0 {
   883  			return nil, fmt.Errorf("zero is not a valid slice step")
   884  		}
   885  	}
   886  
   887  	// TODO(adonovan): opt: preallocate result array.
   888  
   889  	var start, end int
   890  	if step > 0 {
   891  		// positive stride
   892  		// default indices are [0:n].
   893  		var err error
   894  		start, end, err = indices(lo, hi, n)
   895  		if err != nil {
   896  			return nil, err
   897  		}
   898  
   899  		if end < start {
   900  			end = start // => empty result
   901  		}
   902  	} else {
   903  		// negative stride
   904  		// default indices are effectively [n-1:-1], though to
   905  		// get this effect using explicit indices requires
   906  		// [n-1:-1-n:-1] because of the treatment of -ve values.
   907  		start = n - 1
   908  		if err := asIndex(lo, n, &start); err != nil {
   909  			return nil, fmt.Errorf("invalid start index: %s", err)
   910  		}
   911  		if start >= n {
   912  			start = n - 1
   913  		}
   914  
   915  		end = -1
   916  		if err := asIndex(hi, n, &end); err != nil {
   917  			return nil, fmt.Errorf("invalid end index: %s", err)
   918  		}
   919  		if end < -1 {
   920  			end = -1
   921  		}
   922  
   923  		if start < end {
   924  			start = end // => empty result
   925  		}
   926  	}
   927  
   928  	return sliceable.Slice(start, end, step), nil
   929  }
   930  
   931  // From Hacker's Delight, section 2.8.
   932  func signum(x int) int { return int(uint64(int64(x)>>63) | (uint64(-x) >> 63)) }
   933  
   934  // indices converts start_ and end_ to indices in the range [0:len].
   935  // The start index defaults to 0 and the end index defaults to len.
   936  // An index -len < i < 0 is treated like i+len.
   937  // All other indices outside the range are clamped to the nearest value in the range.
   938  // Beware: start may be greater than end.
   939  // This function is suitable only for slices with positive strides.
   940  func indices(start_, end_ Value, len int) (start, end int, err error) {
   941  	start = 0
   942  	if err := asIndex(start_, len, &start); err != nil {
   943  		return 0, 0, fmt.Errorf("invalid start index: %s", err)
   944  	}
   945  	// Clamp to [0:len].
   946  	if start < 0 {
   947  		start = 0
   948  	} else if start > len {
   949  		start = len
   950  	}
   951  
   952  	end = len
   953  	if err := asIndex(end_, len, &end); err != nil {
   954  		return 0, 0, fmt.Errorf("invalid end index: %s", err)
   955  	}
   956  	// Clamp to [0:len].
   957  	if end < 0 {
   958  		end = 0
   959  	} else if end > len {
   960  		end = len
   961  	}
   962  
   963  	return start, end, nil
   964  }
   965  
   966  // asIndex sets *result to the integer value of v, adding len to it
   967  // if it is negative.  If v is nil or None, *result is unchanged.
   968  func asIndex(v Value, len int, result *int) error {
   969  	if v != nil && v != None {
   970  		var err error
   971  		*result, err = AsInt32(v)
   972  		if err != nil {
   973  			return fmt.Errorf("got %s, want int", v.Type())
   974  		}
   975  		if *result < 0 {
   976  			*result += len
   977  		}
   978  	}
   979  	return nil
   980  }
   981  
   982  // setArgs sets the values of the formal parameters of function fn in
   983  // based on the actual parameter values in args and kwargs.
   984  func setArgs(locals []Value, fn *Function, args Tuple, kwargs []Tuple) error {
   985  	cond := func(x bool, y, z interface{}) interface{} {
   986  		if x {
   987  			return y
   988  		}
   989  		return z
   990  	}
   991  
   992  	// nparams is the number of ordinary parameters (sans * or **).
   993  	nparams := fn.NumParams()
   994  	if fn.HasVarargs() {
   995  		nparams--
   996  	}
   997  	if fn.HasKwargs() {
   998  		nparams--
   999  	}
  1000  
  1001  	// This is the algorithm from PyEval_EvalCodeEx.
  1002  	var kwdict *Dict
  1003  	n := len(args)
  1004  	if nparams > 0 || fn.HasVarargs() || fn.HasKwargs() {
  1005  		if fn.HasKwargs() {
  1006  			kwdict = new(Dict)
  1007  			locals[fn.NumParams()-1] = kwdict
  1008  		}
  1009  
  1010  		// too many args?
  1011  		if len(args) > nparams {
  1012  			if !fn.HasVarargs() {
  1013  				return fmt.Errorf("function %s takes %s %d argument%s (%d given)",
  1014  					fn.Name(),
  1015  					cond(len(fn.defaults) > 0, "at most", "exactly"),
  1016  					nparams,
  1017  					cond(nparams == 1, "", "s"),
  1018  					len(args)+len(kwargs))
  1019  			}
  1020  			n = nparams
  1021  		}
  1022  
  1023  		// set of defined (regular) parameters
  1024  		var defined intset
  1025  		defined.init(nparams)
  1026  
  1027  		// ordinary parameters
  1028  		for i := 0; i < n; i++ {
  1029  			locals[i] = args[i]
  1030  			defined.set(i)
  1031  		}
  1032  
  1033  		// variadic arguments
  1034  		if fn.HasVarargs() {
  1035  			tuple := make(Tuple, len(args)-n)
  1036  			for i := n; i < len(args); i++ {
  1037  				tuple[i-n] = args[i]
  1038  			}
  1039  			locals[nparams] = tuple
  1040  		}
  1041  
  1042  		// keyword arguments
  1043  		paramIdents := fn.funcode.Locals[:nparams]
  1044  		for _, pair := range kwargs {
  1045  			k, v := pair[0].(String), pair[1]
  1046  			if i := findParam(paramIdents, string(k)); i >= 0 {
  1047  				if defined.set(i) {
  1048  					return fmt.Errorf("function %s got multiple values for keyword argument %s", fn.Name(), k)
  1049  				}
  1050  				locals[i] = v
  1051  				continue
  1052  			}
  1053  			if kwdict == nil {
  1054  				return fmt.Errorf("function %s got an unexpected keyword argument %s", fn.Name(), k)
  1055  			}
  1056  			kwdict.SetKey(k, v)
  1057  		}
  1058  
  1059  		// default values
  1060  		if len(args) < nparams {
  1061  			m := nparams - len(fn.defaults) // first default
  1062  
  1063  			// report errors for missing non-optional arguments
  1064  			i := len(args)
  1065  			for ; i < m; i++ {
  1066  				if !defined.get(i) {
  1067  					return fmt.Errorf("function %s takes %s %d argument%s (%d given)",
  1068  						fn.Name(),
  1069  						cond(fn.HasVarargs() || len(fn.defaults) > 0, "at least", "exactly"),
  1070  						m,
  1071  						cond(m == 1, "", "s"),
  1072  						defined.len())
  1073  				}
  1074  			}
  1075  
  1076  			// set default values
  1077  			for ; i < nparams; i++ {
  1078  				if !defined.get(i) {
  1079  					locals[i] = fn.defaults[i-m]
  1080  				}
  1081  			}
  1082  		}
  1083  	} else if nactual := len(args) + len(kwargs); nactual > 0 {
  1084  		return fmt.Errorf("function %s takes no arguments (%d given)", fn.Name(), nactual)
  1085  	}
  1086  	return nil
  1087  }
  1088  
  1089  func findParam(params []compile.Ident, name string) int {
  1090  	for i, param := range params {
  1091  		if param.Name == name {
  1092  			return i
  1093  		}
  1094  	}
  1095  	return -1
  1096  }
  1097  
  1098  type intset struct {
  1099  	small uint64       // bitset, used if n < 64
  1100  	large map[int]bool //    set, used if n >= 64
  1101  }
  1102  
  1103  func (is *intset) init(n int) {
  1104  	if n >= 64 {
  1105  		is.large = make(map[int]bool)
  1106  	}
  1107  }
  1108  
  1109  func (is *intset) set(i int) (prev bool) {
  1110  	if is.large == nil {
  1111  		prev = is.small&(1<<uint(i)) != 0
  1112  		is.small |= 1 << uint(i)
  1113  	} else {
  1114  		prev = is.large[i]
  1115  		is.large[i] = true
  1116  	}
  1117  	return
  1118  }
  1119  
  1120  func (is *intset) get(i int) bool {
  1121  	if is.large == nil {
  1122  		return is.small&(1<<uint(i)) != 0
  1123  	}
  1124  	return is.large[i]
  1125  }
  1126  
  1127  func (is *intset) len() int {
  1128  	if is.large == nil {
  1129  		// Suboptimal, but used only for error reporting.
  1130  		len := 0
  1131  		for i := 0; i < 64; i++ {
  1132  			if is.small&(1<<uint(i)) != 0 {
  1133  				len++
  1134  			}
  1135  		}
  1136  		return len
  1137  	}
  1138  	return len(is.large)
  1139  }
  1140  
  1141  // https://github.com/google/skylark/blob/master/doc/spec.md#string-interpolation
  1142  func interpolate(format string, x Value) (Value, error) {
  1143  	var buf bytes.Buffer
  1144  	path := make([]Value, 0, 4)
  1145  	index := 0
  1146  	for {
  1147  		i := strings.IndexByte(format, '%')
  1148  		if i < 0 {
  1149  			buf.WriteString(format)
  1150  			break
  1151  		}
  1152  		buf.WriteString(format[:i])
  1153  		format = format[i+1:]
  1154  
  1155  		if format != "" && format[0] == '%' {
  1156  			buf.WriteByte('%')
  1157  			format = format[1:]
  1158  			continue
  1159  		}
  1160  
  1161  		var arg Value
  1162  		if format != "" && format[0] == '(' {
  1163  			// keyword argument: %(name)s.
  1164  			format = format[1:]
  1165  			j := strings.IndexByte(format, ')')
  1166  			if j < 0 {
  1167  				return nil, fmt.Errorf("incomplete format key")
  1168  			}
  1169  			key := format[:j]
  1170  			if dict, ok := x.(Mapping); !ok {
  1171  				return nil, fmt.Errorf("format requires a mapping")
  1172  			} else if v, found, _ := dict.Get(String(key)); found {
  1173  				arg = v
  1174  			} else {
  1175  				return nil, fmt.Errorf("key not found: %s", key)
  1176  			}
  1177  			format = format[j+1:]
  1178  		} else {
  1179  			// positional argument: %s.
  1180  			if tuple, ok := x.(Tuple); ok {
  1181  				if index >= len(tuple) {
  1182  					return nil, fmt.Errorf("not enough arguments for format string")
  1183  				}
  1184  				arg = tuple[index]
  1185  			} else if index > 0 {
  1186  				return nil, fmt.Errorf("not enough arguments for format string")
  1187  			} else {
  1188  				arg = x
  1189  			}
  1190  		}
  1191  
  1192  		// NOTE: Skylark does not support any of these optional Python features:
  1193  		// - optional conversion flags: [#0- +], etc.
  1194  		// - optional minimum field width (number or *).
  1195  		// - optional precision (.123 or *)
  1196  		// - optional length modifier
  1197  
  1198  		// conversion type
  1199  		if format == "" {
  1200  			return nil, fmt.Errorf("incomplete format")
  1201  		}
  1202  		switch c := format[0]; c {
  1203  		case 's', 'r':
  1204  			if str, ok := AsString(arg); ok && c == 's' {
  1205  				buf.WriteString(str)
  1206  			} else {
  1207  				writeValue(&buf, arg, path)
  1208  			}
  1209  		case 'd', 'i', 'o', 'x', 'X':
  1210  			i, err := NumberToInt(arg)
  1211  			if err != nil {
  1212  				return nil, fmt.Errorf("%%%c format requires integer: %v", c, err)
  1213  			}
  1214  			switch c {
  1215  			case 'd', 'i':
  1216  				buf.WriteString(i.bigint.Text(10))
  1217  			case 'o':
  1218  				buf.WriteString(i.bigint.Text(8))
  1219  			case 'x':
  1220  				buf.WriteString(i.bigint.Text(16))
  1221  			case 'X':
  1222  				buf.WriteString(strings.ToUpper(i.bigint.Text(16)))
  1223  			}
  1224  		case 'e', 'f', 'g', 'E', 'F', 'G':
  1225  			f, ok := AsFloat(arg)
  1226  			if !ok {
  1227  				return nil, fmt.Errorf("%%%c format requires float, not %s", c, arg.Type())
  1228  			}
  1229  			switch c {
  1230  			case 'e':
  1231  				fmt.Fprintf(&buf, "%e", f)
  1232  			case 'f':
  1233  				fmt.Fprintf(&buf, "%f", f)
  1234  			case 'g':
  1235  				fmt.Fprintf(&buf, "%g", f)
  1236  			case 'E':
  1237  				fmt.Fprintf(&buf, "%E", f)
  1238  			case 'F':
  1239  				fmt.Fprintf(&buf, "%F", f)
  1240  			case 'G':
  1241  				fmt.Fprintf(&buf, "%G", f)
  1242  			}
  1243  		case 'c':
  1244  			switch arg := arg.(type) {
  1245  			case Int:
  1246  				// chr(int)
  1247  				r, err := AsInt32(arg)
  1248  				if err != nil || r < 0 || r > unicode.MaxRune {
  1249  					return nil, fmt.Errorf("%%c format requires a valid Unicode code point, got %s", arg)
  1250  				}
  1251  				buf.WriteRune(rune(r))
  1252  			case String:
  1253  				r, size := utf8.DecodeRuneInString(string(arg))
  1254  				if size != len(arg) {
  1255  					return nil, fmt.Errorf("%%c format requires a single-character string")
  1256  				}
  1257  				buf.WriteRune(r)
  1258  			default:
  1259  				return nil, fmt.Errorf("%%c format requires int or single-character string, not %s", arg.Type())
  1260  			}
  1261  		case '%':
  1262  			buf.WriteByte('%')
  1263  		default:
  1264  			return nil, fmt.Errorf("unknown conversion %%%c", c)
  1265  		}
  1266  		format = format[1:]
  1267  		index++
  1268  	}
  1269  
  1270  	if tuple, ok := x.(Tuple); ok && index < len(tuple) {
  1271  		return nil, fmt.Errorf("too many arguments for format string")
  1272  	}
  1273  
  1274  	return String(buf.String()), nil
  1275  }