@ugo-studio/jspp 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analysis/scope.js +17 -0
- package/dist/analysis/typeAnalyzer.js +7 -1
- package/dist/ast/symbols.js +29 -0
- package/dist/ast/types.js +0 -6
- package/dist/cli-utils/args.js +57 -0
- package/dist/cli-utils/colors.js +9 -0
- package/dist/cli-utils/file-utils.js +20 -0
- package/dist/cli-utils/spinner.js +55 -0
- package/dist/cli.js +105 -30
- package/dist/core/codegen/class-handlers.js +10 -6
- package/dist/core/codegen/control-flow-handlers.js +31 -21
- package/dist/core/codegen/declaration-handlers.js +10 -6
- package/dist/core/codegen/expression-handlers.js +202 -60
- package/dist/core/codegen/function-handlers.js +179 -70
- package/dist/core/codegen/helpers.js +107 -17
- package/dist/core/codegen/index.js +9 -8
- package/dist/core/codegen/literal-handlers.js +15 -6
- package/dist/core/codegen/statement-handlers.js +67 -53
- package/dist/core/codegen/visitor.js +3 -1
- package/package.json +1 -1
- package/src/prelude/any_value.hpp +195 -342
- package/src/prelude/any_value_access.hpp +78 -30
- package/src/prelude/any_value_defines.hpp +74 -35
- package/src/prelude/any_value_helpers.hpp +73 -180
- package/src/prelude/exception.hpp +1 -0
- package/src/prelude/exception_helpers.hpp +4 -4
- package/src/prelude/index.hpp +9 -2
- package/src/prelude/library/array.hpp +190 -0
- package/src/prelude/library/console.hpp +6 -5
- package/src/prelude/library/error.hpp +10 -8
- package/src/prelude/library/function.hpp +10 -0
- package/src/prelude/library/global.hpp +20 -0
- package/src/prelude/library/math.hpp +308 -0
- package/src/prelude/library/object.hpp +288 -0
- package/src/prelude/library/performance.hpp +1 -1
- package/src/prelude/library/process.hpp +39 -0
- package/src/prelude/library/promise.hpp +53 -43
- package/src/prelude/library/symbol.hpp +45 -57
- package/src/prelude/library/timer.hpp +6 -6
- package/src/prelude/types.hpp +48 -0
- package/src/prelude/utils/access.hpp +182 -11
- package/src/prelude/utils/assignment_operators.hpp +99 -0
- package/src/prelude/utils/log_any_value/array.hpp +8 -8
- package/src/prelude/utils/log_any_value/function.hpp +6 -4
- package/src/prelude/utils/log_any_value/object.hpp +41 -24
- package/src/prelude/utils/log_any_value/primitives.hpp +3 -1
- package/src/prelude/utils/operators.hpp +750 -274
- package/src/prelude/utils/well_known_symbols.hpp +12 -0
- package/src/prelude/values/array.hpp +8 -6
- package/src/prelude/values/descriptors.hpp +2 -2
- package/src/prelude/values/function.hpp +71 -62
- package/src/prelude/values/helpers/array.hpp +64 -28
- package/src/prelude/values/helpers/function.hpp +77 -92
- package/src/prelude/values/helpers/iterator.hpp +3 -3
- package/src/prelude/values/helpers/object.hpp +54 -9
- package/src/prelude/values/helpers/promise.hpp +3 -3
- package/src/prelude/values/iterator.hpp +1 -1
- package/src/prelude/values/object.hpp +10 -3
- package/src/prelude/values/promise.hpp +3 -3
- package/src/prelude/values/prototypes/array.hpp +851 -12
- package/src/prelude/values/prototypes/function.hpp +2 -2
- package/src/prelude/values/prototypes/iterator.hpp +5 -5
- package/src/prelude/values/prototypes/number.hpp +153 -0
- package/src/prelude/values/prototypes/object.hpp +2 -2
- package/src/prelude/values/prototypes/promise.hpp +40 -30
- package/src/prelude/values/prototypes/string.hpp +28 -28
- package/src/prelude/values/prototypes/symbol.hpp +20 -3
- package/src/prelude/values/shape.hpp +52 -0
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
#include <cmath>
|
|
18
18
|
#include <optional>
|
|
19
19
|
#include <coroutine>
|
|
20
|
+
#include <variant>
|
|
20
21
|
|
|
21
22
|
#include "types.hpp"
|
|
22
23
|
#include "values/non_values.hpp"
|
|
@@ -27,8 +28,8 @@
|
|
|
27
28
|
#include "values/promise.hpp"
|
|
28
29
|
#include "values/symbol.hpp"
|
|
29
30
|
#include "values/string.hpp"
|
|
30
|
-
#include "exception.hpp"
|
|
31
31
|
#include "values/descriptors.hpp"
|
|
32
|
+
#include "exception.hpp"
|
|
32
33
|
#include "utils/well_known_symbols.hpp"
|
|
33
34
|
|
|
34
35
|
namespace jspp
|
|
@@ -51,443 +52,298 @@ namespace jspp
|
|
|
51
52
|
AccessorDescriptor = 13,
|
|
52
53
|
};
|
|
53
54
|
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
std::shared_ptr<JsSymbol> symbol;
|
|
71
|
-
std::shared_ptr<JsPromise> promise;
|
|
72
|
-
std::shared_ptr<DataDescriptor> data_desc;
|
|
73
|
-
std::shared_ptr<AccessorDescriptor> accessor_desc;
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
TaggedValue() noexcept : type(JsType::Undefined), undefined{} {}
|
|
77
|
-
~TaggedValue() {}
|
|
78
|
-
};
|
|
55
|
+
// The variant order MUST match JsType
|
|
56
|
+
using AnyValueVariant = std::variant<
|
|
57
|
+
JsUndefined,
|
|
58
|
+
JsNull,
|
|
59
|
+
JsUninitialized,
|
|
60
|
+
bool,
|
|
61
|
+
double,
|
|
62
|
+
std::shared_ptr<JsString>,
|
|
63
|
+
std::shared_ptr<JsObject>,
|
|
64
|
+
std::shared_ptr<JsArray>,
|
|
65
|
+
std::shared_ptr<JsFunction>,
|
|
66
|
+
std::shared_ptr<JsIterator<AnyValue>>,
|
|
67
|
+
std::shared_ptr<JsSymbol>,
|
|
68
|
+
std::shared_ptr<JsPromise>,
|
|
69
|
+
std::shared_ptr<DataDescriptor>,
|
|
70
|
+
std::shared_ptr<AccessorDescriptor>>;
|
|
79
71
|
|
|
80
72
|
class AnyValue
|
|
81
73
|
{
|
|
82
74
|
private:
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
void destroy_value() noexcept
|
|
86
|
-
{
|
|
87
|
-
switch (storage.type)
|
|
88
|
-
{
|
|
89
|
-
case JsType::String:
|
|
90
|
-
storage.str.~shared_ptr();
|
|
91
|
-
break;
|
|
92
|
-
case JsType::Object:
|
|
93
|
-
storage.object.~shared_ptr();
|
|
94
|
-
break;
|
|
95
|
-
case JsType::Array:
|
|
96
|
-
storage.array.~shared_ptr();
|
|
97
|
-
break;
|
|
98
|
-
case JsType::Function:
|
|
99
|
-
storage.function.~shared_ptr();
|
|
100
|
-
break;
|
|
101
|
-
case JsType::Iterator:
|
|
102
|
-
storage.iterator.~shared_ptr();
|
|
103
|
-
break;
|
|
104
|
-
case JsType::Symbol:
|
|
105
|
-
storage.symbol.~shared_ptr();
|
|
106
|
-
break;
|
|
107
|
-
case JsType::Promise:
|
|
108
|
-
storage.promise.~shared_ptr();
|
|
109
|
-
break;
|
|
110
|
-
case JsType::DataDescriptor:
|
|
111
|
-
storage.data_desc.~shared_ptr();
|
|
112
|
-
break;
|
|
113
|
-
case JsType::AccessorDescriptor:
|
|
114
|
-
storage.accessor_desc.~shared_ptr();
|
|
115
|
-
break;
|
|
116
|
-
default:
|
|
117
|
-
break;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
void reset_to_undefined() noexcept
|
|
122
|
-
{
|
|
123
|
-
destroy_value();
|
|
124
|
-
storage.type = JsType::Undefined;
|
|
125
|
-
storage.undefined = JsUndefined{};
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
void move_from(AnyValue &other) noexcept
|
|
129
|
-
{
|
|
130
|
-
storage.type = other.storage.type;
|
|
131
|
-
switch (other.storage.type)
|
|
132
|
-
{
|
|
133
|
-
case JsType::Undefined:
|
|
134
|
-
storage.undefined = JsUndefined{};
|
|
135
|
-
break;
|
|
136
|
-
case JsType::Null:
|
|
137
|
-
storage.null = JsNull{};
|
|
138
|
-
break;
|
|
139
|
-
case JsType::Uninitialized:
|
|
140
|
-
storage.uninitialized = JsUninitialized{};
|
|
141
|
-
break;
|
|
142
|
-
case JsType::Boolean:
|
|
143
|
-
storage.boolean = other.storage.boolean;
|
|
144
|
-
break;
|
|
145
|
-
case JsType::Number:
|
|
146
|
-
storage.number = other.storage.number;
|
|
147
|
-
break;
|
|
148
|
-
case JsType::String:
|
|
149
|
-
new (&storage.str) std::shared_ptr<JsString>(std::move(other.storage.str));
|
|
150
|
-
break;
|
|
151
|
-
case JsType::Object:
|
|
152
|
-
new (&storage.object) std::shared_ptr<JsObject>(std::move(other.storage.object));
|
|
153
|
-
break;
|
|
154
|
-
case JsType::Array:
|
|
155
|
-
new (&storage.array) std::shared_ptr<JsArray>(std::move(other.storage.array));
|
|
156
|
-
break;
|
|
157
|
-
case JsType::Function:
|
|
158
|
-
new (&storage.function) std::shared_ptr<JsFunction>(std::move(other.storage.function));
|
|
159
|
-
break;
|
|
160
|
-
case JsType::Iterator:
|
|
161
|
-
new (&storage.iterator) std::shared_ptr<JsIterator<AnyValue>>(std::move(other.storage.iterator));
|
|
162
|
-
break;
|
|
163
|
-
case JsType::Symbol:
|
|
164
|
-
new (&storage.symbol) std::shared_ptr<JsSymbol>(std::move(other.storage.symbol));
|
|
165
|
-
break;
|
|
166
|
-
case JsType::Promise:
|
|
167
|
-
new (&storage.promise) std::shared_ptr<JsPromise>(std::move(other.storage.promise));
|
|
168
|
-
break;
|
|
169
|
-
case JsType::DataDescriptor:
|
|
170
|
-
new (&storage.data_desc) std::shared_ptr<DataDescriptor>(std::move(other.storage.data_desc));
|
|
171
|
-
break;
|
|
172
|
-
case JsType::AccessorDescriptor:
|
|
173
|
-
new (&storage.accessor_desc) std::shared_ptr<AccessorDescriptor>(std::move(other.storage.accessor_desc));
|
|
174
|
-
break;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
void copy_from(const AnyValue &other)
|
|
179
|
-
{
|
|
180
|
-
storage.type = other.storage.type;
|
|
181
|
-
switch (other.storage.type)
|
|
182
|
-
{
|
|
183
|
-
case JsType::Undefined:
|
|
184
|
-
storage.undefined = JsUndefined{};
|
|
185
|
-
break;
|
|
186
|
-
case JsType::Null:
|
|
187
|
-
storage.null = JsNull{};
|
|
188
|
-
break;
|
|
189
|
-
case JsType::Uninitialized:
|
|
190
|
-
storage.uninitialized = JsUninitialized{};
|
|
191
|
-
break;
|
|
192
|
-
case JsType::Boolean:
|
|
193
|
-
storage.boolean = other.storage.boolean;
|
|
194
|
-
break;
|
|
195
|
-
case JsType::Number:
|
|
196
|
-
storage.number = other.storage.number;
|
|
197
|
-
break;
|
|
198
|
-
case JsType::String:
|
|
199
|
-
new (&storage.str) std::shared_ptr<JsString>(std::make_shared<JsString>(*other.storage.str));
|
|
200
|
-
break;
|
|
201
|
-
case JsType::Object:
|
|
202
|
-
new (&storage.object) std::shared_ptr<JsObject>(other.storage.object); // shallow copy
|
|
203
|
-
break;
|
|
204
|
-
case JsType::Array:
|
|
205
|
-
new (&storage.array) std::shared_ptr<JsArray>(other.storage.array); // shallow copy
|
|
206
|
-
break;
|
|
207
|
-
case JsType::Function:
|
|
208
|
-
new (&storage.function) std::shared_ptr<JsFunction>(other.storage.function); // shallow copy
|
|
209
|
-
break;
|
|
210
|
-
case JsType::Iterator:
|
|
211
|
-
new (&storage.iterator) std::shared_ptr<JsIterator<AnyValue>>(other.storage.iterator); // shallow copy
|
|
212
|
-
break;
|
|
213
|
-
case JsType::Symbol:
|
|
214
|
-
new (&storage.symbol) std::shared_ptr<JsSymbol>(other.storage.symbol); // shallow copy (shared)
|
|
215
|
-
break;
|
|
216
|
-
case JsType::Promise:
|
|
217
|
-
new (&storage.promise) std::shared_ptr<JsPromise>(other.storage.promise); // shallow copy
|
|
218
|
-
break;
|
|
219
|
-
case JsType::DataDescriptor:
|
|
220
|
-
new (&storage.data_desc) std::shared_ptr<DataDescriptor>(other.storage.data_desc); // shallow copy
|
|
221
|
-
break;
|
|
222
|
-
case JsType::AccessorDescriptor:
|
|
223
|
-
new (&storage.accessor_desc) std::shared_ptr<AccessorDescriptor>(other.storage.accessor_desc); // shallow copy
|
|
224
|
-
break;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
75
|
+
AnyValueVariant storage;
|
|
227
76
|
|
|
228
77
|
public:
|
|
229
78
|
// default ctor (Undefined)
|
|
230
|
-
AnyValue() noexcept
|
|
231
|
-
{
|
|
232
|
-
storage.type = JsType::Undefined;
|
|
233
|
-
storage.undefined = JsUndefined{};
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// 1. Destructor
|
|
237
|
-
~AnyValue() noexcept
|
|
238
|
-
{
|
|
239
|
-
destroy_value();
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// 2. Copy Constructor (deep copy)
|
|
243
|
-
AnyValue(const AnyValue &other)
|
|
244
|
-
{
|
|
245
|
-
copy_from(other);
|
|
246
|
-
}
|
|
79
|
+
AnyValue() noexcept = default;
|
|
247
80
|
|
|
248
|
-
//
|
|
249
|
-
AnyValue
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
destroy_value();
|
|
254
|
-
copy_from(other);
|
|
255
|
-
}
|
|
256
|
-
return *this;
|
|
257
|
-
}
|
|
81
|
+
// Copy/Move handled by std::variant
|
|
82
|
+
AnyValue(const AnyValue &) = default;
|
|
83
|
+
AnyValue(AnyValue &&) noexcept = default;
|
|
84
|
+
AnyValue &operator=(const AnyValue &) = default;
|
|
85
|
+
AnyValue &operator=(AnyValue &&) noexcept = default;
|
|
258
86
|
|
|
259
|
-
|
|
260
|
-
AnyValue(AnyValue &&other) noexcept
|
|
261
|
-
{
|
|
262
|
-
storage.type = JsType::Undefined;
|
|
263
|
-
storage.undefined = JsUndefined{};
|
|
264
|
-
move_from(other);
|
|
265
|
-
other.reset_to_undefined();
|
|
266
|
-
}
|
|
87
|
+
~AnyValue() = default;
|
|
267
88
|
|
|
268
|
-
//
|
|
269
|
-
AnyValue &operator=(
|
|
89
|
+
// Assignments
|
|
90
|
+
AnyValue &operator=(const double &val)
|
|
270
91
|
{
|
|
271
|
-
|
|
272
|
-
{
|
|
273
|
-
destroy_value();
|
|
274
|
-
move_from(other);
|
|
275
|
-
other.reset_to_undefined();
|
|
276
|
-
}
|
|
92
|
+
storage = val;
|
|
277
93
|
return *this;
|
|
278
|
-
}
|
|
94
|
+
};
|
|
279
95
|
|
|
280
96
|
friend void swap(AnyValue &a, AnyValue &b) noexcept
|
|
281
97
|
{
|
|
282
|
-
|
|
283
|
-
a = std::move(b);
|
|
284
|
-
b = std::move(tmp);
|
|
98
|
+
std::swap(a.storage, b.storage);
|
|
285
99
|
}
|
|
286
100
|
|
|
101
|
+
// --- FRIENDS for Optimized Operators
|
|
102
|
+
friend AnyValue &operator+=(AnyValue &lhs, const AnyValue &rhs);
|
|
103
|
+
friend AnyValue &operator-=(AnyValue &lhs, const AnyValue &rhs);
|
|
104
|
+
friend AnyValue &operator*=(AnyValue &lhs, const AnyValue &rhs);
|
|
105
|
+
friend AnyValue &operator/=(AnyValue &lhs, const AnyValue &rhs);
|
|
106
|
+
friend AnyValue &operator%=(AnyValue &lhs, const AnyValue &rhs);
|
|
107
|
+
friend AnyValue &operator++(AnyValue &val);
|
|
108
|
+
friend AnyValue operator++(AnyValue &val, int);
|
|
109
|
+
friend AnyValue &operator--(AnyValue &val);
|
|
110
|
+
friend AnyValue operator--(AnyValue &val, int);
|
|
111
|
+
|
|
287
112
|
// factories -------------------------------------------------------
|
|
288
113
|
static AnyValue make_number(double d) noexcept
|
|
289
114
|
{
|
|
290
115
|
AnyValue v;
|
|
291
|
-
v.storage
|
|
292
|
-
v.storage.number = d;
|
|
116
|
+
v.storage = d;
|
|
293
117
|
return v;
|
|
294
118
|
}
|
|
295
119
|
static AnyValue make_nan() noexcept
|
|
296
120
|
{
|
|
297
121
|
AnyValue v;
|
|
298
|
-
v.storage
|
|
299
|
-
v.storage.number = std::numeric_limits<double>::quiet_NaN();
|
|
122
|
+
v.storage = std::numeric_limits<double>::quiet_NaN();
|
|
300
123
|
return v;
|
|
301
124
|
}
|
|
302
125
|
static AnyValue make_uninitialized() noexcept
|
|
303
126
|
{
|
|
304
127
|
AnyValue v;
|
|
305
|
-
v.storage
|
|
306
|
-
v.storage.uninitialized = JsUninitialized{};
|
|
128
|
+
v.storage = JsUninitialized{};
|
|
307
129
|
return v;
|
|
308
130
|
}
|
|
309
131
|
static AnyValue make_undefined() noexcept
|
|
310
132
|
{
|
|
311
133
|
AnyValue v;
|
|
312
|
-
v.storage
|
|
313
|
-
v.storage.undefined = JsUndefined{};
|
|
134
|
+
v.storage = JsUndefined{};
|
|
314
135
|
return v;
|
|
315
136
|
}
|
|
316
137
|
static AnyValue make_null() noexcept
|
|
317
138
|
{
|
|
318
139
|
AnyValue v;
|
|
319
|
-
v.storage
|
|
320
|
-
v.storage.null = JsNull{};
|
|
140
|
+
v.storage = JsNull{};
|
|
321
141
|
return v;
|
|
322
142
|
}
|
|
323
143
|
static AnyValue make_boolean(bool b) noexcept
|
|
324
144
|
{
|
|
325
145
|
AnyValue v;
|
|
326
|
-
v.storage
|
|
327
|
-
v.storage.boolean = b;
|
|
146
|
+
v.storage = b;
|
|
328
147
|
return v;
|
|
329
148
|
}
|
|
330
149
|
static AnyValue make_string(const std::string &raw_s) noexcept
|
|
331
150
|
{
|
|
332
151
|
AnyValue v;
|
|
333
|
-
v.storage
|
|
334
|
-
|
|
152
|
+
v.storage = std::make_shared<JsString>(raw_s);
|
|
153
|
+
return v;
|
|
154
|
+
}
|
|
155
|
+
static AnyValue make_object(std::initializer_list<std::pair<std::string, AnyValue>> props) noexcept
|
|
156
|
+
{
|
|
157
|
+
AnyValue v;
|
|
158
|
+
v.storage = std::make_shared<JsObject>(props);
|
|
335
159
|
return v;
|
|
336
160
|
}
|
|
337
161
|
static AnyValue make_object(const std::map<std::string, AnyValue> &props) noexcept
|
|
338
162
|
{
|
|
339
163
|
AnyValue v;
|
|
340
|
-
v.storage
|
|
341
|
-
|
|
164
|
+
v.storage = std::make_shared<JsObject>(props);
|
|
165
|
+
return v;
|
|
166
|
+
}
|
|
167
|
+
static AnyValue make_object_with_proto(std::initializer_list<std::pair<std::string, AnyValue>> props, const AnyValue &proto) noexcept
|
|
168
|
+
{
|
|
169
|
+
AnyValue v;
|
|
170
|
+
auto protoPtr = std::make_shared<AnyValue>(proto);
|
|
171
|
+
v.storage = std::make_shared<JsObject>(props, protoPtr);
|
|
342
172
|
return v;
|
|
343
173
|
}
|
|
344
174
|
static AnyValue make_object_with_proto(const std::map<std::string, AnyValue> &props, const AnyValue &proto) noexcept
|
|
345
175
|
{
|
|
346
176
|
AnyValue v;
|
|
347
|
-
v.storage.type = JsType::Object;
|
|
348
177
|
auto protoPtr = std::make_shared<AnyValue>(proto);
|
|
349
|
-
|
|
178
|
+
v.storage = std::make_shared<JsObject>(props, protoPtr);
|
|
179
|
+
return v;
|
|
180
|
+
}
|
|
181
|
+
static AnyValue make_array(std::span<const AnyValue> dense) noexcept
|
|
182
|
+
{
|
|
183
|
+
AnyValue v;
|
|
184
|
+
std::vector<AnyValue> vec;
|
|
185
|
+
vec.reserve(dense.size());
|
|
186
|
+
for (const auto &item : dense)
|
|
187
|
+
vec.push_back(item);
|
|
188
|
+
v.storage = std::make_shared<JsArray>(std::move(vec));
|
|
189
|
+
return v;
|
|
190
|
+
}
|
|
191
|
+
static AnyValue make_array(const std::vector<AnyValue> &dense) noexcept
|
|
192
|
+
{
|
|
193
|
+
AnyValue v;
|
|
194
|
+
v.storage = std::make_shared<JsArray>(dense);
|
|
350
195
|
return v;
|
|
351
196
|
}
|
|
352
|
-
static AnyValue make_array(
|
|
197
|
+
static AnyValue make_array(std::vector<AnyValue> &&dense) noexcept
|
|
353
198
|
{
|
|
354
199
|
AnyValue v;
|
|
355
|
-
v.storage
|
|
356
|
-
new (&v.storage.array) std::shared_ptr<JsArray>(std::make_shared<JsArray>(dense));
|
|
200
|
+
v.storage = std::make_shared<JsArray>(std::move(dense));
|
|
357
201
|
return v;
|
|
358
202
|
}
|
|
359
|
-
static AnyValue
|
|
203
|
+
static AnyValue make_array_with_proto(std::span<const AnyValue> dense, const AnyValue &proto) noexcept
|
|
360
204
|
{
|
|
361
205
|
AnyValue v;
|
|
362
|
-
|
|
363
|
-
|
|
206
|
+
std::vector<AnyValue> vec;
|
|
207
|
+
vec.reserve(dense.size());
|
|
208
|
+
for (const auto &item : dense)
|
|
209
|
+
vec.push_back(item);
|
|
210
|
+
v.storage = std::make_shared<JsArray>(std::move(vec));
|
|
211
|
+
std::get<std::shared_ptr<JsArray>>(v.storage)->proto = std::make_shared<AnyValue>(proto);
|
|
364
212
|
return v;
|
|
365
213
|
}
|
|
366
|
-
static AnyValue
|
|
214
|
+
static AnyValue make_array_with_proto(const std::vector<AnyValue> &dense, const AnyValue &proto) noexcept
|
|
367
215
|
{
|
|
368
216
|
AnyValue v;
|
|
369
|
-
v.storage
|
|
370
|
-
|
|
217
|
+
v.storage = std::make_shared<JsArray>(dense);
|
|
218
|
+
std::get<std::shared_ptr<JsArray>>(v.storage)->proto = std::make_shared<AnyValue>(proto);
|
|
219
|
+
return v;
|
|
220
|
+
}
|
|
221
|
+
static AnyValue make_function(const JsFunctionCallable &call, const std::optional<std::string> &name = std::nullopt, bool is_constructor = true) noexcept
|
|
222
|
+
{
|
|
223
|
+
AnyValue v;
|
|
224
|
+
v.storage = std::make_shared<JsFunction>(call, name, std::unordered_map<std::string, AnyValue>{}, false, is_constructor);
|
|
371
225
|
|
|
372
226
|
auto proto = make_object({});
|
|
373
|
-
proto.
|
|
374
|
-
v.
|
|
227
|
+
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
228
|
+
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
375
229
|
|
|
376
230
|
return v;
|
|
377
231
|
}
|
|
378
|
-
static AnyValue make_class(const JsFunctionCallable &call, const std::string &name) noexcept
|
|
232
|
+
static AnyValue make_class(const JsFunctionCallable &call, const std::optional<std::string> &name = std::nullopt) noexcept
|
|
379
233
|
{
|
|
380
234
|
AnyValue v;
|
|
381
|
-
v.storage.type = JsType::Function;
|
|
382
235
|
// use Constructor A with is_cls = true
|
|
383
|
-
|
|
236
|
+
v.storage = std::make_shared<JsFunction>(call, name, std::unordered_map<std::string, AnyValue>{}, true);
|
|
384
237
|
|
|
385
238
|
auto proto = make_object({});
|
|
386
|
-
proto.
|
|
387
|
-
v.
|
|
239
|
+
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
240
|
+
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
388
241
|
|
|
389
242
|
return v;
|
|
390
243
|
}
|
|
391
|
-
static AnyValue make_generator(const JsFunctionCallable &call, const std::string &name) noexcept
|
|
244
|
+
static AnyValue make_generator(const JsFunctionCallable &call, const std::optional<std::string> &name = std::nullopt) noexcept
|
|
392
245
|
{
|
|
393
246
|
AnyValue v;
|
|
394
|
-
v.storage.type = JsType::Function;
|
|
395
247
|
// use Constructor B with is_gen = true
|
|
396
|
-
|
|
248
|
+
v.storage = std::make_shared<JsFunction>(call, true, name);
|
|
397
249
|
|
|
398
250
|
auto proto = make_object({});
|
|
399
|
-
proto.
|
|
400
|
-
v.
|
|
251
|
+
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
252
|
+
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
401
253
|
|
|
402
254
|
return v;
|
|
403
255
|
}
|
|
404
|
-
static AnyValue make_async_function(const JsFunctionCallable &call, const std::string &name) noexcept
|
|
256
|
+
static AnyValue make_async_function(const JsFunctionCallable &call, const std::optional<std::string> &name = std::nullopt) noexcept
|
|
405
257
|
{
|
|
406
258
|
AnyValue v;
|
|
407
|
-
v.storage.type = JsType::Function;
|
|
408
259
|
// use Constructor C with is_async_func = true
|
|
409
|
-
|
|
260
|
+
v.storage = std::make_shared<JsFunction>(call, false, true, name);
|
|
410
261
|
|
|
411
262
|
auto proto = make_object({});
|
|
412
|
-
proto.
|
|
413
|
-
v.
|
|
263
|
+
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
264
|
+
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
265
|
+
|
|
266
|
+
return v;
|
|
267
|
+
}
|
|
268
|
+
static AnyValue make_async_generator(const JsFunctionCallable &call, const std::optional<std::string> &name = std::nullopt) noexcept
|
|
269
|
+
{
|
|
270
|
+
AnyValue v;
|
|
271
|
+
// use Constructor C with is_gen = true and is_async_func = true
|
|
272
|
+
v.storage = std::make_shared<JsFunction>(call, true, true, name);
|
|
273
|
+
|
|
274
|
+
auto proto = make_object({});
|
|
275
|
+
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
276
|
+
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
414
277
|
|
|
415
278
|
return v;
|
|
416
279
|
}
|
|
417
280
|
static AnyValue make_symbol(const std::string &description = "") noexcept
|
|
418
281
|
{
|
|
419
282
|
AnyValue v;
|
|
420
|
-
v.storage
|
|
421
|
-
new (&v.storage.symbol) std::shared_ptr<JsSymbol>(std::make_shared<JsSymbol>(description));
|
|
283
|
+
v.storage = std::make_shared<JsSymbol>(description);
|
|
422
284
|
return v;
|
|
423
285
|
}
|
|
424
286
|
static AnyValue make_promise(const JsPromise &promise) noexcept
|
|
425
287
|
{
|
|
426
288
|
AnyValue v;
|
|
427
|
-
v.storage
|
|
428
|
-
new (&v.storage.promise) std::shared_ptr<JsPromise>(std::make_shared<JsPromise>(promise));
|
|
289
|
+
v.storage = std::make_shared<JsPromise>(promise);
|
|
429
290
|
return v;
|
|
430
291
|
}
|
|
431
292
|
static AnyValue make_data_descriptor(const AnyValue &value, bool writable, bool enumerable, bool configurable) noexcept
|
|
432
293
|
{
|
|
433
294
|
AnyValue v;
|
|
434
|
-
v.storage
|
|
435
|
-
new (&v.storage.data_desc) std::shared_ptr<DataDescriptor>(std::make_shared<DataDescriptor>(std::make_shared<AnyValue>(value), writable, enumerable, configurable));
|
|
295
|
+
v.storage = std::make_shared<DataDescriptor>(std::make_shared<AnyValue>(value), writable, enumerable, configurable);
|
|
436
296
|
return v;
|
|
437
297
|
}
|
|
438
|
-
static AnyValue make_accessor_descriptor(const std::optional<std::function<AnyValue(const AnyValue &,
|
|
439
|
-
const std::optional<std::function<AnyValue(const AnyValue &,
|
|
298
|
+
static AnyValue make_accessor_descriptor(const std::optional<std::function<AnyValue(const AnyValue &, std::span<const AnyValue>)>> &get,
|
|
299
|
+
const std::optional<std::function<AnyValue(const AnyValue &, std::span<const AnyValue>)>> &set,
|
|
440
300
|
bool enumerable,
|
|
441
301
|
bool configurable) noexcept
|
|
442
302
|
{
|
|
443
303
|
AnyValue v;
|
|
444
|
-
v.storage
|
|
445
|
-
new (&v.storage.accessor_desc) std::shared_ptr<AccessorDescriptor>(std::make_shared<AccessorDescriptor>(get, set, enumerable, configurable));
|
|
304
|
+
v.storage = std::make_shared<AccessorDescriptor>(get, set, enumerable, configurable);
|
|
446
305
|
return v;
|
|
447
306
|
}
|
|
448
307
|
|
|
449
308
|
static AnyValue from_symbol(std::shared_ptr<JsSymbol> sym) noexcept
|
|
450
309
|
{
|
|
451
310
|
AnyValue v;
|
|
452
|
-
v.storage
|
|
453
|
-
new (&v.storage.symbol) std::shared_ptr<JsSymbol>(std::move(sym));
|
|
311
|
+
v.storage = std::move(sym);
|
|
454
312
|
return v;
|
|
455
313
|
}
|
|
456
314
|
static AnyValue from_string(std::shared_ptr<JsString> str) noexcept
|
|
457
315
|
{
|
|
458
316
|
AnyValue v;
|
|
459
|
-
v.storage
|
|
460
|
-
new (&v.storage.str) std::shared_ptr<JsString>(std::move(str));
|
|
317
|
+
v.storage = std::move(str);
|
|
461
318
|
return v;
|
|
462
319
|
}
|
|
463
320
|
static AnyValue from_iterator(JsIterator<AnyValue> &&iterator) noexcept
|
|
464
321
|
{
|
|
465
322
|
AnyValue v;
|
|
466
|
-
v.storage
|
|
467
|
-
new (&v.storage.iterator) std::shared_ptr<JsIterator<AnyValue>>(std::make_shared<JsIterator<AnyValue>>(std::move(iterator)));
|
|
323
|
+
v.storage = std::make_shared<JsIterator<AnyValue>>(std::move(iterator));
|
|
468
324
|
return v;
|
|
469
325
|
}
|
|
470
326
|
static AnyValue from_iterator_ref(JsIterator<AnyValue> *iterator) noexcept
|
|
471
327
|
{
|
|
472
328
|
AnyValue v;
|
|
473
|
-
v.storage
|
|
474
|
-
new (&v.storage.iterator) std::shared_ptr<JsIterator<AnyValue>>(iterator, [](JsIterator<AnyValue> *) {});
|
|
329
|
+
v.storage = std::shared_ptr<JsIterator<AnyValue>>(iterator, [](JsIterator<AnyValue> *) {});
|
|
475
330
|
return v;
|
|
476
331
|
}
|
|
477
332
|
|
|
478
333
|
// PROPERTY RESOLUTION HELPERS ---------------------------------------
|
|
479
334
|
static AnyValue resolve_property_for_read(const AnyValue &val, const AnyValue &thisVal, const std::string &propName) noexcept
|
|
480
335
|
{
|
|
481
|
-
switch (val.
|
|
336
|
+
switch (val.get_type())
|
|
482
337
|
{
|
|
483
338
|
case JsType::DataDescriptor:
|
|
484
339
|
{
|
|
485
|
-
return *(val.
|
|
340
|
+
return *(val.as_data_descriptor()->value);
|
|
486
341
|
}
|
|
487
342
|
case JsType::AccessorDescriptor:
|
|
488
343
|
{
|
|
489
|
-
|
|
490
|
-
|
|
344
|
+
const auto &accessor = val.as_accessor_descriptor();
|
|
345
|
+
if (accessor->get.has_value())
|
|
346
|
+
return accessor->get.value()(thisVal, std::span<const AnyValue>{});
|
|
491
347
|
else
|
|
492
348
|
{
|
|
493
349
|
static AnyValue undefined = AnyValue{};
|
|
@@ -502,13 +358,14 @@ namespace jspp
|
|
|
502
358
|
}
|
|
503
359
|
static AnyValue resolve_property_for_write(AnyValue &val, const AnyValue &thisVal, const AnyValue &new_val, const std::string &propName)
|
|
504
360
|
{
|
|
505
|
-
switch (val.
|
|
361
|
+
switch (val.get_type())
|
|
506
362
|
{
|
|
507
363
|
case JsType::DataDescriptor:
|
|
508
364
|
{
|
|
509
|
-
|
|
365
|
+
const auto &data = val.as_data_descriptor();
|
|
366
|
+
if (data->writable)
|
|
510
367
|
{
|
|
511
|
-
*(
|
|
368
|
+
*(data->value) = new_val;
|
|
512
369
|
return new_val;
|
|
513
370
|
}
|
|
514
371
|
else
|
|
@@ -518,9 +375,11 @@ namespace jspp
|
|
|
518
375
|
}
|
|
519
376
|
case JsType::AccessorDescriptor:
|
|
520
377
|
{
|
|
521
|
-
|
|
378
|
+
const auto &accessor = val.as_accessor_descriptor();
|
|
379
|
+
if (accessor->set.has_value())
|
|
522
380
|
{
|
|
523
|
-
|
|
381
|
+
const AnyValue args[] = {new_val};
|
|
382
|
+
accessor->set.value()(thisVal, args);
|
|
524
383
|
return new_val;
|
|
525
384
|
}
|
|
526
385
|
else
|
|
@@ -537,88 +396,77 @@ namespace jspp
|
|
|
537
396
|
}
|
|
538
397
|
|
|
539
398
|
// TYPE CHECKERS AND ACCESSORS ---------------------------------------
|
|
540
|
-
JsType get_type() const noexcept { return storage.
|
|
541
|
-
bool is_number() const noexcept { return storage.
|
|
542
|
-
bool is_string() const noexcept { return storage.
|
|
543
|
-
bool is_object() const noexcept { return storage.
|
|
544
|
-
bool is_array() const noexcept { return storage.
|
|
545
|
-
bool is_function() const noexcept { return storage.
|
|
546
|
-
bool is_iterator() const noexcept { return storage.
|
|
547
|
-
bool is_boolean() const noexcept { return storage.
|
|
548
|
-
bool is_symbol() const noexcept { return storage.
|
|
549
|
-
bool is_promise() const noexcept { return storage.
|
|
550
|
-
bool is_null() const noexcept { return storage.
|
|
551
|
-
bool is_undefined() const noexcept { return storage.
|
|
552
|
-
bool is_uninitialized() const noexcept { return storage.
|
|
553
|
-
bool is_data_descriptor() const noexcept { return storage.
|
|
554
|
-
bool is_accessor_descriptor() const noexcept { return storage.
|
|
555
|
-
bool is_generator() const noexcept { return
|
|
399
|
+
JsType get_type() const noexcept { return static_cast<JsType>(storage.index()); }
|
|
400
|
+
bool is_number() const noexcept { return storage.index() == 4; }
|
|
401
|
+
bool is_string() const noexcept { return storage.index() == 5; }
|
|
402
|
+
bool is_object() const noexcept { return storage.index() == 6; }
|
|
403
|
+
bool is_array() const noexcept { return storage.index() == 7; }
|
|
404
|
+
bool is_function() const noexcept { return storage.index() == 8; }
|
|
405
|
+
bool is_iterator() const noexcept { return storage.index() == 9; }
|
|
406
|
+
bool is_boolean() const noexcept { return storage.index() == 3; }
|
|
407
|
+
bool is_symbol() const noexcept { return storage.index() == 10; }
|
|
408
|
+
bool is_promise() const noexcept { return storage.index() == 11; }
|
|
409
|
+
bool is_null() const noexcept { return storage.index() == 1; }
|
|
410
|
+
bool is_undefined() const noexcept { return storage.index() == 0; }
|
|
411
|
+
bool is_uninitialized() const noexcept { return storage.index() == 2; }
|
|
412
|
+
bool is_data_descriptor() const noexcept { return storage.index() == 12; }
|
|
413
|
+
bool is_accessor_descriptor() const noexcept { return storage.index() == 13; }
|
|
414
|
+
bool is_generator() const noexcept { return is_function() && as_function()->is_generator; }
|
|
556
415
|
|
|
557
416
|
// --- TYPE CASTERS
|
|
558
417
|
double as_double() const noexcept
|
|
559
418
|
{
|
|
560
|
-
|
|
561
|
-
return storage.number;
|
|
419
|
+
return std::get<double>(storage);
|
|
562
420
|
}
|
|
563
421
|
bool as_boolean() const noexcept
|
|
564
422
|
{
|
|
565
|
-
|
|
566
|
-
return storage.boolean;
|
|
423
|
+
return std::get<bool>(storage);
|
|
567
424
|
}
|
|
568
425
|
JsString *as_string() const noexcept
|
|
569
426
|
{
|
|
570
|
-
|
|
571
|
-
return storage.str.get();
|
|
427
|
+
return std::get<std::shared_ptr<JsString>>(storage).get();
|
|
572
428
|
}
|
|
573
429
|
JsObject *as_object() const noexcept
|
|
574
430
|
{
|
|
575
|
-
|
|
576
|
-
return storage.object.get();
|
|
431
|
+
return std::get<std::shared_ptr<JsObject>>(storage).get();
|
|
577
432
|
}
|
|
578
433
|
JsArray *as_array() const noexcept
|
|
579
434
|
{
|
|
580
|
-
|
|
581
|
-
return storage.array.get();
|
|
435
|
+
return std::get<std::shared_ptr<JsArray>>(storage).get();
|
|
582
436
|
}
|
|
583
|
-
JsFunction *as_function(
|
|
437
|
+
JsFunction *as_function() const noexcept
|
|
584
438
|
{
|
|
585
|
-
|
|
586
|
-
return storage.function.get();
|
|
587
|
-
throw Exception::make_exception(expression.value_or(to_std_string()) + " is not a function", "TypeError");
|
|
439
|
+
return std::get<std::shared_ptr<JsFunction>>(storage).get();
|
|
588
440
|
}
|
|
589
441
|
JsSymbol *as_symbol() const noexcept
|
|
590
442
|
{
|
|
591
|
-
|
|
592
|
-
return storage.symbol.get();
|
|
443
|
+
return std::get<std::shared_ptr<JsSymbol>>(storage).get();
|
|
593
444
|
}
|
|
594
445
|
JsPromise *as_promise() const noexcept
|
|
595
446
|
{
|
|
596
|
-
|
|
597
|
-
return storage.promise.get();
|
|
447
|
+
return std::get<std::shared_ptr<JsPromise>>(storage).get();
|
|
598
448
|
}
|
|
599
449
|
std::shared_ptr<JsIterator<AnyValue>> as_iterator() const
|
|
600
450
|
{
|
|
601
|
-
|
|
602
|
-
return storage.iterator; // Returns the shared_ptr, incrementing ref count
|
|
451
|
+
return std::get<std::shared_ptr<JsIterator<AnyValue>>>(storage);
|
|
603
452
|
}
|
|
604
453
|
DataDescriptor *as_data_descriptor() const noexcept
|
|
605
454
|
{
|
|
606
|
-
|
|
607
|
-
return storage.data_desc.get();
|
|
455
|
+
return std::get<std::shared_ptr<DataDescriptor>>(storage).get();
|
|
608
456
|
}
|
|
609
457
|
AccessorDescriptor *as_accessor_descriptor() const noexcept
|
|
610
458
|
{
|
|
611
|
-
|
|
612
|
-
return storage.accessor_desc.get();
|
|
459
|
+
return std::get<std::shared_ptr<AccessorDescriptor>>(storage).get();
|
|
613
460
|
}
|
|
614
461
|
|
|
615
462
|
// --- CO_AWAIT Operator ---
|
|
616
463
|
auto operator co_await() const;
|
|
617
464
|
|
|
618
465
|
// --- PROPERTY ACCESS OPERATORS
|
|
466
|
+
bool has_property(const std::string &key) const;
|
|
619
467
|
AnyValue get_own_property(const std::string &key) const;
|
|
620
|
-
AnyValue get_own_property(uint32_t idx) const
|
|
621
|
-
AnyValue get_own_property(const AnyValue &key) const
|
|
468
|
+
AnyValue get_own_property(uint32_t idx) const;
|
|
469
|
+
AnyValue get_own_property(const AnyValue &key) const;
|
|
622
470
|
// for getting values with a specific receiver (used in inheritance chains)
|
|
623
471
|
AnyValue get_property_with_receiver(const std::string &key, const AnyValue &receiver) const;
|
|
624
472
|
// for setting values
|
|
@@ -636,18 +484,10 @@ namespace jspp
|
|
|
636
484
|
void define_setter(const AnyValue &key, const AnyValue &setter);
|
|
637
485
|
|
|
638
486
|
// --- HELPERS
|
|
639
|
-
const
|
|
640
|
-
const
|
|
641
|
-
const bool is_equal_to_primitive(const AnyValue &other) const noexcept;
|
|
642
|
-
|
|
643
|
-
const AnyValue is_strictly_equal_to(const AnyValue &other) const noexcept;
|
|
644
|
-
const AnyValue is_equal_to(const AnyValue &other) const noexcept;
|
|
645
|
-
const AnyValue not_strictly_equal_to(const AnyValue &other) const noexcept;
|
|
646
|
-
const AnyValue not_equal_to(const AnyValue &other) const noexcept;
|
|
647
|
-
|
|
648
|
-
const AnyValue construct(const std::vector<AnyValue> &args) const;
|
|
487
|
+
const AnyValue call(const AnyValue &thisVal, std::span<const AnyValue> args, const std::optional<std::string> &expr) const;
|
|
488
|
+
const AnyValue construct(std::span<const AnyValue> args, const std::optional<std::string> &name) const;
|
|
649
489
|
void set_prototype(const AnyValue &proto);
|
|
650
|
-
|
|
490
|
+
std::string to_std_string() const;
|
|
651
491
|
};
|
|
652
492
|
|
|
653
493
|
// Inline implementation of operator co_await
|
|
@@ -655,4 +495,17 @@ namespace jspp
|
|
|
655
495
|
{
|
|
656
496
|
return AnyValueAwaiter{*this};
|
|
657
497
|
}
|
|
658
|
-
|
|
498
|
+
|
|
499
|
+
// Global Constants for Optimization
|
|
500
|
+
namespace Constants
|
|
501
|
+
{
|
|
502
|
+
inline const AnyValue UNINITIALIZED = AnyValue::make_uninitialized();
|
|
503
|
+
inline const AnyValue UNDEFINED = AnyValue::make_undefined();
|
|
504
|
+
inline const AnyValue Null = AnyValue::make_null();
|
|
505
|
+
inline const AnyValue NaN = AnyValue::make_nan();
|
|
506
|
+
inline const AnyValue TRUE = AnyValue::make_boolean(true);
|
|
507
|
+
inline const AnyValue FALSE = AnyValue::make_boolean(false);
|
|
508
|
+
inline const AnyValue ZERO = AnyValue::make_number(0.0);
|
|
509
|
+
inline const AnyValue ONE = AnyValue::make_number(1.0);
|
|
510
|
+
}
|
|
511
|
+
}
|