@ugo-studio/jspp 0.3.2 → 0.3.4
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/README.md +2 -6
- package/dist/cli/args.js +5 -0
- package/dist/cli/compiler.js +1 -1
- package/dist/cli/index.js +4 -2
- package/dist/interpreter/analysis/typeAnalyzer.js +62 -25
- package/dist/interpreter/core/codegen/control-flow-handlers.js +34 -10
- package/dist/interpreter/core/codegen/expression-handlers.js +92 -21
- package/dist/interpreter/core/codegen/function-handlers.js +16 -11
- package/dist/interpreter/core/codegen/helpers.js +5 -1
- package/dist/interpreter/core/codegen/index.js +1 -1
- package/dist/interpreter/core/codegen/statement-handlers.js +15 -11
- package/dist/interpreter/core/traverser.js +1 -2
- package/package.json +2 -2
- package/scripts/precompile-headers.ts +9 -1
- package/src/prelude/library/array.cpp +2 -2
- package/src/prelude/library/math.cpp +8 -8
- package/src/prelude/utils/access.hpp +0 -34
- package/src/prelude/utils/assignment_operators.hpp +96 -0
- package/src/prelude/utils/operators.hpp +39 -4
- package/src/prelude/utils/operators_native.hpp +73 -62
- package/src/prelude/values/array.cpp +17 -17
- package/src/prelude/values/iterator.cpp +262 -210
- package/src/prelude/values/number.cpp +4 -4
- package/src/prelude/values/string.cpp +13 -13
|
@@ -2,210 +2,251 @@
|
|
|
2
2
|
#include "values/iterator.hpp"
|
|
3
3
|
#include "values/prototypes/iterator.hpp"
|
|
4
4
|
|
|
5
|
-
namespace jspp
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
template <typename T>
|
|
25
|
-
std::suspend_always JsIterator<T>::promise_type::initial_suspend() noexcept { return {}; }
|
|
26
|
-
|
|
27
|
-
template <typename T>
|
|
28
|
-
std::suspend_always JsIterator<T>::promise_type::final_suspend() noexcept { return {}; }
|
|
29
|
-
|
|
30
|
-
template <typename T>
|
|
31
|
-
void JsIterator<T>::promise_type::unhandled_exception() {
|
|
32
|
-
try {
|
|
33
|
-
throw;
|
|
34
|
-
} catch (const GeneratorReturnException&) {
|
|
35
|
-
} catch (...) {
|
|
36
|
-
exception_ = std::current_exception();
|
|
5
|
+
namespace jspp
|
|
6
|
+
{
|
|
7
|
+
|
|
8
|
+
template <typename T>
|
|
9
|
+
JsIterator<T>::JsIterator(handle_type h) : handle(h) {}
|
|
10
|
+
|
|
11
|
+
template <typename T>
|
|
12
|
+
JsIterator<T>::JsIterator(JsIterator &&other) noexcept
|
|
13
|
+
: handle(std::exchange(other.handle, nullptr)),
|
|
14
|
+
props(std::move(other.props)),
|
|
15
|
+
symbol_props(std::move(other.symbol_props)) {}
|
|
16
|
+
|
|
17
|
+
template <typename T>
|
|
18
|
+
JsIterator<T>::~JsIterator()
|
|
19
|
+
{
|
|
20
|
+
if (handle)
|
|
21
|
+
handle.destroy();
|
|
37
22
|
}
|
|
38
|
-
}
|
|
39
23
|
|
|
40
|
-
template <typename T>
|
|
41
|
-
|
|
24
|
+
template <typename T>
|
|
25
|
+
JsIterator<T> JsIterator<T>::promise_type::get_return_object()
|
|
26
|
+
{
|
|
27
|
+
return JsIterator{std::coroutine_handle<promise_type>::from_promise(*this)};
|
|
28
|
+
}
|
|
42
29
|
|
|
43
|
-
template <typename T>
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
template <typename T>
|
|
66
|
-
typename JsIterator<T>::NextResult JsIterator<T>::throw_(const AnyValue &err)
|
|
67
|
-
{
|
|
68
|
-
if (!handle || handle.done()) throw Exception(err);
|
|
69
|
-
handle.promise().pending_exception = std::make_exception_ptr(Exception(err));
|
|
70
|
-
handle.resume();
|
|
71
|
-
if (handle.promise().exception_) std::rethrow_exception(handle.promise().exception_);
|
|
72
|
-
bool is_done = handle.done();
|
|
73
|
-
return {handle.promise().current_value, is_done};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
template <typename T>
|
|
77
|
-
std::vector<T> JsIterator<T>::to_vector()
|
|
78
|
-
{
|
|
79
|
-
std::vector<T> result;
|
|
80
|
-
while (true) {
|
|
81
|
-
auto next_res = this->next();
|
|
82
|
-
if (next_res.done) break;
|
|
83
|
-
result.push_back(next_res.value.value_or(Constants::UNDEFINED));
|
|
30
|
+
template <typename T>
|
|
31
|
+
std::suspend_always JsIterator<T>::promise_type::initial_suspend() noexcept { return {}; }
|
|
32
|
+
|
|
33
|
+
template <typename T>
|
|
34
|
+
std::suspend_always JsIterator<T>::promise_type::final_suspend() noexcept { return {}; }
|
|
35
|
+
|
|
36
|
+
template <typename T>
|
|
37
|
+
void JsIterator<T>::promise_type::unhandled_exception()
|
|
38
|
+
{
|
|
39
|
+
try
|
|
40
|
+
{
|
|
41
|
+
throw;
|
|
42
|
+
}
|
|
43
|
+
catch (const GeneratorReturnException &)
|
|
44
|
+
{
|
|
45
|
+
}
|
|
46
|
+
catch (...)
|
|
47
|
+
{
|
|
48
|
+
exception_ = std::current_exception();
|
|
49
|
+
}
|
|
84
50
|
}
|
|
85
|
-
return result;
|
|
86
|
-
}
|
|
87
51
|
|
|
88
|
-
template <typename T>
|
|
89
|
-
|
|
52
|
+
template <typename T>
|
|
53
|
+
std::string JsIterator<T>::to_std_string() const { return "[object Generator]"; }
|
|
54
|
+
|
|
55
|
+
template <typename T>
|
|
56
|
+
typename JsIterator<T>::NextResult JsIterator<T>::next(const T &val)
|
|
57
|
+
{
|
|
58
|
+
if (!handle || handle.done())
|
|
59
|
+
return {std::nullopt, true};
|
|
60
|
+
handle.promise().input_value = val;
|
|
61
|
+
handle.resume();
|
|
62
|
+
if (handle.promise().exception_)
|
|
63
|
+
std::rethrow_exception(handle.promise().exception_);
|
|
64
|
+
bool is_done = handle.done();
|
|
65
|
+
return {handle.promise().current_value, is_done};
|
|
66
|
+
}
|
|
90
67
|
|
|
91
|
-
template <typename T>
|
|
92
|
-
|
|
93
|
-
{
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
68
|
+
template <typename T>
|
|
69
|
+
typename JsIterator<T>::NextResult JsIterator<T>::return_(const T &val)
|
|
70
|
+
{
|
|
71
|
+
if (!handle || handle.done())
|
|
72
|
+
return {val, true};
|
|
73
|
+
handle.promise().pending_return = true;
|
|
74
|
+
handle.promise().current_value = val;
|
|
75
|
+
handle.resume();
|
|
76
|
+
if (handle.promise().exception_)
|
|
77
|
+
std::rethrow_exception(handle.promise().exception_);
|
|
78
|
+
return {handle.promise().current_value, true};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
template <typename T>
|
|
82
|
+
typename JsIterator<T>::NextResult JsIterator<T>::throw_(const AnyValue &err)
|
|
83
|
+
{
|
|
84
|
+
if (!handle || handle.done())
|
|
85
|
+
throw Exception(err);
|
|
86
|
+
handle.promise().pending_exception = std::make_exception_ptr(Exception(err));
|
|
87
|
+
handle.resume();
|
|
88
|
+
if (handle.promise().exception_)
|
|
89
|
+
std::rethrow_exception(handle.promise().exception_);
|
|
90
|
+
bool is_done = handle.done();
|
|
91
|
+
return {handle.promise().current_value, is_done};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
template <typename T>
|
|
95
|
+
std::vector<T> JsIterator<T>::to_vector()
|
|
96
|
+
{
|
|
97
|
+
std::vector<T> result;
|
|
98
|
+
while (true)
|
|
99
|
+
{
|
|
100
|
+
auto next_res = this->next();
|
|
101
|
+
if (next_res.done)
|
|
102
|
+
break;
|
|
103
|
+
result.push_back(next_res.value.value_or(Constants::UNDEFINED));
|
|
99
104
|
}
|
|
100
|
-
return
|
|
105
|
+
return result;
|
|
101
106
|
}
|
|
102
|
-
return AnyValue::resolve_property_for_read(it->second, thisVal, key);
|
|
103
|
-
}
|
|
104
107
|
|
|
105
|
-
template <typename T>
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
108
|
+
template <typename T>
|
|
109
|
+
bool JsIterator<T>::has_symbol_property(const AnyValue &key) const { return symbol_props.count(key) > 0; }
|
|
110
|
+
|
|
111
|
+
template <typename T>
|
|
112
|
+
AnyValue JsIterator<T>::get_property(const std::string &key, AnyValue thisVal)
|
|
113
|
+
{
|
|
114
|
+
auto it = props.find(key);
|
|
115
|
+
if (it == props.end())
|
|
116
|
+
{
|
|
117
|
+
if constexpr (std::is_same_v<T, AnyValue>)
|
|
118
|
+
{
|
|
119
|
+
auto proto_it = IteratorPrototypes::get(key);
|
|
120
|
+
if (proto_it.has_value())
|
|
121
|
+
return AnyValue::resolve_property_for_read(proto_it.value(), thisVal, key);
|
|
122
|
+
}
|
|
123
|
+
return Constants::UNDEFINED;
|
|
113
124
|
}
|
|
114
|
-
return
|
|
125
|
+
return AnyValue::resolve_property_for_read(it->second, thisVal, key);
|
|
115
126
|
}
|
|
116
|
-
return AnyValue::resolve_property_for_read(it->second, thisVal, key.to_std_string());
|
|
117
|
-
}
|
|
118
127
|
|
|
119
|
-
template <typename T>
|
|
120
|
-
AnyValue JsIterator<T>::
|
|
121
|
-
{
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
template <typename T>
|
|
129
|
+
AnyValue JsIterator<T>::get_symbol_property(const AnyValue &key, AnyValue thisVal)
|
|
130
|
+
{
|
|
131
|
+
auto it = symbol_props.find(key);
|
|
132
|
+
if (it == symbol_props.end())
|
|
133
|
+
{
|
|
134
|
+
if constexpr (std::is_same_v<T, AnyValue>)
|
|
135
|
+
{
|
|
136
|
+
auto proto_it = IteratorPrototypes::get(key);
|
|
137
|
+
if (proto_it.has_value())
|
|
138
|
+
return AnyValue::resolve_property_for_read(proto_it.value(), thisVal, key.to_std_string());
|
|
139
|
+
}
|
|
140
|
+
return Constants::UNDEFINED;
|
|
128
141
|
}
|
|
142
|
+
return AnyValue::resolve_property_for_read(it->second, thisVal, key.to_std_string());
|
|
129
143
|
}
|
|
130
|
-
auto it = props.find(key);
|
|
131
|
-
if (it != props.end()) return jspp::AnyValue::resolve_property_for_write(it->second, thisVal, value, key);
|
|
132
|
-
else { props[key] = value; return value; }
|
|
133
|
-
}
|
|
134
144
|
|
|
135
|
-
template <typename T>
|
|
136
|
-
AnyValue JsIterator<T>::
|
|
137
|
-
{
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
145
|
+
template <typename T>
|
|
146
|
+
AnyValue JsIterator<T>::set_property(const std::string &key, AnyValue value, AnyValue thisVal)
|
|
147
|
+
{
|
|
148
|
+
if constexpr (std::is_same_v<T, AnyValue>)
|
|
149
|
+
{
|
|
150
|
+
auto proto_it = IteratorPrototypes::get(key);
|
|
151
|
+
if (proto_it.has_value())
|
|
152
|
+
{
|
|
153
|
+
auto proto_value = proto_it.value();
|
|
154
|
+
if (proto_value.is_accessor_descriptor())
|
|
155
|
+
return AnyValue::resolve_property_for_write(proto_value, thisVal, value, key);
|
|
156
|
+
if (proto_value.is_data_descriptor() && !proto_value.as_data_descriptor()->writable)
|
|
157
|
+
return AnyValue::resolve_property_for_write(proto_value, thisVal, value, key);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
auto it = props.find(key);
|
|
161
|
+
if (it != props.end())
|
|
162
|
+
return jspp::AnyValue::resolve_property_for_write(it->second, thisVal, value, key);
|
|
163
|
+
else
|
|
164
|
+
{
|
|
165
|
+
props[key] = value;
|
|
166
|
+
return value;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
142
169
|
|
|
143
|
-
|
|
144
|
-
|
|
170
|
+
template <typename T>
|
|
171
|
+
AnyValue JsIterator<T>::set_symbol_property(const AnyValue &key, AnyValue value, AnyValue thisVal)
|
|
172
|
+
{
|
|
173
|
+
auto it = symbol_props.find(key);
|
|
174
|
+
if (it != symbol_props.end())
|
|
175
|
+
return AnyValue::resolve_property_for_write(it->second, thisVal, value, key.to_std_string());
|
|
176
|
+
else
|
|
177
|
+
{
|
|
178
|
+
symbol_props[key] = value;
|
|
179
|
+
return value;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
145
182
|
|
|
146
|
-
|
|
183
|
+
// Explicit template instantiation
|
|
184
|
+
template class JsIterator<AnyValue>;
|
|
147
185
|
|
|
148
|
-
|
|
149
|
-
{
|
|
150
|
-
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
151
|
-
{ return AnyValue::make_string(thisVal.as_iterator()->to_std_string()); },
|
|
152
|
-
"toString");
|
|
153
|
-
return fn;
|
|
154
|
-
}
|
|
186
|
+
namespace IteratorPrototypes
|
|
187
|
+
{
|
|
155
188
|
|
|
156
|
-
AnyValue &
|
|
157
|
-
{
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
189
|
+
AnyValue &get_toString_fn()
|
|
190
|
+
{
|
|
191
|
+
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
192
|
+
{ return AnyValue::make_string(thisVal.as_iterator()->to_std_string()); },
|
|
193
|
+
"toString");
|
|
194
|
+
return fn;
|
|
195
|
+
}
|
|
163
196
|
|
|
164
|
-
AnyValue &
|
|
165
|
-
{
|
|
166
|
-
|
|
167
|
-
|
|
197
|
+
AnyValue &get_iterator_fn()
|
|
198
|
+
{
|
|
199
|
+
static AnyValue fn = AnyValue::make_generator([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
200
|
+
{ return thisVal; },
|
|
201
|
+
"Symbol.iterator");
|
|
202
|
+
return fn;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
AnyValue &get_next_fn()
|
|
206
|
+
{
|
|
207
|
+
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
208
|
+
{
|
|
168
209
|
AnyValue val = args.empty() ? Constants::UNDEFINED : args[0];
|
|
169
210
|
auto res = thisVal.as_iterator()->next(val);
|
|
170
211
|
return AnyValue::make_object({{"value", res.value.value_or(Constants::UNDEFINED)}, {"done", AnyValue::make_boolean(res.done)}}); },
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
212
|
+
"next");
|
|
213
|
+
return fn;
|
|
214
|
+
}
|
|
174
215
|
|
|
175
|
-
AnyValue &get_return_fn()
|
|
176
|
-
{
|
|
177
|
-
|
|
178
|
-
|
|
216
|
+
AnyValue &get_return_fn()
|
|
217
|
+
{
|
|
218
|
+
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
219
|
+
{
|
|
179
220
|
AnyValue val = args.empty() ? Constants::UNDEFINED : args[0];
|
|
180
221
|
auto res = thisVal.as_iterator()->return_(val);
|
|
181
222
|
return AnyValue::make_object({{"value", res.value.value_or(Constants::UNDEFINED)}, {"done", AnyValue::make_boolean(res.done)}}); },
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
223
|
+
"return");
|
|
224
|
+
return fn;
|
|
225
|
+
}
|
|
185
226
|
|
|
186
|
-
AnyValue &get_throw_fn()
|
|
187
|
-
{
|
|
188
|
-
|
|
189
|
-
|
|
227
|
+
AnyValue &get_throw_fn()
|
|
228
|
+
{
|
|
229
|
+
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
230
|
+
{
|
|
190
231
|
AnyValue err = args.empty() ? Constants::UNDEFINED : args[0];
|
|
191
232
|
auto res = thisVal.as_iterator()->throw_(err);
|
|
192
233
|
return AnyValue::make_object({{"value", res.value.value_or(Constants::UNDEFINED)}, {"done", AnyValue::make_boolean(res.done)}}); },
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
234
|
+
"throw");
|
|
235
|
+
return fn;
|
|
236
|
+
}
|
|
196
237
|
|
|
197
|
-
AnyValue &get_toArray_fn()
|
|
198
|
-
{
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
238
|
+
AnyValue &get_toArray_fn()
|
|
239
|
+
{
|
|
240
|
+
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
241
|
+
{ return AnyValue::make_array(thisVal.as_iterator()->to_vector()); },
|
|
242
|
+
"toArray");
|
|
243
|
+
return fn;
|
|
244
|
+
}
|
|
204
245
|
|
|
205
|
-
AnyValue &get_drop_fn()
|
|
206
|
-
{
|
|
207
|
-
|
|
208
|
-
|
|
246
|
+
AnyValue &get_drop_fn()
|
|
247
|
+
{
|
|
248
|
+
static AnyValue fn = AnyValue::make_generator([](AnyValue thisVal, std::vector<AnyValue> args) -> JsIterator<AnyValue>
|
|
249
|
+
{
|
|
209
250
|
auto self = thisVal.as_iterator();
|
|
210
251
|
size_t skip_count = 0;
|
|
211
252
|
if (!args.empty()) {
|
|
@@ -224,14 +265,14 @@ AnyValue &get_drop_fn()
|
|
|
224
265
|
co_yield next_res.value.value_or(Constants::UNDEFINED);
|
|
225
266
|
}
|
|
226
267
|
co_return jspp::Constants::UNDEFINED; },
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}
|
|
268
|
+
"drop");
|
|
269
|
+
return fn;
|
|
270
|
+
}
|
|
230
271
|
|
|
231
|
-
AnyValue &get_take_fn()
|
|
232
|
-
{
|
|
233
|
-
|
|
234
|
-
|
|
272
|
+
AnyValue &get_take_fn()
|
|
273
|
+
{
|
|
274
|
+
static AnyValue fn = AnyValue::make_generator([](AnyValue thisVal, std::vector<AnyValue> args) -> JsIterator<AnyValue>
|
|
275
|
+
{
|
|
235
276
|
auto self = thisVal.as_iterator();
|
|
236
277
|
size_t take_count = 0;
|
|
237
278
|
if (!args.empty()) {
|
|
@@ -254,14 +295,14 @@ AnyValue &get_take_fn()
|
|
|
254
295
|
}
|
|
255
296
|
}
|
|
256
297
|
co_return jspp::Constants::UNDEFINED; },
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
}
|
|
298
|
+
"take");
|
|
299
|
+
return fn;
|
|
300
|
+
}
|
|
260
301
|
|
|
261
|
-
AnyValue &get_some_fn()
|
|
262
|
-
{
|
|
263
|
-
|
|
264
|
-
|
|
302
|
+
AnyValue &get_some_fn()
|
|
303
|
+
{
|
|
304
|
+
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
305
|
+
{
|
|
265
306
|
auto self = thisVal.as_iterator();
|
|
266
307
|
if (args.empty() || !args[0].is_function()) throw Exception::make_exception("callback is not a function", "TypeError");
|
|
267
308
|
auto callback = args[0].as_function();
|
|
@@ -269,7 +310,8 @@ AnyValue &get_some_fn()
|
|
|
269
310
|
{
|
|
270
311
|
auto next_res = self->next();
|
|
271
312
|
if (next_res.done) { break; }
|
|
272
|
-
|
|
313
|
+
AnyValue cb_arg = next_res.value.value_or(Constants::UNDEFINED);
|
|
314
|
+
if (is_truthy(callback->call(thisVal, std::span<const AnyValue>(&cb_arg, 1))))
|
|
273
315
|
{
|
|
274
316
|
self->return_();
|
|
275
317
|
return Constants::TRUE;
|
|
@@ -277,33 +319,43 @@ AnyValue &get_some_fn()
|
|
|
277
319
|
}
|
|
278
320
|
return jspp::Constants::FALSE; },
|
|
279
321
|
"some");
|
|
280
|
-
|
|
281
|
-
}
|
|
322
|
+
return fn;
|
|
323
|
+
}
|
|
282
324
|
|
|
283
|
-
std::optional<AnyValue> get(const std::string &key)
|
|
284
|
-
{
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
325
|
+
std::optional<AnyValue> get(const std::string &key)
|
|
326
|
+
{
|
|
327
|
+
if (key == "toString")
|
|
328
|
+
return get_toString_fn();
|
|
329
|
+
if (key == "next")
|
|
330
|
+
return get_next_fn();
|
|
331
|
+
if (key == "return")
|
|
332
|
+
return get_return_fn();
|
|
333
|
+
if (key == "throw")
|
|
334
|
+
return get_throw_fn();
|
|
335
|
+
if (key == "toArray")
|
|
336
|
+
return get_toArray_fn();
|
|
337
|
+
if (key == "drop")
|
|
338
|
+
return get_drop_fn();
|
|
339
|
+
if (key == "take")
|
|
340
|
+
return get_take_fn();
|
|
341
|
+
if (key == "some")
|
|
342
|
+
return get_some_fn();
|
|
343
|
+
return std::nullopt;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
std::optional<AnyValue> get(const AnyValue &key)
|
|
347
|
+
{
|
|
348
|
+
if (key.is_string())
|
|
349
|
+
return get(key.as_string()->value);
|
|
300
350
|
|
|
301
|
-
|
|
302
|
-
|
|
351
|
+
if (key == AnyValue::from_symbol(WellKnownSymbols::toStringTag))
|
|
352
|
+
return get_toString_fn();
|
|
353
|
+
if (key == AnyValue::from_symbol(WellKnownSymbols::iterator))
|
|
354
|
+
return get_iterator_fn();
|
|
303
355
|
|
|
304
|
-
|
|
305
|
-
}
|
|
356
|
+
return std::nullopt;
|
|
357
|
+
}
|
|
306
358
|
|
|
307
|
-
} // namespace IteratorPrototypes
|
|
359
|
+
} // namespace IteratorPrototypes
|
|
308
360
|
|
|
309
361
|
} // namespace jspp
|
|
@@ -87,7 +87,7 @@ namespace jspp
|
|
|
87
87
|
int digits = -1;
|
|
88
88
|
if (!args.empty() && !args[0].is_undefined())
|
|
89
89
|
{
|
|
90
|
-
digits =
|
|
90
|
+
digits = NumberOperators::ToInt32(args[0]);
|
|
91
91
|
if (digits < 0 || digits > 100)
|
|
92
92
|
{
|
|
93
93
|
throw Exception::make_exception("toExponential() digits argument must be between 0 and 100", "RangeError");
|
|
@@ -118,7 +118,7 @@ namespace jspp
|
|
|
118
118
|
int digits = 0;
|
|
119
119
|
if (!args.empty() && !args[0].is_undefined())
|
|
120
120
|
{
|
|
121
|
-
digits =
|
|
121
|
+
digits = NumberOperators::ToInt32(args[0]);
|
|
122
122
|
}
|
|
123
123
|
if (digits < 0 || digits > 100)
|
|
124
124
|
{
|
|
@@ -141,7 +141,7 @@ namespace jspp
|
|
|
141
141
|
{
|
|
142
142
|
return AnyValue::make_number(self).get_own_property("toString").call(AnyValue::make_number(self), {}, "toString");
|
|
143
143
|
}
|
|
144
|
-
int precision =
|
|
144
|
+
int precision = NumberOperators::ToInt32(args[0]);
|
|
145
145
|
if (precision < 1 || precision > 100)
|
|
146
146
|
{
|
|
147
147
|
throw Exception::make_exception("toPrecision() precision argument must be between 1 and 100", "RangeError");
|
|
@@ -162,7 +162,7 @@ namespace jspp
|
|
|
162
162
|
int radix = 10;
|
|
163
163
|
if (!args.empty() && !args[0].is_undefined())
|
|
164
164
|
{
|
|
165
|
-
radix =
|
|
165
|
+
radix = NumberOperators::ToInt32(args[0]);
|
|
166
166
|
}
|
|
167
167
|
if (radix < 2 || radix > 36)
|
|
168
168
|
{
|