1package tengo 2 3import ( 4 "bytes" 5 "fmt" 6 "math" 7 "strconv" 8 "strings" 9 "time" 10 11 "github.com/d5/tengo/v2/parser" 12 "github.com/d5/tengo/v2/token" 13) 14 15var ( 16 // TrueValue represents a true value. 17 TrueValue Object = &Bool{value: true} 18 19 // FalseValue represents a false value. 20 FalseValue Object = &Bool{value: false} 21 22 // UndefinedValue represents an undefined value. 23 UndefinedValue Object = &Undefined{} 24) 25 26// Object represents an object in the VM. 27type Object interface { 28 // TypeName should return the name of the type. 29 TypeName() string 30 31 // String should return a string representation of the type's value. 32 String() string 33 34 // BinaryOp should return another object that is the result of a given 35 // binary operator and a right-hand side object. If BinaryOp returns an 36 // error, the VM will treat it as a run-time error. 37 BinaryOp(op token.Token, rhs Object) (Object, error) 38 39 // IsFalsy should return true if the value of the type should be considered 40 // as falsy. 41 IsFalsy() bool 42 43 // Equals should return true if the value of the type should be considered 44 // as equal to the value of another object. 45 Equals(another Object) bool 46 47 // Copy should return a copy of the type (and its value). Copy function 48 // will be used for copy() builtin function which is expected to deep-copy 49 // the values generally. 50 Copy() Object 51 52 // IndexGet should take an index Object and return a result Object or an 53 // error for indexable objects. Indexable is an object that can take an 54 // index and return an object. If error is returned, the runtime will treat 55 // it as a run-time error and ignore returned value. If Object is not 56 // indexable, ErrNotIndexable should be returned as error. If nil is 57 // returned as value, it will be converted to UndefinedToken value by the 58 // runtime. 59 IndexGet(index Object) (value Object, err error) 60 61 // IndexSet should take an index Object and a value Object for index 62 // assignable objects. Index assignable is an object that can take an index 63 // and a value on the left-hand side of the assignment statement. If Object 64 // is not index assignable, ErrNotIndexAssignable should be returned as 65 // error. If an error is returned, it will be treated as a run-time error. 66 IndexSet(index, value Object) error 67 68 // Iterate should return an Iterator for the type. 69 Iterate() Iterator 70 71 // CanIterate should return whether the Object can be Iterated. 72 CanIterate() bool 73 74 // Call should take an arbitrary number of arguments and returns a return 75 // value and/or an error, which the VM will consider as a run-time error. 76 Call(args ...Object) (ret Object, err error) 77 78 // CanCall should return whether the Object can be Called. 79 CanCall() bool 80} 81 82// ObjectImpl represents a default Object Implementation. To defined a new 83// value type, one can embed ObjectImpl in their type declarations to avoid 84// implementing all non-significant methods. TypeName() and String() methods 85// still need to be implemented. 86type ObjectImpl struct { 87} 88 89// TypeName returns the name of the type. 90func (o *ObjectImpl) TypeName() string { 91 panic(ErrNotImplemented) 92} 93 94func (o *ObjectImpl) String() string { 95 panic(ErrNotImplemented) 96} 97 98// BinaryOp returns another object that is the result of a given binary 99// operator and a right-hand side object. 100func (o *ObjectImpl) BinaryOp(_ token.Token, _ Object) (Object, error) { 101 return nil, ErrInvalidOperator 102} 103 104// Copy returns a copy of the type. 105func (o *ObjectImpl) Copy() Object { 106 return nil 107} 108 109// IsFalsy returns true if the value of the type is falsy. 110func (o *ObjectImpl) IsFalsy() bool { 111 return false 112} 113 114// Equals returns true if the value of the type is equal to the value of 115// another object. 116func (o *ObjectImpl) Equals(x Object) bool { 117 return o == x 118} 119 120// IndexGet returns an element at a given index. 121func (o *ObjectImpl) IndexGet(_ Object) (res Object, err error) { 122 return nil, ErrNotIndexable 123} 124 125// IndexSet sets an element at a given index. 126func (o *ObjectImpl) IndexSet(_, _ Object) (err error) { 127 return ErrNotIndexAssignable 128} 129 130// Iterate returns an iterator. 131func (o *ObjectImpl) Iterate() Iterator { 132 return nil 133} 134 135// CanIterate returns whether the Object can be Iterated. 136func (o *ObjectImpl) CanIterate() bool { 137 return false 138} 139 140// Call takes an arbitrary number of arguments and returns a return value 141// and/or an error. 142func (o *ObjectImpl) Call(_ ...Object) (ret Object, err error) { 143 return nil, nil 144} 145 146// CanCall returns whether the Object can be Called. 147func (o *ObjectImpl) CanCall() bool { 148 return false 149} 150 151// Array represents an array of objects. 152type Array struct { 153 ObjectImpl 154 Value []Object 155} 156 157// TypeName returns the name of the type. 158func (o *Array) TypeName() string { 159 return "array" 160} 161 162func (o *Array) String() string { 163 var elements []string 164 for _, e := range o.Value { 165 elements = append(elements, e.String()) 166 } 167 return fmt.Sprintf("[%s]", strings.Join(elements, ", ")) 168} 169 170// BinaryOp returns another object that is the result of a given binary 171// operator and a right-hand side object. 172func (o *Array) BinaryOp(op token.Token, rhs Object) (Object, error) { 173 if rhs, ok := rhs.(*Array); ok { 174 switch op { 175 case token.Add: 176 if len(rhs.Value) == 0 { 177 return o, nil 178 } 179 return &Array{Value: append(o.Value, rhs.Value...)}, nil 180 } 181 } 182 return nil, ErrInvalidOperator 183} 184 185// Copy returns a copy of the type. 186func (o *Array) Copy() Object { 187 var c []Object 188 for _, elem := range o.Value { 189 c = append(c, elem.Copy()) 190 } 191 return &Array{Value: c} 192} 193 194// IsFalsy returns true if the value of the type is falsy. 195func (o *Array) IsFalsy() bool { 196 return len(o.Value) == 0 197} 198 199// Equals returns true if the value of the type is equal to the value of 200// another object. 201func (o *Array) Equals(x Object) bool { 202 var xVal []Object 203 switch x := x.(type) { 204 case *Array: 205 xVal = x.Value 206 case *ImmutableArray: 207 xVal = x.Value 208 default: 209 return false 210 } 211 if len(o.Value) != len(xVal) { 212 return false 213 } 214 for i, e := range o.Value { 215 if !e.Equals(xVal[i]) { 216 return false 217 } 218 } 219 return true 220} 221 222// IndexGet returns an element at a given index. 223func (o *Array) IndexGet(index Object) (res Object, err error) { 224 intIdx, ok := index.(*Int) 225 if !ok { 226 err = ErrInvalidIndexType 227 return 228 } 229 idxVal := int(intIdx.Value) 230 if idxVal < 0 || idxVal >= len(o.Value) { 231 res = UndefinedValue 232 return 233 } 234 res = o.Value[idxVal] 235 return 236} 237 238// IndexSet sets an element at a given index. 239func (o *Array) IndexSet(index, value Object) (err error) { 240 intIdx, ok := ToInt(index) 241 if !ok { 242 err = ErrInvalidIndexType 243 return 244 } 245 if intIdx < 0 || intIdx >= len(o.Value) { 246 err = ErrIndexOutOfBounds 247 return 248 } 249 o.Value[intIdx] = value 250 return nil 251} 252 253// Iterate creates an array iterator. 254func (o *Array) Iterate() Iterator { 255 return &ArrayIterator{ 256 v: o.Value, 257 l: len(o.Value), 258 } 259} 260 261// CanIterate returns whether the Object can be Iterated. 262func (o *Array) CanIterate() bool { 263 return true 264} 265 266// Bool represents a boolean value. 267type Bool struct { 268 ObjectImpl 269 270 // this is intentionally non-public to force using objects.TrueValue and 271 // FalseValue always 272 value bool 273} 274 275func (o *Bool) String() string { 276 if o.value { 277 return "true" 278 } 279 280 return "false" 281} 282 283// TypeName returns the name of the type. 284func (o *Bool) TypeName() string { 285 return "bool" 286} 287 288// Copy returns a copy of the type. 289func (o *Bool) Copy() Object { 290 return o 291} 292 293// IsFalsy returns true if the value of the type is falsy. 294func (o *Bool) IsFalsy() bool { 295 return !o.value 296} 297 298// Equals returns true if the value of the type is equal to the value of 299// another object. 300func (o *Bool) Equals(x Object) bool { 301 return o == x 302} 303 304// GobDecode decodes bool value from input bytes. 305func (o *Bool) GobDecode(b []byte) (err error) { 306 o.value = b[0] == 1 307 return 308} 309 310// GobEncode encodes bool values into bytes. 311func (o *Bool) GobEncode() (b []byte, err error) { 312 if o.value { 313 b = []byte{1} 314 } else { 315 b = []byte{0} 316 } 317 return 318} 319 320// BuiltinFunction represents a builtin function. 321type BuiltinFunction struct { 322 ObjectImpl 323 Name string 324 Value CallableFunc 325} 326 327// TypeName returns the name of the type. 328func (o *BuiltinFunction) TypeName() string { 329 return "builtin-function:" + o.Name 330} 331 332func (o *BuiltinFunction) String() string { 333 return "<builtin-function>" 334} 335 336// Copy returns a copy of the type. 337func (o *BuiltinFunction) Copy() Object { 338 return &BuiltinFunction{Value: o.Value} 339} 340 341// Equals returns true if the value of the type is equal to the value of 342// another object. 343func (o *BuiltinFunction) Equals(_ Object) bool { 344 return false 345} 346 347// Call executes a builtin function. 348func (o *BuiltinFunction) Call(args ...Object) (Object, error) { 349 return o.Value(args...) 350} 351 352// CanCall returns whether the Object can be Called. 353func (o *BuiltinFunction) CanCall() bool { 354 return true 355} 356 357// BuiltinModule is an importable module that's written in Go. 358type BuiltinModule struct { 359 Attrs map[string]Object 360} 361 362// Import returns an immutable map for the module. 363func (m *BuiltinModule) Import(moduleName string) (interface{}, error) { 364 return m.AsImmutableMap(moduleName), nil 365} 366 367// AsImmutableMap converts builtin module into an immutable map. 368func (m *BuiltinModule) AsImmutableMap(moduleName string) *ImmutableMap { 369 attrs := make(map[string]Object, len(m.Attrs)) 370 for k, v := range m.Attrs { 371 attrs[k] = v.Copy() 372 } 373 attrs["__module_name__"] = &String{Value: moduleName} 374 return &ImmutableMap{Value: attrs} 375} 376 377// Bytes represents a byte array. 378type Bytes struct { 379 ObjectImpl 380 Value []byte 381} 382 383func (o *Bytes) String() string { 384 return string(o.Value) 385} 386 387// TypeName returns the name of the type. 388func (o *Bytes) TypeName() string { 389 return "bytes" 390} 391 392// BinaryOp returns another object that is the result of a given binary 393// operator and a right-hand side object. 394func (o *Bytes) BinaryOp(op token.Token, rhs Object) (Object, error) { 395 switch op { 396 case token.Add: 397 switch rhs := rhs.(type) { 398 case *Bytes: 399 if len(o.Value)+len(rhs.Value) > MaxBytesLen { 400 return nil, ErrBytesLimit 401 } 402 return &Bytes{Value: append(o.Value, rhs.Value...)}, nil 403 } 404 } 405 return nil, ErrInvalidOperator 406} 407 408// Copy returns a copy of the type. 409func (o *Bytes) Copy() Object { 410 return &Bytes{Value: append([]byte{}, o.Value...)} 411} 412 413// IsFalsy returns true if the value of the type is falsy. 414func (o *Bytes) IsFalsy() bool { 415 return len(o.Value) == 0 416} 417 418// Equals returns true if the value of the type is equal to the value of 419// another object. 420func (o *Bytes) Equals(x Object) bool { 421 t, ok := x.(*Bytes) 422 if !ok { 423 return false 424 } 425 return bytes.Equal(o.Value, t.Value) 426} 427 428// IndexGet returns an element (as Int) at a given index. 429func (o *Bytes) IndexGet(index Object) (res Object, err error) { 430 intIdx, ok := index.(*Int) 431 if !ok { 432 err = ErrInvalidIndexType 433 return 434 } 435 idxVal := int(intIdx.Value) 436 if idxVal < 0 || idxVal >= len(o.Value) { 437 res = UndefinedValue 438 return 439 } 440 res = &Int{Value: int64(o.Value[idxVal])} 441 return 442} 443 444// Iterate creates a bytes iterator. 445func (o *Bytes) Iterate() Iterator { 446 return &BytesIterator{ 447 v: o.Value, 448 l: len(o.Value), 449 } 450} 451 452// CanIterate returns whether the Object can be Iterated. 453func (o *Bytes) CanIterate() bool { 454 return true 455} 456 457// Char represents a character value. 458type Char struct { 459 ObjectImpl 460 Value rune 461} 462 463func (o *Char) String() string { 464 return string(o.Value) 465} 466 467// TypeName returns the name of the type. 468func (o *Char) TypeName() string { 469 return "char" 470} 471 472// BinaryOp returns another object that is the result of a given binary 473// operator and a right-hand side object. 474func (o *Char) BinaryOp(op token.Token, rhs Object) (Object, error) { 475 switch rhs := rhs.(type) { 476 case *Char: 477 switch op { 478 case token.Add: 479 r := o.Value + rhs.Value 480 if r == o.Value { 481 return o, nil 482 } 483 return &Char{Value: r}, nil 484 case token.Sub: 485 r := o.Value - rhs.Value 486 if r == o.Value { 487 return o, nil 488 } 489 return &Char{Value: r}, nil 490 case token.Less: 491 if o.Value < rhs.Value { 492 return TrueValue, nil 493 } 494 return FalseValue, nil 495 case token.Greater: 496 if o.Value > rhs.Value { 497 return TrueValue, nil 498 } 499 return FalseValue, nil 500 case token.LessEq: 501 if o.Value <= rhs.Value { 502 return TrueValue, nil 503 } 504 return FalseValue, nil 505 case token.GreaterEq: 506 if o.Value >= rhs.Value { 507 return TrueValue, nil 508 } 509 return FalseValue, nil 510 } 511 case *Int: 512 switch op { 513 case token.Add: 514 r := o.Value + rune(rhs.Value) 515 if r == o.Value { 516 return o, nil 517 } 518 return &Char{Value: r}, nil 519 case token.Sub: 520 r := o.Value - rune(rhs.Value) 521 if r == o.Value { 522 return o, nil 523 } 524 return &Char{Value: r}, nil 525 case token.Less: 526 if int64(o.Value) < rhs.Value { 527 return TrueValue, nil 528 } 529 return FalseValue, nil 530 case token.Greater: 531 if int64(o.Value) > rhs.Value { 532 return TrueValue, nil 533 } 534 return FalseValue, nil 535 case token.LessEq: 536 if int64(o.Value) <= rhs.Value { 537 return TrueValue, nil 538 } 539 return FalseValue, nil 540 case token.GreaterEq: 541 if int64(o.Value) >= rhs.Value { 542 return TrueValue, nil 543 } 544 return FalseValue, nil 545 } 546 } 547 return nil, ErrInvalidOperator 548} 549 550// Copy returns a copy of the type. 551func (o *Char) Copy() Object { 552 return &Char{Value: o.Value} 553} 554 555// IsFalsy returns true if the value of the type is falsy. 556func (o *Char) IsFalsy() bool { 557 return o.Value == 0 558} 559 560// Equals returns true if the value of the type is equal to the value of 561// another object. 562func (o *Char) Equals(x Object) bool { 563 t, ok := x.(*Char) 564 if !ok { 565 return false 566 } 567 return o.Value == t.Value 568} 569 570// CompiledFunction represents a compiled function. 571type CompiledFunction struct { 572 ObjectImpl 573 Instructions []byte 574 NumLocals int // number of local variables (including function parameters) 575 NumParameters int 576 VarArgs bool 577 SourceMap map[int]parser.Pos 578 Free []*ObjectPtr 579} 580 581// TypeName returns the name of the type. 582func (o *CompiledFunction) TypeName() string { 583 return "compiled-function" 584} 585 586func (o *CompiledFunction) String() string { 587 return "<compiled-function>" 588} 589 590// Copy returns a copy of the type. 591func (o *CompiledFunction) Copy() Object { 592 return &CompiledFunction{ 593 Instructions: append([]byte{}, o.Instructions...), 594 NumLocals: o.NumLocals, 595 NumParameters: o.NumParameters, 596 VarArgs: o.VarArgs, 597 Free: append([]*ObjectPtr{}, o.Free...), // DO NOT Copy() of elements; these are variable pointers 598 } 599} 600 601// Equals returns true if the value of the type is equal to the value of 602// another object. 603func (o *CompiledFunction) Equals(_ Object) bool { 604 return false 605} 606 607// SourcePos returns the source position of the instruction at ip. 608func (o *CompiledFunction) SourcePos(ip int) parser.Pos { 609 for ip >= 0 { 610 if p, ok := o.SourceMap[ip]; ok { 611 return p 612 } 613 ip-- 614 } 615 return parser.NoPos 616} 617 618// CanCall returns whether the Object can be Called. 619func (o *CompiledFunction) CanCall() bool { 620 return true 621} 622 623// Error represents an error value. 624type Error struct { 625 ObjectImpl 626 Value Object 627} 628 629// TypeName returns the name of the type. 630func (o *Error) TypeName() string { 631 return "error" 632} 633 634func (o *Error) String() string { 635 if o.Value != nil { 636 return fmt.Sprintf("error: %s", o.Value.String()) 637 } 638 return "error" 639} 640 641// IsFalsy returns true if the value of the type is falsy. 642func (o *Error) IsFalsy() bool { 643 return true // error is always false. 644} 645 646// Copy returns a copy of the type. 647func (o *Error) Copy() Object { 648 return &Error{Value: o.Value.Copy()} 649} 650 651// Equals returns true if the value of the type is equal to the value of 652// another object. 653func (o *Error) Equals(x Object) bool { 654 return o == x // pointer equality 655} 656 657// IndexGet returns an element at a given index. 658func (o *Error) IndexGet(index Object) (res Object, err error) { 659 if strIdx, _ := ToString(index); strIdx != "value" { 660 err = ErrInvalidIndexOnError 661 return 662 } 663 res = o.Value 664 return 665} 666 667// Float represents a floating point number value. 668type Float struct { 669 ObjectImpl 670 Value float64 671} 672 673func (o *Float) String() string { 674 return strconv.FormatFloat(o.Value, 'f', -1, 64) 675} 676 677// TypeName returns the name of the type. 678func (o *Float) TypeName() string { 679 return "float" 680} 681 682// BinaryOp returns another object that is the result of a given binary 683// operator and a right-hand side object. 684func (o *Float) BinaryOp(op token.Token, rhs Object) (Object, error) { 685 switch rhs := rhs.(type) { 686 case *Float: 687 switch op { 688 case token.Add: 689 r := o.Value + rhs.Value 690 if r == o.Value { 691 return o, nil 692 } 693 return &Float{Value: r}, nil 694 case token.Sub: 695 r := o.Value - rhs.Value 696 if r == o.Value { 697 return o, nil 698 } 699 return &Float{Value: r}, nil 700 case token.Mul: 701 r := o.Value * rhs.Value 702 if r == o.Value { 703 return o, nil 704 } 705 return &Float{Value: r}, nil 706 case token.Quo: 707 r := o.Value / rhs.Value 708 if r == o.Value { 709 return o, nil 710 } 711 return &Float{Value: r}, nil 712 case token.Less: 713 if o.Value < rhs.Value { 714 return TrueValue, nil 715 } 716 return FalseValue, nil 717 case token.Greater: 718 if o.Value > rhs.Value { 719 return TrueValue, nil 720 } 721 return FalseValue, nil 722 case token.LessEq: 723 if o.Value <= rhs.Value { 724 return TrueValue, nil 725 } 726 return FalseValue, nil 727 case token.GreaterEq: 728 if o.Value >= rhs.Value { 729 return TrueValue, nil 730 } 731 return FalseValue, nil 732 } 733 case *Int: 734 switch op { 735 case token.Add: 736 r := o.Value + float64(rhs.Value) 737 if r == o.Value { 738 return o, nil 739 } 740 return &Float{Value: r}, nil 741 case token.Sub: 742 r := o.Value - float64(rhs.Value) 743 if r == o.Value { 744 return o, nil 745 } 746 return &Float{Value: r}, nil 747 case token.Mul: 748 r := o.Value * float64(rhs.Value) 749 if r == o.Value { 750 return o, nil 751 } 752 return &Float{Value: r}, nil 753 case token.Quo: 754 r := o.Value / float64(rhs.Value) 755 if r == o.Value { 756 return o, nil 757 } 758 return &Float{Value: r}, nil 759 case token.Less: 760 if o.Value < float64(rhs.Value) { 761 return TrueValue, nil 762 } 763 return FalseValue, nil 764 case token.Greater: 765 if o.Value > float64(rhs.Value) { 766 return TrueValue, nil 767 } 768 return FalseValue, nil 769 case token.LessEq: 770 if o.Value <= float64(rhs.Value) { 771 return TrueValue, nil 772 } 773 return FalseValue, nil 774 case token.GreaterEq: 775 if o.Value >= float64(rhs.Value) { 776 return TrueValue, nil 777 } 778 return FalseValue, nil 779 } 780 } 781 return nil, ErrInvalidOperator 782} 783 784// Copy returns a copy of the type. 785func (o *Float) Copy() Object { 786 return &Float{Value: o.Value} 787} 788 789// IsFalsy returns true if the value of the type is falsy. 790func (o *Float) IsFalsy() bool { 791 return math.IsNaN(o.Value) 792} 793 794// Equals returns true if the value of the type is equal to the value of 795// another object. 796func (o *Float) Equals(x Object) bool { 797 t, ok := x.(*Float) 798 if !ok { 799 return false 800 } 801 return o.Value == t.Value 802} 803 804// ImmutableArray represents an immutable array of objects. 805type ImmutableArray struct { 806 ObjectImpl 807 Value []Object 808} 809 810// TypeName returns the name of the type. 811func (o *ImmutableArray) TypeName() string { 812 return "immutable-array" 813} 814 815func (o *ImmutableArray) String() string { 816 var elements []string 817 for _, e := range o.Value { 818 elements = append(elements, e.String()) 819 } 820 return fmt.Sprintf("[%s]", strings.Join(elements, ", ")) 821} 822 823// BinaryOp returns another object that is the result of a given binary 824// operator and a right-hand side object. 825func (o *ImmutableArray) BinaryOp(op token.Token, rhs Object) (Object, error) { 826 if rhs, ok := rhs.(*ImmutableArray); ok { 827 switch op { 828 case token.Add: 829 return &Array{Value: append(o.Value, rhs.Value...)}, nil 830 } 831 } 832 return nil, ErrInvalidOperator 833} 834 835// Copy returns a copy of the type. 836func (o *ImmutableArray) Copy() Object { 837 var c []Object 838 for _, elem := range o.Value { 839 c = append(c, elem.Copy()) 840 } 841 return &Array{Value: c} 842} 843 844// IsFalsy returns true if the value of the type is falsy. 845func (o *ImmutableArray) IsFalsy() bool { 846 return len(o.Value) == 0 847} 848 849// Equals returns true if the value of the type is equal to the value of 850// another object. 851func (o *ImmutableArray) Equals(x Object) bool { 852 var xVal []Object 853 switch x := x.(type) { 854 case *Array: 855 xVal = x.Value 856 case *ImmutableArray: 857 xVal = x.Value 858 default: 859 return false 860 } 861 if len(o.Value) != len(xVal) { 862 return false 863 } 864 for i, e := range o.Value { 865 if !e.Equals(xVal[i]) { 866 return false 867 } 868 } 869 return true 870} 871 872// IndexGet returns an element at a given index. 873func (o *ImmutableArray) IndexGet(index Object) (res Object, err error) { 874 intIdx, ok := index.(*Int) 875 if !ok { 876 err = ErrInvalidIndexType 877 return 878 } 879 idxVal := int(intIdx.Value) 880 if idxVal < 0 || idxVal >= len(o.Value) { 881 res = UndefinedValue 882 return 883 } 884 res = o.Value[idxVal] 885 return 886} 887 888// Iterate creates an array iterator. 889func (o *ImmutableArray) Iterate() Iterator { 890 return &ArrayIterator{ 891 v: o.Value, 892 l: len(o.Value), 893 } 894} 895 896// CanIterate returns whether the Object can be Iterated. 897func (o *ImmutableArray) CanIterate() bool { 898 return true 899} 900 901// ImmutableMap represents an immutable map object. 902type ImmutableMap struct { 903 ObjectImpl 904 Value map[string]Object 905} 906 907// TypeName returns the name of the type. 908func (o *ImmutableMap) TypeName() string { 909 return "immutable-map" 910} 911 912func (o *ImmutableMap) String() string { 913 var pairs []string 914 for k, v := range o.Value { 915 pairs = append(pairs, fmt.Sprintf("%s: %s", k, v.String())) 916 } 917 return fmt.Sprintf("{%s}", strings.Join(pairs, ", ")) 918} 919 920// Copy returns a copy of the type. 921func (o *ImmutableMap) Copy() Object { 922 c := make(map[string]Object) 923 for k, v := range o.Value { 924 c[k] = v.Copy() 925 } 926 return &Map{Value: c} 927} 928 929// IsFalsy returns true if the value of the type is falsy. 930func (o *ImmutableMap) IsFalsy() bool { 931 return len(o.Value) == 0 932} 933 934// IndexGet returns the value for the given key. 935func (o *ImmutableMap) IndexGet(index Object) (res Object, err error) { 936 strIdx, ok := ToString(index) 937 if !ok { 938 err = ErrInvalidIndexType 939 return 940 } 941 res, ok = o.Value[strIdx] 942 if !ok { 943 res = UndefinedValue 944 } 945 return 946} 947 948// Equals returns true if the value of the type is equal to the value of 949// another object. 950func (o *ImmutableMap) Equals(x Object) bool { 951 var xVal map[string]Object 952 switch x := x.(type) { 953 case *Map: 954 xVal = x.Value 955 case *ImmutableMap: 956 xVal = x.Value 957 default: 958 return false 959 } 960 if len(o.Value) != len(xVal) { 961 return false 962 } 963 for k, v := range o.Value { 964 tv := xVal[k] 965 if !v.Equals(tv) { 966 return false 967 } 968 } 969 return true 970} 971 972// Iterate creates an immutable map iterator. 973func (o *ImmutableMap) Iterate() Iterator { 974 var keys []string 975 for k := range o.Value { 976 keys = append(keys, k) 977 } 978 return &MapIterator{ 979 v: o.Value, 980 k: keys, 981 l: len(keys), 982 } 983} 984 985// CanIterate returns whether the Object can be Iterated. 986func (o *ImmutableMap) CanIterate() bool { 987 return true 988} 989 990// Int represents an integer value. 991type Int struct { 992 ObjectImpl 993 Value int64 994} 995 996func (o *Int) String() string { 997 return strconv.FormatInt(o.Value, 10) 998} 999 1000// TypeName returns the name of the type. 1001func (o *Int) TypeName() string { 1002 return "int" 1003} 1004 1005// BinaryOp returns another object that is the result of a given binary 1006// operator and a right-hand side object. 1007func (o *Int) BinaryOp(op token.Token, rhs Object) (Object, error) { 1008 switch rhs := rhs.(type) { 1009 case *Int: 1010 switch op { 1011 case token.Add: 1012 r := o.Value + rhs.Value 1013 if r == o.Value { 1014 return o, nil 1015 } 1016 return &Int{Value: r}, nil 1017 case token.Sub: 1018 r := o.Value - rhs.Value 1019 if r == o.Value { 1020 return o, nil 1021 } 1022 return &Int{Value: r}, nil 1023 case token.Mul: 1024 r := o.Value * rhs.Value 1025 if r == o.Value { 1026 return o, nil 1027 } 1028 return &Int{Value: r}, nil 1029 case token.Quo: 1030 r := o.Value / rhs.Value 1031 if r == o.Value { 1032 return o, nil 1033 } 1034 return &Int{Value: r}, nil 1035 case token.Rem: 1036 r := o.Value % rhs.Value 1037 if r == o.Value { 1038 return o, nil 1039 } 1040 return &Int{Value: r}, nil 1041 case token.And: 1042 r := o.Value & rhs.Value 1043 if r == o.Value { 1044 return o, nil 1045 } 1046 return &Int{Value: r}, nil 1047 case token.Or: 1048 r := o.Value | rhs.Value 1049 if r == o.Value { 1050 return o, nil 1051 } 1052 return &Int{Value: r}, nil 1053 case token.Xor: 1054 r := o.Value ^ rhs.Value 1055 if r == o.Value { 1056 return o, nil 1057 } 1058 return &Int{Value: r}, nil 1059 case token.AndNot: 1060 r := o.Value &^ rhs.Value 1061 if r == o.Value { 1062 return o, nil 1063 } 1064 return &Int{Value: r}, nil 1065 case token.Shl: 1066 r := o.Value << uint64(rhs.Value) 1067 if r == o.Value { 1068 return o, nil 1069 } 1070 return &Int{Value: r}, nil 1071 case token.Shr: 1072 r := o.Value >> uint64(rhs.Value) 1073 if r == o.Value { 1074 return o, nil 1075 } 1076 return &Int{Value: r}, nil 1077 case token.Less: 1078 if o.Value < rhs.Value { 1079 return TrueValue, nil 1080 } 1081 return FalseValue, nil 1082 case token.Greater: 1083 if o.Value > rhs.Value { 1084 return TrueValue, nil 1085 } 1086 return FalseValue, nil 1087 case token.LessEq: 1088 if o.Value <= rhs.Value { 1089 return TrueValue, nil 1090 } 1091 return FalseValue, nil 1092 case token.GreaterEq: 1093 if o.Value >= rhs.Value { 1094 return TrueValue, nil 1095 } 1096 return FalseValue, nil 1097 } 1098 case *Float: 1099 switch op { 1100 case token.Add: 1101 return &Float{Value: float64(o.Value) + rhs.Value}, nil 1102 case token.Sub: 1103 return &Float{Value: float64(o.Value) - rhs.Value}, nil 1104 case token.Mul: 1105 return &Float{Value: float64(o.Value) * rhs.Value}, nil 1106 case token.Quo: 1107 return &Float{Value: float64(o.Value) / rhs.Value}, nil 1108 case token.Less: 1109 if float64(o.Value) < rhs.Value { 1110 return TrueValue, nil 1111 } 1112 return FalseValue, nil 1113 case token.Greater: 1114 if float64(o.Value) > rhs.Value { 1115 return TrueValue, nil 1116 } 1117 return FalseValue, nil 1118 case token.LessEq: 1119 if float64(o.Value) <= rhs.Value { 1120 return TrueValue, nil 1121 } 1122 return FalseValue, nil 1123 case token.GreaterEq: 1124 if float64(o.Value) >= rhs.Value { 1125 return TrueValue, nil 1126 } 1127 return FalseValue, nil 1128 } 1129 case *Char: 1130 switch op { 1131 case token.Add: 1132 return &Char{Value: rune(o.Value) + rhs.Value}, nil 1133 case token.Sub: 1134 return &Char{Value: rune(o.Value) - rhs.Value}, nil 1135 case token.Less: 1136 if o.Value < int64(rhs.Value) { 1137 return TrueValue, nil 1138 } 1139 return FalseValue, nil 1140 case token.Greater: 1141 if o.Value > int64(rhs.Value) { 1142 return TrueValue, nil 1143 } 1144 return FalseValue, nil 1145 case token.LessEq: 1146 if o.Value <= int64(rhs.Value) { 1147 return TrueValue, nil 1148 } 1149 return FalseValue, nil 1150 case token.GreaterEq: 1151 if o.Value >= int64(rhs.Value) { 1152 return TrueValue, nil 1153 } 1154 return FalseValue, nil 1155 } 1156 } 1157 return nil, ErrInvalidOperator 1158} 1159 1160// Copy returns a copy of the type. 1161func (o *Int) Copy() Object { 1162 return &Int{Value: o.Value} 1163} 1164 1165// IsFalsy returns true if the value of the type is falsy. 1166func (o *Int) IsFalsy() bool { 1167 return o.Value == 0 1168} 1169 1170// Equals returns true if the value of the type is equal to the value of 1171// another object. 1172func (o *Int) Equals(x Object) bool { 1173 t, ok := x.(*Int) 1174 if !ok { 1175 return false 1176 } 1177 return o.Value == t.Value 1178} 1179 1180// Map represents a map of objects. 1181type Map struct { 1182 ObjectImpl 1183 Value map[string]Object 1184} 1185 1186// TypeName returns the name of the type. 1187func (o *Map) TypeName() string { 1188 return "map" 1189} 1190 1191func (o *Map) String() string { 1192 var pairs []string 1193 for k, v := range o.Value { 1194 pairs = append(pairs, fmt.Sprintf("%s: %s", k, v.String())) 1195 } 1196 return fmt.Sprintf("{%s}", strings.Join(pairs, ", ")) 1197} 1198 1199// Copy returns a copy of the type. 1200func (o *Map) Copy() Object { 1201 c := make(map[string]Object) 1202 for k, v := range o.Value { 1203 c[k] = v.Copy() 1204 } 1205 return &Map{Value: c} 1206} 1207 1208// IsFalsy returns true if the value of the type is falsy. 1209func (o *Map) IsFalsy() bool { 1210 return len(o.Value) == 0 1211} 1212 1213// Equals returns true if the value of the type is equal to the value of 1214// another object. 1215func (o *Map) Equals(x Object) bool { 1216 var xVal map[string]Object 1217 switch x := x.(type) { 1218 case *Map: 1219 xVal = x.Value 1220 case *ImmutableMap: 1221 xVal = x.Value 1222 default: 1223 return false 1224 } 1225 if len(o.Value) != len(xVal) { 1226 return false 1227 } 1228 for k, v := range o.Value { 1229 tv := xVal[k] 1230 if !v.Equals(tv) { 1231 return false 1232 } 1233 } 1234 return true 1235} 1236 1237// IndexGet returns the value for the given key. 1238func (o *Map) IndexGet(index Object) (res Object, err error) { 1239 strIdx, ok := ToString(index) 1240 if !ok { 1241 err = ErrInvalidIndexType 1242 return 1243 } 1244 res, ok = o.Value[strIdx] 1245 if !ok { 1246 res = UndefinedValue 1247 } 1248 return 1249} 1250 1251// IndexSet sets the value for the given key. 1252func (o *Map) IndexSet(index, value Object) (err error) { 1253 strIdx, ok := ToString(index) 1254 if !ok { 1255 err = ErrInvalidIndexType 1256 return 1257 } 1258 o.Value[strIdx] = value 1259 return nil 1260} 1261 1262// Iterate creates a map iterator. 1263func (o *Map) Iterate() Iterator { 1264 var keys []string 1265 for k := range o.Value { 1266 keys = append(keys, k) 1267 } 1268 return &MapIterator{ 1269 v: o.Value, 1270 k: keys, 1271 l: len(keys), 1272 } 1273} 1274 1275// CanIterate returns whether the Object can be Iterated. 1276func (o *Map) CanIterate() bool { 1277 return true 1278} 1279 1280// ObjectPtr represents a free variable. 1281type ObjectPtr struct { 1282 ObjectImpl 1283 Value *Object 1284} 1285 1286func (o *ObjectPtr) String() string { 1287 return "free-var" 1288} 1289 1290// TypeName returns the name of the type. 1291func (o *ObjectPtr) TypeName() string { 1292 return "<free-var>" 1293} 1294 1295// Copy returns a copy of the type. 1296func (o *ObjectPtr) Copy() Object { 1297 return o 1298} 1299 1300// IsFalsy returns true if the value of the type is falsy. 1301func (o *ObjectPtr) IsFalsy() bool { 1302 return o.Value == nil 1303} 1304 1305// Equals returns true if the value of the type is equal to the value of 1306// another object. 1307func (o *ObjectPtr) Equals(x Object) bool { 1308 return o == x 1309} 1310 1311// String represents a string value. 1312type String struct { 1313 ObjectImpl 1314 Value string 1315 runeStr []rune 1316} 1317 1318// TypeName returns the name of the type. 1319func (o *String) TypeName() string { 1320 return "string" 1321} 1322 1323func (o *String) String() string { 1324 return strconv.Quote(o.Value) 1325} 1326 1327// BinaryOp returns another object that is the result of a given binary 1328// operator and a right-hand side object. 1329func (o *String) BinaryOp(op token.Token, rhs Object) (Object, error) { 1330 switch op { 1331 case token.Add: 1332 switch rhs := rhs.(type) { 1333 case *String: 1334 if len(o.Value)+len(rhs.Value) > MaxStringLen { 1335 return nil, ErrStringLimit 1336 } 1337 return &String{Value: o.Value + rhs.Value}, nil 1338 default: 1339 rhsStr := rhs.String() 1340 if len(o.Value)+len(rhsStr) > MaxStringLen { 1341 return nil, ErrStringLimit 1342 } 1343 return &String{Value: o.Value + rhsStr}, nil 1344 } 1345 case token.Less: 1346 switch rhs := rhs.(type) { 1347 case *String: 1348 if o.Value < rhs.Value { 1349 return TrueValue, nil 1350 } 1351 return FalseValue, nil 1352 } 1353 case token.LessEq: 1354 switch rhs := rhs.(type) { 1355 case *String: 1356 if o.Value <= rhs.Value { 1357 return TrueValue, nil 1358 } 1359 return FalseValue, nil 1360 } 1361 case token.Greater: 1362 switch rhs := rhs.(type) { 1363 case *String: 1364 if o.Value > rhs.Value { 1365 return TrueValue, nil 1366 } 1367 return FalseValue, nil 1368 } 1369 case token.GreaterEq: 1370 switch rhs := rhs.(type) { 1371 case *String: 1372 if o.Value >= rhs.Value { 1373 return TrueValue, nil 1374 } 1375 return FalseValue, nil 1376 } 1377 } 1378 return nil, ErrInvalidOperator 1379} 1380 1381// IsFalsy returns true if the value of the type is falsy. 1382func (o *String) IsFalsy() bool { 1383 return len(o.Value) == 0 1384} 1385 1386// Copy returns a copy of the type. 1387func (o *String) Copy() Object { 1388 return &String{Value: o.Value} 1389} 1390 1391// Equals returns true if the value of the type is equal to the value of 1392// another object. 1393func (o *String) Equals(x Object) bool { 1394 t, ok := x.(*String) 1395 if !ok { 1396 return false 1397 } 1398 return o.Value == t.Value 1399} 1400 1401// IndexGet returns a character at a given index. 1402func (o *String) IndexGet(index Object) (res Object, err error) { 1403 intIdx, ok := index.(*Int) 1404 if !ok { 1405 err = ErrInvalidIndexType 1406 return 1407 } 1408 idxVal := int(intIdx.Value) 1409 if o.runeStr == nil { 1410 o.runeStr = []rune(o.Value) 1411 } 1412 if idxVal < 0 || idxVal >= len(o.runeStr) { 1413 res = UndefinedValue 1414 return 1415 } 1416 res = &Char{Value: o.runeStr[idxVal]} 1417 return 1418} 1419 1420// Iterate creates a string iterator. 1421func (o *String) Iterate() Iterator { 1422 if o.runeStr == nil { 1423 o.runeStr = []rune(o.Value) 1424 } 1425 return &StringIterator{ 1426 v: o.runeStr, 1427 l: len(o.runeStr), 1428 } 1429} 1430 1431// CanIterate returns whether the Object can be Iterated. 1432func (o *String) CanIterate() bool { 1433 return true 1434} 1435 1436// Time represents a time value. 1437type Time struct { 1438 ObjectImpl 1439 Value time.Time 1440} 1441 1442func (o *Time) String() string { 1443 return o.Value.String() 1444} 1445 1446// TypeName returns the name of the type. 1447func (o *Time) TypeName() string { 1448 return "time" 1449} 1450 1451// BinaryOp returns another object that is the result of a given binary 1452// operator and a right-hand side object. 1453func (o *Time) BinaryOp(op token.Token, rhs Object) (Object, error) { 1454 switch rhs := rhs.(type) { 1455 case *Int: 1456 switch op { 1457 case token.Add: // time + int => time 1458 if rhs.Value == 0 { 1459 return o, nil 1460 } 1461 return &Time{Value: o.Value.Add(time.Duration(rhs.Value))}, nil 1462 case token.Sub: // time - int => time 1463 if rhs.Value == 0 { 1464 return o, nil 1465 } 1466 return &Time{Value: o.Value.Add(time.Duration(-rhs.Value))}, nil 1467 } 1468 case *Time: 1469 switch op { 1470 case token.Sub: // time - time => int (duration) 1471 return &Int{Value: int64(o.Value.Sub(rhs.Value))}, nil 1472 case token.Less: // time < time => bool 1473 if o.Value.Before(rhs.Value) { 1474 return TrueValue, nil 1475 } 1476 return FalseValue, nil 1477 case token.Greater: 1478 if o.Value.After(rhs.Value) { 1479 return TrueValue, nil 1480 } 1481 return FalseValue, nil 1482 case token.LessEq: 1483 if o.Value.Equal(rhs.Value) || o.Value.Before(rhs.Value) { 1484 return TrueValue, nil 1485 } 1486 return FalseValue, nil 1487 case token.GreaterEq: 1488 if o.Value.Equal(rhs.Value) || o.Value.After(rhs.Value) { 1489 return TrueValue, nil 1490 } 1491 return FalseValue, nil 1492 } 1493 } 1494 return nil, ErrInvalidOperator 1495} 1496 1497// Copy returns a copy of the type. 1498func (o *Time) Copy() Object { 1499 return &Time{Value: o.Value} 1500} 1501 1502// IsFalsy returns true if the value of the type is falsy. 1503func (o *Time) IsFalsy() bool { 1504 return o.Value.IsZero() 1505} 1506 1507// Equals returns true if the value of the type is equal to the value of 1508// another object. 1509func (o *Time) Equals(x Object) bool { 1510 t, ok := x.(*Time) 1511 if !ok { 1512 return false 1513 } 1514 return o.Value.Equal(t.Value) 1515} 1516 1517// Undefined represents an undefined value. 1518type Undefined struct { 1519 ObjectImpl 1520} 1521 1522// TypeName returns the name of the type. 1523func (o *Undefined) TypeName() string { 1524 return "undefined" 1525} 1526 1527func (o *Undefined) String() string { 1528 return "<undefined>" 1529} 1530 1531// Copy returns a copy of the type. 1532func (o *Undefined) Copy() Object { 1533 return o 1534} 1535 1536// IsFalsy returns true if the value of the type is falsy. 1537func (o *Undefined) IsFalsy() bool { 1538 return true 1539} 1540 1541// Equals returns true if the value of the type is equal to the value of 1542// another object. 1543func (o *Undefined) Equals(x Object) bool { 1544 return o == x 1545} 1546 1547// IndexGet returns an element at a given index. 1548func (o *Undefined) IndexGet(_ Object) (Object, error) { 1549 return UndefinedValue, nil 1550} 1551 1552// Iterate creates a map iterator. 1553func (o *Undefined) Iterate() Iterator { 1554 return o 1555} 1556 1557// CanIterate returns whether the Object can be Iterated. 1558func (o *Undefined) CanIterate() bool { 1559 return true 1560} 1561 1562// Next returns true if there are more elements to iterate. 1563func (o *Undefined) Next() bool { 1564 return false 1565} 1566 1567// Key returns the key or index value of the current element. 1568func (o *Undefined) Key() Object { 1569 return o 1570} 1571 1572// Value returns the value of the current element. 1573func (o *Undefined) Value() Object { 1574 return o 1575} 1576 1577// UserFunction represents a user function. 1578type UserFunction struct { 1579 ObjectImpl 1580 Name string 1581 Value CallableFunc 1582 EncodingID string 1583} 1584 1585// TypeName returns the name of the type. 1586func (o *UserFunction) TypeName() string { 1587 return "user-function:" + o.Name 1588} 1589 1590func (o *UserFunction) String() string { 1591 return "<user-function>" 1592} 1593 1594// Copy returns a copy of the type. 1595func (o *UserFunction) Copy() Object { 1596 return &UserFunction{Value: o.Value} 1597} 1598 1599// Equals returns true if the value of the type is equal to the value of 1600// another object. 1601func (o *UserFunction) Equals(_ Object) bool { 1602 return false 1603} 1604 1605// Call invokes a user function. 1606func (o *UserFunction) Call(args ...Object) (Object, error) { 1607 return o.Value(args...) 1608} 1609 1610// CanCall returns whether the Object can be Called. 1611func (o *UserFunction) CanCall() bool { 1612 return true 1613} 1614