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