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