• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS of ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16package std.core;
17
18// Class Value
19
20native function ValueAPIGetFieldBoolean(obj: Object, i: long): boolean
21
22native function ValueAPIGetFieldByte(obj: Object, i: long): byte
23
24native function ValueAPIGetFieldShort(obj: Object, i: long): short
25
26native function ValueAPIGetFieldChar(obj: Object, i: long): char
27
28native function ValueAPIGetFieldInt(obj: Object, i: long): int
29
30native function ValueAPIGetFieldFloat(obj: Object, i: long): float
31
32native function ValueAPIGetFieldDouble(obj: Object, i: long): double
33
34native function ValueAPIGetFieldLong(obj: Object, i: long): long
35
36native function ValueAPIGetFieldObject(obj: Object, i: long): Object
37
38
39native function ValueAPIGetFieldByNameBoolean(obj: Object, name: String): boolean
40
41native function ValueAPIGetFieldByNameByte(obj: Object, name: String): byte
42
43native function ValueAPIGetFieldByNameShort(obj: Object, name: String): short
44
45native function ValueAPIGetFieldByNameChar(obj: Object, name: String): char
46
47native function ValueAPIGetFieldByNameInt(obj: Object, name: String): int
48
49native function ValueAPIGetFieldByNameFloat(obj: Object, name: String): float
50
51native function ValueAPIGetFieldByNameDouble(obj: Object, name: String): double
52
53native function ValueAPIGetFieldByNameLong(obj: Object, name: String): long
54
55native function ValueAPIGetFieldByNameObject(obj: Object, name: String): Object
56
57
58native function ValueAPISetFieldBoolean(obj: Object, i: long, val: boolean): void
59
60native function ValueAPISetFieldByte(obj: Object, i: long, val: byte): void
61
62native function ValueAPISetFieldShort(obj: Object, i: long, val: short): void
63
64native function ValueAPISetFieldChar(obj: Object, i: long, val: char): void
65
66native function ValueAPISetFieldInt(obj: Object, i: long, val: int): void
67
68native function ValueAPISetFieldFloat(obj: Object, i: long, val: float): void
69
70native function ValueAPISetFieldDouble(obj: Object, i: long, val: double): void
71
72native function ValueAPISetFieldLong(obj: Object, i: long, val: long): void
73
74native function ValueAPISetFieldObject(obj: Object, i: long, val: Object): void
75
76
77native function ValueAPISetFieldByNameBoolean(obj: Object, name: String, val: boolean): void
78
79native function ValueAPISetFieldByNameByte(obj: Object, name: String, val: byte): void
80
81native function ValueAPISetFieldByNameShort(obj: Object, name: String, val: short): void
82
83native function ValueAPISetFieldByNameChar(obj: Object, name: String, val: char): void
84
85native function ValueAPISetFieldByNameInt(obj: Object, name: String, val: int): void
86
87native function ValueAPISetFieldByNameFloat(obj: Object, name: String, val: float): void
88
89native function ValueAPISetFieldByNameDouble(obj: Object, name: String, val: double): void
90
91native function ValueAPISetFieldByNameLong(obj: Object, name: String, val: long): void
92
93native function ValueAPISetFieldByNameObject(obj: Object, name: String, val: Object): void
94
95// Array Value
96native function ValueAPIGetArrayLength(obj: Object): long
97
98native function ValueAPISetElementBoolean(obj: Object, i: long, val: boolean): void
99
100native function ValueAPISetElementByte(obj: Object, i: long, val: byte): void
101
102native function ValueAPISetElementShort(obj: Object, i: long, val: short): void
103
104native function ValueAPISetElementChar(obj: Object, i: long, val: char): void
105
106native function ValueAPISetElementInt(obj: Object, i: long, val: int): void
107
108native function ValueAPISetElementFloat(obj: Object, i: long, val: float): void
109
110native function ValueAPISetElementDouble(obj: Object, i: long, val: double): void
111
112native function ValueAPISetElementLong(obj: Object, i: long, val: long): void
113
114native function ValueAPISetElementObject(obj: Object, i: long, val: Object): void
115
116
117native function ValueAPIGetElementBoolean(obj: Object, i: long): boolean
118
119native function ValueAPIGetElementByte(obj: Object, i: long): byte
120
121native function ValueAPIGetElementShort(obj: Object, i: long): short
122
123native function ValueAPIGetElementChar(obj: Object, i: long): char
124
125native function ValueAPIGetElementInt(obj: Object, i: long): int
126
127native function ValueAPIGetElementFloat(obj: Object, i: long): float
128
129native function ValueAPIGetElementDouble(obj: Object, i: long): double
130
131native function ValueAPIGetElementLong(obj: Object, i: long): long
132
133native function ValueAPIGetElementObject(obj: Object, i: long): Object
134
135/**
136 * Represents abstract value
137 */
138export abstract class Value extends Object {
139    public static of(v: boolean): Value {
140        return new BooleanValue(BooleanType.VAL, v)
141    }
142
143    public static of(v: char): Value {
144        return new CharValue(CharType.VAL, v)
145    }
146
147    public static of(v: byte): Value {
148        return new ByteValue(ByteType.VAL, v)
149    }
150
151    public static of(v: short): Value {
152        return new ShortValue(ShortType.VAL, v)
153    }
154
155    public static of(v: int): Value {
156        return new IntValue(IntType.VAL, v)
157    }
158
159    public static of(v: long): Value {
160        return new LongValue(LongType.VAL, v)
161    }
162
163    public static of(v: float): Value {
164        return new FloatValue(FloatType.VAL, v)
165    }
166
167    public static of(v: double): Value {
168        return new DoubleValue(DoubleType.VAL, v)
169    }
170
171    // -----
172
173    public static of(v: Boolean): Value {
174        return new BooleanValue(BooleanType.REF, v)
175    }
176
177    public static of(v: Char): Value {
178        return new CharValue(CharType.REF, v)
179    }
180
181    public static of(v: Byte): Value {
182        return new ByteValue(ByteType.REF, v)
183    }
184
185    public static of(v: Short): Value {
186        return new ShortValue(ShortType.REF, v)
187    }
188
189    public static of(v: Int): Value {
190        return new IntValue(IntType.REF, v)
191    }
192
193    public static of(v: Long): Value {
194        return new LongValue(LongType.REF, v)
195    }
196
197    public static of(v: Float): Value {
198        return new FloatValue(FloatType.REF, v)
199    }
200
201    public static of(v: Double): Value {
202        return new DoubleValue(DoubleType.REF, v)
203    }
204
205    // -----
206
207    /**
208     * Returns value of this object
209     *
210     * @param o object instance
211     *
212     * @returns {@link Value} of this object
213     */
214    public static of(o: NullishType): Value {
215        if (o instanceof Value) {
216            return o as Value
217        } else if (o instanceof Boolean) {
218            return new BooleanValue(BooleanType.REF, o as Boolean)
219        } else if (o instanceof Char) {
220            return new CharValue(CharType.REF, o as Char)
221        } else if (o instanceof Byte) {
222            return new ByteValue(ByteType.REF, o as Byte)
223        } else if (o instanceof Short) {
224            return new ShortValue(ShortType.REF, o as Short)
225        } else if (o instanceof Int) {
226            return new IntValue(IntType.REF, o as Int)
227        } else if (o instanceof Long) {
228            return new LongValue(LongType.REF, o as Long)
229        } else if (o instanceof Float) {
230            return new FloatValue(FloatType.REF, o as Float)
231        } else if (o instanceof Double) {
232            return new DoubleValue(DoubleType.REF, o as Double)
233        }
234
235        let t = Type.of(o)
236        if (t instanceof NullType) {
237            return NullValue.INSTANCE
238        } else if (t instanceof UndefinedType) {
239            return UndefinedValue.INSTANCE
240        } else if (t instanceof VoidType) {
241            return VoidValue.INSTANCE
242        } else if (t instanceof ClassType) {
243            return new ClassValue(t as ClassType, o!)
244        } else if (t instanceof ArrayType) {
245            return new ArrayValue(t as ArrayType, o!)
246        } else if (t instanceof StringType) {
247            return new StringValue(t as StringType, o! as string)
248        } else if (t instanceof LambdaType) {
249            return new LambdaValue(t as LambdaType, o!)
250        } else if (t instanceof MethodType) {
251            throw new Error("The MethodType cannot be instantiated")
252        } else if (t instanceof EnumType) {
253            throw new Error("Not implemented")
254        } else if (t instanceof UnionType) {
255            throw new Error("Not implemented")
256        } else if (t instanceof TupleType) {
257            throw new Error("Not implemented")
258        }
259        throw new Error("Unknown type")
260    }
261
262    // -----
263
264    public static of(v: boolean[]): Value {
265        return new ArrayValue(ArrayType.BOOLEAN_VAL, v)
266    }
267
268    public static of(v: char[]): Value {
269        return new ArrayValue(ArrayType.CHAR_VAL, v)
270    }
271
272    public static of(v: byte[]): Value {
273        return new ArrayValue(ArrayType.BYTE_VAL, v)
274    }
275
276    public static of(v: short[]): Value {
277        return new ArrayValue(ArrayType.SHORT_VAL, v)
278    }
279
280    public static of(v: int[]): Value {
281        return new ArrayValue(ArrayType.INT_VAL, v)
282    }
283
284    public static of(v: long[]): Value {
285        return new ArrayValue(ArrayType.LONG_VAL, v)
286    }
287
288    public static of(v: float[]): Value {
289        return new ArrayValue(ArrayType.FLOAT_VAL, v)
290    }
291
292    public static of(v: double[]): Value {
293        return new ArrayValue(ArrayType.DOUBLE_VAL, v)
294    }
295
296    public abstract getType(): Type
297
298    public abstract getData(): NullishType
299
300    public abstract toPrint(depth: int): string
301}
302
303
304/**
305 * Represents value of object of class type
306 */
307export final class ClassValue extends Value {
308    private typ: ClassType
309    private data: Object
310
311    public override getType(): Type {
312        return this.typ as Type
313    }
314
315    public override getData(): NullishType {
316        return this.data
317    }
318
319    internal constructor(typ: ClassType, data: Object) {
320        this.typ = typ
321        this.data = data
322    }
323
324    /**
325     * Returns number of fields of this value
326     *
327     * @returns number of fields
328     */
329    public getFieldsNum(): long {
330        return this.typ.getFieldsNum()
331    }
332
333    /**
334     * Returns ith field of value
335     *
336     * @param i index
337     *
338     * @throws error when i greater then field's number
339     *
340     * @returns field {@link Value}
341     */
342    public getField(i: long): Value {
343        let f = this.typ.getField(i)
344        if (f.isStatic()) {
345            throw new Error("Field must be not static")
346        }
347        let ft = f.getType()
348        if (!ft.isReference()) {
349            if (ft instanceof BooleanType) {
350                return new BooleanValue(ft as BooleanType, ValueAPIGetFieldBoolean(this.data, i))
351            } else if (ft instanceof ByteType) {
352                return new ByteValue(ft as ByteType, ValueAPIGetFieldByte(this.data, i))
353            } else if (ft instanceof ShortType) {
354                return new ShortValue(ft as ShortType, ValueAPIGetFieldShort(this.data, i))
355            } else if (ft instanceof CharType) {
356                return new CharValue(ft as CharType, ValueAPIGetFieldChar(this.data, i))
357            } else if (ft instanceof IntType) {
358                return new IntValue(ft as IntType, ValueAPIGetFieldInt(this.data, i))
359            } else if (ft instanceof FloatType) {
360                return new FloatValue(ft as FloatType, ValueAPIGetFieldFloat(this.data, i))
361            } else if (ft instanceof DoubleType) {
362                return new DoubleValue(ft as DoubleType, ValueAPIGetFieldDouble(this.data, i))
363            } else if (ft instanceof LongType) {
364                return new LongValue(ft as LongType, ValueAPIGetFieldLong(this.data, i))
365            }
366        }
367        return Value.of(ValueAPIGetFieldObject(this.data, i))
368    }
369
370    public getFieldByName(name: string): Value {
371        let f = this.typ.getFieldByName(name)
372        if (f.isStatic()) {
373            throw new Error("Field must be not static")
374        }
375        const ft = f.getType()
376        if (!ft.isReference()) {
377            if (ft instanceof BooleanType) {
378                return new BooleanValue(ft as BooleanType, ValueAPIGetFieldByNameBoolean(this.data, name))
379            } else if (ft instanceof ByteType) {
380                return new ByteValue(ft as ByteType, ValueAPIGetFieldByNameByte(this.data, name))
381            } else if (ft instanceof ShortType) {
382                return new ShortValue(ft as ShortType, ValueAPIGetFieldByNameShort(this.data, name))
383            } else if (ft instanceof CharType) {
384                return new CharValue(ft as CharType, ValueAPIGetFieldByNameChar(this.data, name))
385            } else if (ft instanceof IntType) {
386                return new IntValue(ft as IntType, ValueAPIGetFieldByNameInt(this.data, name))
387            } else if (ft instanceof FloatType) {
388                return new FloatValue(ft as FloatType, ValueAPIGetFieldByNameFloat(this.data, name))
389            } else if (ft instanceof DoubleType) {
390                return new DoubleValue(ft as DoubleType, ValueAPIGetFieldByNameDouble(this.data, name))
391            } else if (ft instanceof LongType) {
392                return new LongValue(ft as LongType, ValueAPIGetFieldByNameLong(this.data, name))
393            }
394            assert(false)
395        }
396        return Value.of(ValueAPIGetFieldByNameObject(this.data, name))
397    }
398
399    /**
400     * Sets field value by it's name
401     *
402     * @param name of field
403     *
404     * @param val @{link Value}
405     *
406     * @throws error if this value doesn't have field with {@link name}
407     * or type of {@link val} doesn't assignable to type of this value
408     */
409    public setFieldByName(name: string, val: Value) {
410        let f = this.typ.getFieldByName(name)
411        if (f.isStatic()) {
412            throw new Error("Field must be not static")
413        }
414        let ft = f.getType()
415        let vt = val.getType()
416        if (!ft.assignableFrom(vt)) {
417            throw new Error("Cannot assign field of type " + ft + " with value of type " + vt)
418        }
419
420        if (ft instanceof BooleanType && val instanceof BooleanValue) {
421            ValueAPISetFieldByNameBoolean(this.data, name, (val as BooleanValue).getValueData())
422        } else if (ft instanceof ByteType && val instanceof ByteValue) {
423            ValueAPISetFieldByNameByte(this.data, name, (val as ByteValue).getValueData())
424        } else if (ft instanceof ShortType && val instanceof ShortValue) {
425            ValueAPISetFieldByNameShort(this.data, name, (val as ShortValue).getValueData())
426        } else if (ft instanceof CharType && val instanceof CharValue) {
427            ValueAPISetFieldByNameChar(this.data, name, (val as CharValue).getValueData())
428        } else if (ft instanceof IntType && val instanceof IntValue) {
429            ValueAPISetFieldByNameInt(this.data, name, (val as IntValue).getValueData())
430        } else if (ft instanceof FloatType && val instanceof FloatValue) {
431            ValueAPISetFieldByNameFloat(this.data, name, (val as FloatValue).getValueData())
432        } else if (ft instanceof DoubleType && val instanceof DoubleValue) {
433            ValueAPISetFieldByNameDouble(this.data, name, (val as DoubleValue).getValueData())
434        } else if (ft instanceof LongType && val instanceof LongValue) {
435            ValueAPISetFieldByNameLong(this.data, name, (val as LongValue).getValueData())
436        } else if (ft.assignableFrom(StringType.REF) && val instanceof StringValue) {
437            ValueAPISetFieldByNameObject(this.data, name, (val as StringValue).getData()! as string)
438        } else if (ft instanceof ArrayType && val instanceof ArrayValue) {
439            ValueAPISetFieldByNameObject(this.data, name, (val as ArrayValue).getData()!)
440        } else if (ft instanceof ClassType && this.isAssignableToObject(val)) {
441            ValueAPISetFieldByNameObject(this.data, name, val.getData()!)
442        } else if (ft instanceof LambdaType && val instanceof LambdaValue) {
443            ValueAPISetFieldByNameObject(this.data, name, (val as LambdaValue).getData()!)
444        } else {
445            throw new Error("Cannot assign field of type " + ft + " with value of type " + vt)
446        }
447    }
448
449    private isAssignableToObject(v: Value): boolean {
450        return v instanceof ClassValue
451            || v instanceof LambdaValue
452            || v instanceof StringValue
453            || v instanceof ArrayValue
454    }
455
456    /**
457     * Sets field value by it's index
458     *
459     * @param i of field
460     *
461     * @param val @{link Value}
462     *
463     * @throws error if this value doesn't have field with {@link index}'th index
464     * or type of {@link val} doesn't assignable to type of this value
465     */
466    public setField(i: long, val: Value) {
467        let f = this.typ.getField(i)
468        if (f.isStatic()) {
469            throw new Error("Field must be not static")
470        }
471        let ft = f.getType()
472        let vt = val.getType()
473        if (!ft.assignableFrom(vt)) {
474            throw new Error("Cannot assign field of type " + ft + " with value of type " + vt)
475        }
476        if (ft instanceof BooleanType && val instanceof BooleanValue) {
477            ValueAPISetFieldBoolean(this.data, i, (val as BooleanValue).getValueData())
478        } else if (ft instanceof ByteType && val instanceof ByteValue) {
479            ValueAPISetFieldByte(this.data, i, (val as ByteValue).getValueData())
480        } else if (ft instanceof ShortType && val instanceof ShortValue) {
481            ValueAPISetFieldShort(this.data, i, (val as ShortValue).getValueData())
482        } else if (ft instanceof CharType && val instanceof CharValue) {
483            ValueAPISetFieldChar(this.data, i, (val as CharValue).getValueData())
484        } else if (ft instanceof IntType && val instanceof IntValue) {
485            ValueAPISetFieldInt(this.data, i, (val as IntValue).getValueData())
486        } else if (ft instanceof FloatType && val instanceof FloatValue) {
487            ValueAPISetFieldFloat(this.data, i, (val as FloatValue).getValueData())
488        } else if (ft instanceof DoubleType && val instanceof DoubleValue) {
489            ValueAPISetFieldDouble(this.data, i, (val as DoubleValue).getValueData())
490        } else if (ft instanceof LongType && val instanceof LongValue) {
491            ValueAPISetFieldLong(this.data, i, (val as LongValue).getValueData())
492        } else if (ft instanceof StringType && val instanceof StringValue) {
493            ValueAPISetFieldObject(this.data, i, (val as StringValue).getData()! as string)
494        } else if (ft instanceof ArrayType && val instanceof ArrayValue) {
495            ValueAPISetFieldObject(this.data, i, (val as ArrayValue).getData()!)
496        } else if (ft instanceof ClassType && this.isAssignableToObject(val)) {
497            ValueAPISetFieldObject(this.data, i, (val as ClassValue).getData()!)
498        } else if (ft instanceof LambdaType && val instanceof LambdaValue) {
499            ValueAPISetFieldObject(this.data, i, val.getData()!)
500        } else {
501            throw new Error("Cannot assign field of type " + ft + " with value of type " + vt)
502        }
503    }
504
505    public override toPrint(depth: int): string {
506        if (depth == 0) {
507            return this.typ.getName() + " {...}"
508        }
509
510        const thisStr = this.data.toString()
511        const objStr = new Object().toString()
512        if (thisStr != objStr) {
513            return thisStr
514        }
515        const fnum = this.getFieldsNum()
516        if (fnum == 0) {
517            return this.typ.getName() + " {}"
518        }
519        let res = new StringBuilder(this.typ.getName())
520        res.append(" {")
521        for (let i = 0; i < fnum; i++) {
522            const f = this.typ.getField(i)
523            if (f.isStatic()) {
524                continue
525            }
526            const fv = this.getField(i)
527            res.append(f.getName())
528            res.append(": ")
529            res.append(fv.toPrint(depth - 1))
530            if (i != fnum - 1) {
531                res.append(", ")
532            }
533        }
534        res.append("}")
535        return res.toString()
536    }
537
538    public override toString(): string {
539        return "[object Object]"
540    }
541
542    public override toLocaleString(): string {
543        return this.toString()
544    }
545}
546
547/**
548 * Represents array value
549 */
550export final class ArrayValue extends Value {
551    private typ: ArrayType
552    private data: Object
553
554    public override getType(): Type {
555        return this.typ as Type
556    }
557
558    public override getData(): NullishType {
559        return this.data
560    }
561
562    internal constructor(typ: ArrayType, data: Object) {
563        this.typ = typ
564        this.data = data
565    }
566
567    public getLength(): long {
568        return ValueAPIGetArrayLength(this.data)
569    }
570
571    public getElement(i: long): Value {
572        const et = this.typ.getElementType()
573        if (!et.isReference()) {
574            if (et instanceof BooleanType) {
575                return new BooleanValue(et as BooleanType, ValueAPIGetElementBoolean(this.data, i))
576            } else if (et instanceof ByteType) {
577                return new ByteValue(et as ByteType, ValueAPIGetElementByte(this.data, i))
578            } else if (et instanceof ShortType) {
579                return new ShortValue(et as ShortType, ValueAPIGetElementShort(this.data, i))
580            } else if (et instanceof CharType) {
581                return new CharValue(et as CharType, ValueAPIGetElementChar(this.data, i))
582            } else if (et instanceof IntType) {
583                return new IntValue(et as IntType, ValueAPIGetElementInt(this.data, i))
584            } else if (et instanceof FloatType) {
585                return new FloatValue(et as FloatType, ValueAPIGetElementFloat(this.data, i))
586            } else if (et instanceof DoubleType) {
587                return new DoubleValue(et as DoubleType, ValueAPIGetElementDouble(this.data, i))
588            } else if (et instanceof LongType) {
589                return new LongValue(et as LongType, ValueAPIGetElementLong(this.data, i))
590            }
591            assert(false)
592        }
593        return Value.of(ValueAPIGetElementObject(this.data, i))
594    }
595
596    /**
597     * Sets i'th element of array
598     *
599     * @param i index
600     *
601     * @param val {@link Value} to be set
602     *
603     * @throws error if of {@link val} cannot be assign to i'th element of array
604     */
605    public setElement(i: long, val: Value) {
606        let et = this.typ.getElementType()
607        let vt = val.getType()
608        if (!et.assignableFrom(vt)) {
609            throw new Error("Cannot assign array of type " + et + " with value of type " + vt)
610        }
611        if (et instanceof BooleanType && val instanceof BooleanValue) {
612            ValueAPISetElementBoolean(this.data, i, (val as BooleanValue).getValueData())
613        } else if (et instanceof ByteType && val instanceof ByteValue) {
614            ValueAPISetElementByte(this.data, i, (val as ByteValue).getValueData())
615        } else if (et instanceof ShortType && val instanceof ShortValue) {
616            ValueAPISetElementShort(this.data, i, (val as ShortValue).getValueData())
617        } else if (et instanceof CharType && val instanceof CharValue) {
618            ValueAPISetElementChar(this.data, i, (val as CharValue).getValueData())
619        } else if (et instanceof IntType && val instanceof IntValue) {
620            ValueAPISetElementInt(this.data, i, (val as IntValue).getValueData())
621        } else if (et instanceof FloatType && val instanceof FloatValue) {
622            ValueAPISetElementFloat(this.data, i, (val as FloatValue).getValueData())
623        } else if (et instanceof DoubleType && val instanceof DoubleValue) {
624            ValueAPISetElementDouble(this.data, i, (val as DoubleValue).getValueData())
625        } else if (et instanceof LongType && val instanceof LongValue) {
626            ValueAPISetElementLong(this.data, i, (val as LongValue).getValueData())
627        } else if (et instanceof StringType && val instanceof StringValue) {
628            ValueAPISetElementObject(this.data, i, (val as StringValue).getData()! as string)
629        } else if (et instanceof ArrayType && val instanceof ArrayValue) {
630            ValueAPISetElementObject(this.data, i, (val as ArrayValue).getData()!)
631        } else if (et instanceof ClassType && val instanceof ClassValue) {
632            ValueAPISetElementObject(this.data, i, (val as ClassValue).getData()!)
633        } else {
634            throw new Error("Cannot assign array of type " + et + " with value of type " + vt)
635        }
636    }
637
638    public override toPrint(depth: int): string {
639        if (depth == 0) {
640            return "[...]"
641        }
642        const len = this.getLength()
643        if (len == 0) {
644            return "[]"
645        }
646        let res = new StringBuilder("[")
647        for (let i = 0; i < len; i++) {
648            res.append(this.getElement(i).toPrint(depth - 1))
649            if (i != len - 1) {
650                res.append(", ")
651            }
652        }
653        res.append("]")
654        return res.toString()
655    }
656
657    public override toString(): string {
658        const len = this.getLength()
659        if (len == 0) {
660            return ""
661        }
662        let res = new StringBuilder()
663        for (let i = 0; i < len; i++) {
664            res.append(this.getElement(i).toString())
665            if (i != len - 1) {
666                res.append(",")
667            }
668        }
669        return res.toString()
670    }
671
672    public override toLocaleString(): string {
673        const len = this.getLength()
674        if (len == 0) {
675            return ""
676        }
677        let res = new StringBuilder()
678        for (let i = 0; i < len; i++) {
679            res.append(this.getElement(i).toLocaleString())
680            if (i != len - 1) {
681                res.append(",")
682            }
683        }
684        return res.toString()
685    }
686}
687
688export final class LambdaValue extends Value {
689    private typ: LambdaType
690    private data: Object
691
692    public override getType(): Type {
693        return this.typ as Type
694    }
695
696    public override getData(): NullishType {
697        return this.data
698    }
699
700    internal constructor(typ: LambdaType, data: Object) {
701        this.typ = typ
702        this.data = data
703    }
704
705    public invoke(...args: Object[]): Object {
706        // NOTE(shumilov-petr): not implemented
707        throw new Error("Not implemented")
708    }
709
710    public override toPrint(depth: int): string {
711        return "[object Function]"
712    }
713
714    public override toString(): string {
715        return this.typ.toString()
716    }
717
718    public override toLocaleString(): string {
719        return this.toString()
720    }
721}
722
723/**
724 * Represents boolean value
725 */
726export final class BooleanValue extends Value {
727    private typ: BooleanType
728    private data: boolean
729
730    public override getType(): Type {
731        return this.typ as Type
732    }
733
734    public override getData(): NullishType {
735        return new Boolean(this.data)
736    }
737
738    public getValueData(): boolean {
739        return this.data
740    }
741
742    internal constructor(typ: BooleanType, data: boolean) {
743        this.typ = typ
744        this.data = data
745    }
746
747    internal constructor(typ: BooleanType, data: Boolean) {
748        this(typ, data.unboxed())
749    }
750
751    public override toPrint(depth: int): string {
752        return new StringBuilder().append(this.data).toString()
753    }
754
755    public override toString(): string {
756        return new StringBuilder().append(this.data).toString()
757    }
758
759    public override toLocaleString(): string {
760        return this.toString()
761    }
762}
763
764/**
765 * Represents byte value
766 */
767export final class ByteValue extends Value {
768    private typ: ByteType
769    private data: byte
770
771    public override getType(): Type {
772        return this.typ as Type
773    }
774
775    public override getData(): NullishType {
776        return new Byte(this.data)
777    }
778
779    public getValueData(): byte {
780        return this.data
781    }
782
783    internal constructor(typ: ByteType, data: byte) {
784        this.typ = typ
785        this.data = data
786    }
787
788    internal constructor(typ: ByteType, data: Byte) {
789        this(typ, data.unboxed())
790    }
791
792    public override toPrint(depth: int): string {
793        return new StringBuilder().append(this.data).toString()
794    }
795
796    public override toString(): string {
797        return new StringBuilder().append(this.data).toString()
798    }
799
800    public override toLocaleString(): string {
801        return this.toString()
802    }
803}
804
805/**
806 * Represents short value
807 */
808export final class ShortValue extends Value {
809    private typ: ShortType
810    private data: short
811
812    public override getType(): Type {
813        return this.typ as Type
814    }
815
816    public override getData(): NullishType {
817        return new Short(this.data)
818    }
819
820    public getValueData(): short {
821        return this.data
822    }
823
824    internal constructor(typ: ShortType, data: short) {
825        this.typ = typ
826        this.data = data
827    }
828
829    internal constructor(typ: ShortType, data: Short) {
830        this(typ, data.unboxed())
831    }
832
833    public override toPrint(depth: int): string {
834        return new StringBuilder().append(this.data).toString()
835    }
836
837    public override toString(): string {
838        return new StringBuilder().append(this.data).toString()
839    }
840
841    public override toLocaleString(): string {
842        return this.toString()
843    }
844}
845
846/**
847 * Represents char value
848 */
849export final class CharValue extends Value {
850    private typ: CharType
851    private data: char
852
853    public override getType(): Type {
854        return this.typ as Type
855    }
856
857    public override getData(): NullishType {
858        return new Char(this.data)
859    }
860
861    public getValueData(): char {
862        return this.data
863    }
864
865    internal constructor(typ: CharType, data: char) {
866        this.typ = typ
867        this.data = data
868    }
869
870    internal constructor(typ: CharType, data: Char) {
871        this(typ, data.unboxed())
872    }
873
874    public override toPrint(depth: int): string {
875        return new StringBuilder("\"").append(this.data).append("\"").toString()
876    }
877
878    public override toString(): string {
879        return new StringBuilder("\"").append(this.data).append("\"").toString()
880    }
881
882    public override toLocaleString(): string {
883        return this.toString()
884    }
885}
886
887/**
888 * Represents int value
889 */
890export final class IntValue extends Value {
891    private typ: IntType
892    private data: int
893
894    public override getType(): Type {
895        return this.typ as Type
896    }
897
898    public override getData(): NullishType {
899        return new Int(this.data)
900    }
901
902    public getValueData(): int {
903        return this.data
904    }
905
906    internal constructor(typ: IntType, data: int) {
907        this.typ = typ
908        this.data = data
909    }
910
911    internal constructor(typ: IntType, data: Int) {
912        this(typ, data.unboxed())
913    }
914
915    public override toPrint(depth: int): string {
916        return new StringBuilder().append(this.data).toString()
917    }
918
919    public override toString(): string {
920        return new StringBuilder().append(this.data).toString()
921    }
922
923    public override toLocaleString(): string {
924        return this.toString()
925    }
926}
927
928/**
929 * Represents float value
930 */
931export final class FloatValue extends Value {
932    private typ: FloatType
933    private data: float
934
935    public override getType(): Type {
936        return this.typ as Type
937    }
938
939    public override getData(): NullishType {
940        return new Float(this.data)
941    }
942
943    public getValueData(): float {
944        return this.data
945    }
946
947    internal constructor(typ: FloatType, data: float) {
948        this.typ = typ
949        this.data = data
950    }
951
952    internal constructor(typ: FloatType, data: Float) {
953        this(typ, data.unboxed())
954    }
955
956    public override toPrint(depth: int): string {
957        return new StringBuilder().append(this.data).toString()
958    }
959
960    public override toString(): string {
961        return new StringBuilder().append(this.data).toString()
962    }
963
964    public override toLocaleString(): string {
965        return this.toString()
966    }
967}
968
969/**
970 * Represents double value
971 */
972export final class DoubleValue extends Value {
973    private typ: DoubleType
974    private data: double
975
976    public override getType(): Type {
977        return this.typ as Type
978    }
979
980    public override getData(): NullishType {
981        return this.data
982    }
983
984    public getValueData(): double {
985        return this.data
986    }
987
988    internal constructor(typ: DoubleType, data: double) {
989        this.typ = typ
990        this.data = data
991    }
992
993    internal constructor(typ: DoubleType, data: Double) {
994        this(typ, data.unboxed())
995    }
996
997    public override toPrint(depth: int): string {
998        return new StringBuilder().append(this.data).toString()
999    }
1000
1001    public override toString(): string {
1002        return new StringBuilder().append(this.data).toString()
1003    }
1004
1005    public override toLocaleString(): string {
1006        return this.toString()
1007    }
1008}
1009
1010/**
1011 * Represents long value
1012 */
1013export final class LongValue extends Value {
1014    private typ: LongType
1015    private data: long
1016
1017    public override getType(): Type {
1018        return this.typ as Type
1019    }
1020
1021    public override getData(): NullishType {
1022        return new Long(this.data)
1023    }
1024
1025    public getValueData(): long {
1026        return this.data
1027    }
1028
1029    internal constructor(typ: LongType, data: long) {
1030        this.typ = typ
1031        this.data = data
1032    }
1033
1034    internal constructor(typ: LongType, data: Long) {
1035        this(typ, data.unboxed())
1036    }
1037
1038    public override toPrint(depth: int): string {
1039        return new StringBuilder().append(this.data).toString()
1040    }
1041
1042    public override toString(): string {
1043        return new StringBuilder().append(this.data).toString()
1044    }
1045
1046    public override toLocaleString(): string {
1047        return this.toString()
1048    }
1049}
1050
1051/**
1052 * Represents string value
1053 */
1054export final class StringValue extends Value {
1055    private typ: StringType
1056    private data: string
1057
1058    public override getType(): Type {
1059        return this.typ as Type
1060    }
1061
1062    public override getData(): NullishType {
1063        return this.data
1064    }
1065
1066    internal constructor(typ: StringType, data: String) {
1067        this.typ = typ
1068        this.data = data
1069    }
1070
1071    public override toPrint(depth: int): string {
1072        return new StringBuilder().append(this.data).toString()
1073    }
1074
1075    public override toString(): string {
1076        return new StringBuilder().append(this.data).toString()
1077    }
1078
1079    public override toLocaleString(): string {
1080        return this.toString()
1081    }
1082}
1083
1084/**
1085 * Represents null value
1086 */
1087export final class NullValue extends Value {
1088    public static readonly INSTANCE = new NullValue()
1089
1090    public override getType(): Type {
1091        return NullType.REF as Type
1092    }
1093
1094    public override getData(): NullishType {
1095        return null
1096    }
1097
1098    internal constructor() {}
1099
1100    public override toPrint(depth: int): string {
1101        return NullType.REF.toString()
1102    }
1103
1104    public override toString(): string {
1105        return NullType.REF.toString()
1106    }
1107
1108    public override toLocaleString(): string {
1109        return this.toString()
1110    }
1111}
1112
1113/**
1114 * Represents undefined value
1115 */
1116export final class UndefinedValue extends Value {
1117    public static readonly INSTANCE = new UndefinedValue()
1118
1119    public override getType(): Type {
1120        return UndefinedType.REF as Type
1121    }
1122
1123    public override getData(): NullishType {
1124        return undefined
1125    }
1126
1127    internal constructor() {}
1128
1129    public override toPrint(depth: int): string {
1130        return UndefinedType.REF.toString()
1131    }
1132
1133    public override toString(): string {
1134        return UndefinedType.REF.toString()
1135    }
1136
1137    public override toLocaleString(): string {
1138        return this.toString()
1139    }
1140}
1141
1142/**
1143 * Represents void value
1144 */
1145export final class VoidValue extends Value {
1146    public static readonly INSTANCE = new VoidValue()
1147
1148    public override getType(): Type {
1149        return VoidType.REF as Type
1150    }
1151
1152    public override getData(): NullishType {
1153        return Void.void_instance
1154    }
1155
1156    internal constructor() {}
1157
1158    public override toPrint(depth: int): string {
1159        return VoidType.REF.toString()
1160    }
1161
1162    public override toString(): string {
1163        return VoidType.REF.toString()
1164    }
1165
1166    public override toLocaleString(): string {
1167        return this.toString()
1168    }
1169}
1170