• 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        // NOTE(shumilov-petr): throw `unknown type` exception
260        assert(false)
261    }
262
263    // -----
264
265    public static of(v: boolean[]): Value {
266        return new ArrayValue(ArrayType.BOOLEAN_VAL, v)
267    }
268
269    public static of(v: char[]): Value {
270        return new ArrayValue(ArrayType.CHAR_VAL, v)
271    }
272
273    public static of(v: byte[]): Value {
274        return new ArrayValue(ArrayType.BYTE_VAL, v)
275    }
276
277    public static of(v: short[]): Value {
278        return new ArrayValue(ArrayType.SHORT_VAL, v)
279    }
280
281    public static of(v: int[]): Value {
282        return new ArrayValue(ArrayType.INT_VAL, v)
283    }
284
285    public static of(v: long[]): Value {
286        return new ArrayValue(ArrayType.LONG_VAL, v)
287    }
288
289    public static of(v: float[]): Value {
290        return new ArrayValue(ArrayType.FLOAT_VAL, v)
291    }
292
293    public static of(v: double[]): Value {
294        return new ArrayValue(ArrayType.DOUBLE_VAL, v)
295    }
296
297    public abstract getType(): Type
298
299    public abstract getData(): NullishType
300
301    public abstract toPrint(depth: int): string
302}
303
304
305/**
306 * Represents value of object of class type
307 */
308export final class ClassValue extends Value {
309    private typ: ClassType
310    private data: Object
311
312    public override getType(): Type {
313        return this.typ as Type
314    }
315
316    public override getData(): NullishType {
317        return this.data
318    }
319
320    internal constructor(typ: ClassType, data: Object) {
321        this.typ = typ
322        this.data = data
323    }
324
325    /**
326     * Returns number of fields of this value
327     *
328     * @returns number of fields
329     */
330    public getFieldsNum(): long {
331        return this.typ.getFieldsNum()
332    }
333
334    /**
335     * Returns ith field of value
336     *
337     * @param i index
338     *
339     * @throws error when i greater then field's number
340     *
341     * @returns field {@link Value}
342     */
343    public getField(i: long): Value {
344        let f = this.typ.getField(i)
345        if (f.isStatic()) {
346            throw new Error("Field must be not static")
347        }
348        let ft = f.getType()
349        if (!ft.isReference()) {
350            if (ft instanceof BooleanType) {
351                return new BooleanValue(ft as BooleanType, ValueAPIGetFieldBoolean(this.data, i))
352            } else if (ft instanceof ByteType) {
353                return new ByteValue(ft as ByteType, ValueAPIGetFieldByte(this.data, i))
354            } else if (ft instanceof ShortType) {
355                return new ShortValue(ft as ShortType, ValueAPIGetFieldShort(this.data, i))
356            } else if (ft instanceof CharType) {
357                return new CharValue(ft as CharType, ValueAPIGetFieldChar(this.data, i))
358            } else if (ft instanceof IntType) {
359                return new IntValue(ft as IntType, ValueAPIGetFieldInt(this.data, i))
360            } else if (ft instanceof FloatType) {
361                return new FloatValue(ft as FloatType, ValueAPIGetFieldFloat(this.data, i))
362            } else if (ft instanceof DoubleType) {
363                return new DoubleValue(ft as DoubleType, ValueAPIGetFieldDouble(this.data, i))
364            } else if (ft instanceof LongType) {
365                return new LongValue(ft as LongType, ValueAPIGetFieldLong(this.data, i))
366            }
367        }
368        return Value.of(ValueAPIGetFieldObject(this.data, i))
369    }
370
371    public getFieldByName(name: string): Value {
372        let f = this.typ.getFieldByName(name)
373        if (f.isStatic()) {
374            throw new Error("Field must be not static")
375        }
376        const ft = f.getType()
377        if (!ft.isReference()) {
378            if (ft instanceof BooleanType) {
379                return new BooleanValue(ft as BooleanType, ValueAPIGetFieldByNameBoolean(this.data, name))
380            } else if (ft instanceof ByteType) {
381                return new ByteValue(ft as ByteType, ValueAPIGetFieldByNameByte(this.data, name))
382            } else if (ft instanceof ShortType) {
383                return new ShortValue(ft as ShortType, ValueAPIGetFieldByNameShort(this.data, name))
384            } else if (ft instanceof CharType) {
385                return new CharValue(ft as CharType, ValueAPIGetFieldByNameChar(this.data, name))
386            } else if (ft instanceof IntType) {
387                return new IntValue(ft as IntType, ValueAPIGetFieldByNameInt(this.data, name))
388            } else if (ft instanceof FloatType) {
389                return new FloatValue(ft as FloatType, ValueAPIGetFieldByNameFloat(this.data, name))
390            } else if (ft instanceof DoubleType) {
391                return new DoubleValue(ft as DoubleType, ValueAPIGetFieldByNameDouble(this.data, name))
392            } else if (ft instanceof LongType) {
393                return new LongValue(ft as LongType, ValueAPIGetFieldByNameLong(this.data, name))
394            }
395            assert(false)
396        }
397        return Value.of(ValueAPIGetFieldByNameObject(this.data, name))
398    }
399
400    /**
401     * Sets field value by it's name
402     *
403     * @param name of field
404     *
405     * @param val @{link Value}
406     *
407     * @throws error if this value doesn't have field with {@link name}
408     * or type of {@link val} doesn't assignable to type of this value
409     */
410    public setFieldByName(name: string, val: Value) {
411        let f = this.typ.getFieldByName(name)
412        if (f.isStatic()) {
413            throw new Error("Field must be not static")
414        }
415        let ft = f.getType()
416        let vt = val.getType()
417        if (!ft.assignableFrom(vt)) {
418            throw new Error("Cannot assign field of type " + ft + " with value of type " + vt)
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 instanceof StringType && 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 && val instanceof ClassValue) {
441            ValueAPISetFieldByNameObject(this.data, name, (val as ClassValue).getData()!)
442        } else {
443            throw new Error("Cannot assign field of type " + ft + " with value of type " + vt)
444        }
445    }
446
447    /**
448     * Sets field value by it's index
449     *
450     * @param i of field
451     *
452     * @param val @{link Value}
453     *
454     * @throws error if this value doesn't have field with {@link index}'th index
455     * or type of {@link val} doesn't assignable to type of this value
456     */
457    public setField(i: long, val: Value) {
458        let f = this.typ.getField(i)
459        if (f.isStatic()) {
460            throw new Error("Field must be not static")
461        }
462        let ft = f.getType()
463        let vt = val.getType()
464        if (!ft.assignableFrom(vt)) {
465            throw new Error("Cannot assign field of type " + ft + " with value of type " + vt)
466        }
467        if (ft instanceof BooleanType && val instanceof BooleanValue) {
468            ValueAPISetFieldBoolean(this.data, i, (val as BooleanValue).getValueData())
469        } else if (ft instanceof ByteType && val instanceof ByteValue) {
470            ValueAPISetFieldByte(this.data, i, (val as ByteValue).getValueData())
471        } else if (ft instanceof ShortType && val instanceof ShortValue) {
472            ValueAPISetFieldShort(this.data, i, (val as ShortValue).getValueData())
473        } else if (ft instanceof CharType && val instanceof CharValue) {
474            ValueAPISetFieldChar(this.data, i, (val as CharValue).getValueData())
475        } else if (ft instanceof IntType && val instanceof IntValue) {
476            ValueAPISetFieldInt(this.data, i, (val as IntValue).getValueData())
477        } else if (ft instanceof FloatType && val instanceof FloatValue) {
478            ValueAPISetFieldFloat(this.data, i, (val as FloatValue).getValueData())
479        } else if (ft instanceof DoubleType && val instanceof DoubleValue) {
480            ValueAPISetFieldDouble(this.data, i, (val as DoubleValue).getValueData())
481        } else if (ft instanceof LongType && val instanceof LongValue) {
482            ValueAPISetFieldLong(this.data, i, (val as LongValue).getValueData())
483        } else if (ft instanceof StringType && val instanceof StringValue) {
484            ValueAPISetFieldObject(this.data, i, (val as StringValue).getData()! as string)
485        } else if (ft instanceof ArrayType && val instanceof ArrayValue) {
486            ValueAPISetFieldObject(this.data, i, (val as ArrayValue).getData()!)
487        } else if (ft instanceof ClassType && val instanceof ClassValue) {
488            ValueAPISetFieldObject(this.data, i, (val as ClassValue).getData()!)
489        } else {
490            throw new Error("Cannot assign field of type " + ft + " with value of type " + vt)
491        }
492    }
493
494    public override toPrint(depth: int): string {
495        if (depth == 0) {
496            return this.typ.getName() + " {...}"
497        }
498        // If class has user-overrided `toString`
499        const mnum = this.typ.getMethodsNum()
500        for (let i = 0; i < mnum; i++) {
501            const m = this.typ.getMethod(i)
502            if (m.getName() == OBJECT_TO_STRING_MEMBER_NAME && !m.getType().getReceiverType().equals(ObjectType)) {
503                return this.data.toString()
504            }
505        }
506        const fnum = this.getFieldsNum()
507        if (fnum == 0) {
508            return this.typ.getName() + " {}"
509        }
510        let res = new StringBuilder(this.typ.getName())
511        res.append(" {")
512        for (let i = 0; i < fnum; i++) {
513            const f = this.typ.getField(i)
514            if (f.isStatic()) {
515                continue
516            }
517            const fv = this.getField(i)
518            res.append(f.getName())
519            res.append(": ")
520            res.append(fv.toPrint(depth - 1))
521            if (i != fnum - 1) {
522                res.append(", ")
523            }
524        }
525        res.append("}")
526        return res.toString()
527    }
528
529    public override toString(): string {
530        return "[object Object]"
531    }
532
533    public override toLocaleString(): string {
534        return this.toString()
535    }
536}
537
538/**
539 * Represents array value
540 */
541export final class ArrayValue extends Value {
542    private typ: ArrayType
543    private data: Object
544
545    public override getType(): Type {
546        return this.typ as Type
547    }
548
549    public override getData(): NullishType {
550        return this.data
551    }
552
553    internal constructor(typ: ArrayType, data: Object) {
554        this.typ = typ
555        this.data = data
556    }
557
558    public getLength(): long {
559        return ValueAPIGetArrayLength(this.data)
560    }
561
562    public getElement(i: long): Value {
563        const et = this.typ.getElementType()
564        if (!et.isReference()) {
565            if (et instanceof BooleanType) {
566                return new BooleanValue(et as BooleanType, ValueAPIGetElementBoolean(this.data, i))
567            } else if (et instanceof ByteType) {
568                return new ByteValue(et as ByteType, ValueAPIGetElementByte(this.data, i))
569            } else if (et instanceof ShortType) {
570                return new ShortValue(et as ShortType, ValueAPIGetElementShort(this.data, i))
571            } else if (et instanceof CharType) {
572                return new CharValue(et as CharType, ValueAPIGetElementChar(this.data, i))
573            } else if (et instanceof IntType) {
574                return new IntValue(et as IntType, ValueAPIGetElementInt(this.data, i))
575            } else if (et instanceof FloatType) {
576                return new FloatValue(et as FloatType, ValueAPIGetElementFloat(this.data, i))
577            } else if (et instanceof DoubleType) {
578                return new DoubleValue(et as DoubleType, ValueAPIGetElementDouble(this.data, i))
579            } else if (et instanceof LongType) {
580                return new LongValue(et as LongType, ValueAPIGetElementLong(this.data, i))
581            }
582            assert(false)
583        }
584        return Value.of(ValueAPIGetElementObject(this.data, i))
585    }
586
587    /**
588     * Sets i'th element of array
589     *
590     * @param i index
591     *
592     * @param val {@link Value} to be set
593     *
594     * @throws error if of {@link val} cannot be assign to i'th element of array
595     */
596    public setElement(i: long, val: Value) {
597        let et = this.typ.getElementType()
598        let vt = val.getType()
599        if (!et.assignableFrom(vt)) {
600            throw new Error("Cannot assign array of type " + et + " with value of type " + vt)
601        }
602        if (et instanceof BooleanType && val instanceof BooleanValue) {
603            ValueAPISetElementBoolean(this.data, i, (val as BooleanValue).getValueData())
604        } else if (et instanceof ByteType && val instanceof ByteValue) {
605            ValueAPISetElementByte(this.data, i, (val as ByteValue).getValueData())
606        } else if (et instanceof ShortType && val instanceof ShortValue) {
607            ValueAPISetElementShort(this.data, i, (val as ShortValue).getValueData())
608        } else if (et instanceof CharType && val instanceof CharValue) {
609            ValueAPISetElementChar(this.data, i, (val as CharValue).getValueData())
610        } else if (et instanceof IntType && val instanceof IntValue) {
611            ValueAPISetElementInt(this.data, i, (val as IntValue).getValueData())
612        } else if (et instanceof FloatType && val instanceof FloatValue) {
613            ValueAPISetElementFloat(this.data, i, (val as FloatValue).getValueData())
614        } else if (et instanceof DoubleType && val instanceof DoubleValue) {
615            ValueAPISetElementDouble(this.data, i, (val as DoubleValue).getValueData())
616        } else if (et instanceof LongType && val instanceof LongValue) {
617            ValueAPISetElementLong(this.data, i, (val as LongValue).getValueData())
618        } else if (et instanceof StringType && val instanceof StringValue) {
619            ValueAPISetElementObject(this.data, i, (val as StringValue).getData()! as string)
620        } else if (et instanceof ArrayType && val instanceof ArrayValue) {
621            ValueAPISetElementObject(this.data, i, (val as ArrayValue).getData()!)
622        } else if (et instanceof ClassType && val instanceof ClassValue) {
623            ValueAPISetElementObject(this.data, i, (val as ClassValue).getData()!)
624        } else {
625            throw new Error("Cannot assign array of type " + et + " with value of type " + vt)
626        }
627    }
628
629    public override toPrint(depth: int): string {
630        if (depth == 0) {
631            return "[...]"
632        }
633        const len = this.getLength()
634        if (len == 0) {
635            return "[]"
636        }
637        let res = new StringBuilder("[")
638        for (let i = 0; i < len; i++) {
639            res.append(this.getElement(i).toPrint(depth - 1))
640            if (i != len - 1) {
641                res.append(", ")
642            }
643        }
644        res.append("]")
645        return res.toString()
646    }
647
648    public override toString(): string {
649        const len = this.getLength()
650        if (len == 0) {
651            return ""
652        }
653        let res = new StringBuilder()
654        for (let i = 0; i < len; i++) {
655            res.append(this.getElement(i).toString())
656            if (i != len - 1) {
657                res.append(",")
658            }
659        }
660        return res.toString()
661    }
662
663    public override toLocaleString(): string {
664        const len = this.getLength()
665        if (len == 0) {
666            return ""
667        }
668        let res = new StringBuilder()
669        for (let i = 0; i < len; i++) {
670            res.append(this.getElement(i).toLocaleString())
671            if (i != len - 1) {
672                res.append(",")
673            }
674        }
675        return res.toString()
676    }
677}
678
679export final class LambdaValue extends Value {
680    private typ: LambdaType
681    private data: Object
682
683    public override getType(): Type {
684        return this.typ as Type
685    }
686
687    public override getData(): NullishType {
688        return this.data
689    }
690
691    internal constructor(typ: LambdaType, data: Object) {
692        this.typ = typ
693        this.data = data
694    }
695
696    public invoke(...args: Object[]): Object {
697        // NOTE(shumilov-petr): not implemented
698        throw new Error("Not implemented")
699    }
700
701    public override toPrint(depth: int): string {
702        return "[object Function]"
703    }
704
705    public override toString(): string {
706        return this.typ.toString()
707    }
708
709    public override toLocaleString(): string {
710        return this.toString()
711    }
712}
713
714/**
715 * Represents boolean value
716 */
717export final class BooleanValue extends Value {
718    private typ: BooleanType
719    private data: boolean
720
721    public override getType(): Type {
722        return this.typ as Type
723    }
724
725    public override getData(): NullishType {
726        return new Boolean(this.data)
727    }
728
729    public getValueData(): boolean {
730        return this.data
731    }
732
733    internal constructor(typ: BooleanType, data: boolean) {
734        this.typ = typ
735        this.data = data
736    }
737
738    internal constructor(typ: BooleanType, data: Boolean) {
739        this(typ, data.unboxed())
740    }
741
742    public override toPrint(depth: int): string {
743        return new StringBuilder().append(this.data).toString()
744    }
745
746    public override toString(): string {
747        return new StringBuilder().append(this.data).toString()
748    }
749
750    public override toLocaleString(): string {
751        return this.toString()
752    }
753}
754
755/**
756 * Represents byte value
757 */
758export final class ByteValue extends Value {
759    private typ: ByteType
760    private data: byte
761
762    public override getType(): Type {
763        return this.typ as Type
764    }
765
766    public override getData(): NullishType {
767        return new Byte(this.data)
768    }
769
770    public getValueData(): byte {
771        return this.data
772    }
773
774    internal constructor(typ: ByteType, data: byte) {
775        this.typ = typ
776        this.data = data
777    }
778
779    internal constructor(typ: ByteType, data: Byte) {
780        this(typ, data.unboxed())
781    }
782
783    public override toPrint(depth: int): string {
784        return new StringBuilder().append(this.data).toString()
785    }
786
787    public override toString(): string {
788        return new StringBuilder().append(this.data).toString()
789    }
790
791    public override toLocaleString(): string {
792        return this.toString()
793    }
794}
795
796/**
797 * Represents short value
798 */
799export final class ShortValue extends Value {
800    private typ: ShortType
801    private data: short
802
803    public override getType(): Type {
804        return this.typ as Type
805    }
806
807    public override getData(): NullishType {
808        return new Short(this.data)
809    }
810
811    public getValueData(): short {
812        return this.data
813    }
814
815    internal constructor(typ: ShortType, data: short) {
816        this.typ = typ
817        this.data = data
818    }
819
820    internal constructor(typ: ShortType, data: Short) {
821        this(typ, data.unboxed())
822    }
823
824    public override toPrint(depth: int): string {
825        return new StringBuilder().append(this.data).toString()
826    }
827
828    public override toString(): string {
829        return new StringBuilder().append(this.data).toString()
830    }
831
832    public override toLocaleString(): string {
833        return this.toString()
834    }
835}
836
837/**
838 * Represents char value
839 */
840export final class CharValue extends Value {
841    private typ: CharType
842    private data: char
843
844    public override getType(): Type {
845        return this.typ as Type
846    }
847
848    public override getData(): NullishType {
849        return new Char(this.data)
850    }
851
852    public getValueData(): char {
853        return this.data
854    }
855
856    internal constructor(typ: CharType, data: char) {
857        this.typ = typ
858        this.data = data
859    }
860
861    internal constructor(typ: CharType, data: Char) {
862        this(typ, data.unboxed())
863    }
864
865    public override toPrint(depth: int): string {
866        return new StringBuilder("\"").append(this.data).append("\"").toString()
867    }
868
869    public override toString(): string {
870        return new StringBuilder("\"").append(this.data).append("\"").toString()
871    }
872
873    public override toLocaleString(): string {
874        return this.toString()
875    }
876}
877
878/**
879 * Represents int value
880 */
881export final class IntValue extends Value {
882    private typ: IntType
883    private data: int
884
885    public override getType(): Type {
886        return this.typ as Type
887    }
888
889    public override getData(): NullishType {
890        return new Int(this.data)
891    }
892
893    public getValueData(): int {
894        return this.data
895    }
896
897    internal constructor(typ: IntType, data: int) {
898        this.typ = typ
899        this.data = data
900    }
901
902    internal constructor(typ: IntType, data: Int) {
903        this(typ, data.unboxed())
904    }
905
906    public override toPrint(depth: int): string {
907        return new StringBuilder().append(this.data).toString()
908    }
909
910    public override toString(): string {
911        return new StringBuilder().append(this.data).toString()
912    }
913
914    public override toLocaleString(): string {
915        return this.toString()
916    }
917}
918
919/**
920 * Represents float value
921 */
922export final class FloatValue extends Value {
923    private typ: FloatType
924    private data: float
925
926    public override getType(): Type {
927        return this.typ as Type
928    }
929
930    public override getData(): NullishType {
931        return new Float(this.data)
932    }
933
934    public getValueData(): float {
935        return this.data
936    }
937
938    internal constructor(typ: FloatType, data: float) {
939        this.typ = typ
940        this.data = data
941    }
942
943    internal constructor(typ: FloatType, data: Float) {
944        this(typ, data.unboxed())
945    }
946
947    public override toPrint(depth: int): string {
948        return new StringBuilder().append(this.data).toString()
949    }
950
951    public override toString(): string {
952        return new StringBuilder().append(this.data).toString()
953    }
954
955    public override toLocaleString(): string {
956        return this.toString()
957    }
958}
959
960/**
961 * Represents double value
962 */
963export final class DoubleValue extends Value {
964    private typ: DoubleType
965    private data: double
966
967    public override getType(): Type {
968        return this.typ as Type
969    }
970
971    public override getData(): NullishType {
972        return this.data
973    }
974
975    public getValueData(): double {
976        return this.data
977    }
978
979    internal constructor(typ: DoubleType, data: double) {
980        this.typ = typ
981        this.data = data
982    }
983
984    internal constructor(typ: DoubleType, data: Double) {
985        this(typ, data.unboxed())
986    }
987
988    public override toPrint(depth: int): string {
989        return new StringBuilder().append(this.data).toString()
990    }
991
992    public override toString(): string {
993        return new StringBuilder().append(this.data).toString()
994    }
995
996    public override toLocaleString(): string {
997        return this.toString()
998    }
999}
1000
1001/**
1002 * Represents long value
1003 */
1004export final class LongValue extends Value {
1005    private typ: LongType
1006    private data: long
1007
1008    public override getType(): Type {
1009        return this.typ as Type
1010    }
1011
1012    public override getData(): NullishType {
1013        return new Long(this.data)
1014    }
1015
1016    public getValueData(): long {
1017        return this.data
1018    }
1019
1020    internal constructor(typ: LongType, data: long) {
1021        this.typ = typ
1022        this.data = data
1023    }
1024
1025    internal constructor(typ: LongType, data: Long) {
1026        this(typ, data.unboxed())
1027    }
1028
1029    public override toPrint(depth: int): string {
1030        return new StringBuilder().append(this.data).toString()
1031    }
1032
1033    public override toString(): string {
1034        return new StringBuilder().append(this.data).toString()
1035    }
1036
1037    public override toLocaleString(): string {
1038        return this.toString()
1039    }
1040}
1041
1042/**
1043 * Represents string value
1044 */
1045export final class StringValue extends Value {
1046    private typ: StringType
1047    private data: string
1048
1049    public override getType(): Type {
1050        return this.typ as Type
1051    }
1052
1053    public override getData(): NullishType {
1054        return this.data
1055    }
1056
1057    internal constructor(typ: StringType, data: String) {
1058        this.typ = typ
1059        this.data = data
1060    }
1061
1062    public override toPrint(depth: int): string {
1063        return new StringBuilder("\"").append(this.data).append("\"").toString()
1064    }
1065
1066    public override toString(): string {
1067        return new StringBuilder("\"").append(this.data).append("\"").toString()
1068    }
1069
1070    public override toLocaleString(): string {
1071        return this.toString()
1072    }
1073}
1074
1075/**
1076 * Represents null value
1077 */
1078export final class NullValue extends Value {
1079    public static readonly INSTANCE = new NullValue()
1080
1081    public override getType(): Type {
1082        return NullType.REF as Type
1083    }
1084
1085    public override getData(): NullishType {
1086        return null
1087    }
1088
1089    internal constructor() {}
1090
1091    public override toPrint(depth: int): string {
1092        return NullType.REF.toString()
1093    }
1094
1095    public override toString(): string {
1096        return NullType.REF.toString()
1097    }
1098
1099    public override toLocaleString(): string {
1100        return this.toString()
1101    }
1102}
1103
1104/**
1105 * Represents undefined value
1106 */
1107export final class UndefinedValue extends Value {
1108    public static readonly INSTANCE = new UndefinedValue()
1109
1110    public override getType(): Type {
1111        return UndefinedType.REF as Type
1112    }
1113
1114    public override getData(): NullishType {
1115        return undefined
1116    }
1117
1118    internal constructor() {}
1119
1120    public override toPrint(depth: int): string {
1121        return UndefinedType.REF.toString()
1122    }
1123
1124    public override toString(): string {
1125        return UndefinedType.REF.toString()
1126    }
1127
1128    public override toLocaleString(): string {
1129        return this.toString()
1130    }
1131}
1132
1133/**
1134 * Represents void value
1135 */
1136export final class VoidValue extends Value {
1137    public static readonly INSTANCE = new VoidValue()
1138
1139    public override getType(): Type {
1140        return VoidType.REF as Type
1141    }
1142
1143    public override getData(): NullishType {
1144        return Void.void_instance
1145    }
1146
1147    internal constructor() {}
1148
1149    public override toPrint(depth: int): string {
1150        return VoidType.REF.toString()
1151    }
1152
1153    public override toString(): string {
1154        return VoidType.REF.toString()
1155    }
1156
1157    public override toLocaleString(): string {
1158        return this.toString()
1159    }
1160}
1161