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 }