@ugo-studio/jspp 0.2.9 → 0.3.0
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/core/codegen/class-handlers.js +6 -6
- package/dist/core/codegen/statement-handlers.js +1 -1
- package/package.json +1 -1
- package/src/prelude/any_value.hpp +362 -362
- package/src/prelude/any_value_access.hpp +170 -170
- package/src/prelude/any_value_defines.hpp +189 -189
- package/src/prelude/any_value_helpers.hpp +374 -374
- package/src/prelude/library/array.hpp +185 -185
- package/src/prelude/library/console.hpp +111 -111
- package/src/prelude/library/error.hpp +112 -112
- package/src/prelude/library/function.hpp +10 -10
- package/src/prelude/library/math.hpp +307 -307
- package/src/prelude/library/object.hpp +275 -275
- package/src/prelude/library/process.hpp +39 -39
- package/src/prelude/library/promise.hpp +123 -123
- package/src/prelude/library/symbol.hpp +52 -52
- package/src/prelude/library/timer.hpp +91 -91
- package/src/prelude/types.hpp +178 -178
- package/src/prelude/utils/access.hpp +411 -411
- package/src/prelude/utils/operators.hpp +336 -336
- package/src/prelude/values/array.hpp +0 -1
- package/src/prelude/values/async_iterator.hpp +83 -83
- package/src/prelude/values/function.hpp +82 -82
- package/src/prelude/values/helpers/array.hpp +198 -208
- package/src/prelude/values/helpers/async_iterator.hpp +275 -275
- package/src/prelude/values/helpers/function.hpp +108 -108
- package/src/prelude/values/helpers/iterator.hpp +144 -144
- package/src/prelude/values/helpers/promise.hpp +253 -253
- package/src/prelude/values/helpers/string.hpp +37 -61
- package/src/prelude/values/promise.hpp +72 -72
- package/src/prelude/values/prototypes/array.hpp +14 -2
- package/src/prelude/values/prototypes/iterator.hpp +201 -201
- package/src/prelude/values/prototypes/promise.hpp +196 -196
- package/src/prelude/values/prototypes/string.hpp +564 -542
- package/src/prelude/values/string.hpp +25 -26
|
@@ -1,72 +1,72 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#include "types.hpp"
|
|
4
|
-
#include "any_value.hpp"
|
|
5
|
-
#include <vector>
|
|
6
|
-
#include <functional>
|
|
7
|
-
#include <memory>
|
|
8
|
-
#include <variant>
|
|
9
|
-
#include <coroutine>
|
|
10
|
-
#include <unordered_map>
|
|
11
|
-
#include <string>
|
|
12
|
-
|
|
13
|
-
namespace jspp
|
|
14
|
-
{
|
|
15
|
-
// Forward declaration of AnyValue
|
|
16
|
-
class AnyValue;
|
|
17
|
-
|
|
18
|
-
enum class PromiseStatus { Pending, Fulfilled, Rejected };
|
|
19
|
-
|
|
20
|
-
struct PromiseState
|
|
21
|
-
{
|
|
22
|
-
PromiseStatus status = PromiseStatus::Pending;
|
|
23
|
-
AnyValue result; // Value if fulfilled, reason if rejected
|
|
24
|
-
std::vector<std::function<void(const AnyValue&)>> onFulfilled;
|
|
25
|
-
std::vector<std::function<void(const AnyValue&)>> onRejected;
|
|
26
|
-
|
|
27
|
-
PromiseState(); // Defined in helpers
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
struct JsPromisePromiseType; // Forward declaration
|
|
31
|
-
|
|
32
|
-
struct JsPromise : HeapObject
|
|
33
|
-
{
|
|
34
|
-
using promise_type = JsPromisePromiseType;
|
|
35
|
-
|
|
36
|
-
std::shared_ptr<PromiseState> state;
|
|
37
|
-
std::unordered_map<std::string, AnyValue> props;
|
|
38
|
-
|
|
39
|
-
JsPromise();
|
|
40
|
-
|
|
41
|
-
JsType get_heap_type() const override { return JsType::Promise; }
|
|
42
|
-
|
|
43
|
-
// --- Promise Logic ---
|
|
44
|
-
void resolve(AnyValue value);
|
|
45
|
-
void reject(AnyValue reason);
|
|
46
|
-
void then(std::function<void(AnyValue)> onFulfilled, std::function<void(AnyValue)> onRejected = nullptr);
|
|
47
|
-
|
|
48
|
-
// --- Methods ---
|
|
49
|
-
std::string to_std_string() const;
|
|
50
|
-
AnyValue get_property(const std::string& key, AnyValue thisVal);
|
|
51
|
-
AnyValue set_property(const std::string& key, AnyValue value, AnyValue thisVal);
|
|
52
|
-
|
|
53
|
-
auto operator co_await() const;
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
struct JsPromisePromiseType {
|
|
57
|
-
JsPromise promise;
|
|
58
|
-
|
|
59
|
-
JsPromise get_return_object() { return promise; }
|
|
60
|
-
std::suspend_never initial_suspend() { return {}; }
|
|
61
|
-
std::suspend_never final_suspend() noexcept { return {}; }
|
|
62
|
-
|
|
63
|
-
void return_value(AnyValue val);
|
|
64
|
-
|
|
65
|
-
void unhandled_exception();
|
|
66
|
-
|
|
67
|
-
// await_transform for AnyValue
|
|
68
|
-
auto await_transform(AnyValue value);
|
|
69
|
-
// await_transform for JsPromise
|
|
70
|
-
auto await_transform(const JsPromise& value);
|
|
71
|
-
};
|
|
72
|
-
}
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "types.hpp"
|
|
4
|
+
#include "any_value.hpp"
|
|
5
|
+
#include <vector>
|
|
6
|
+
#include <functional>
|
|
7
|
+
#include <memory>
|
|
8
|
+
#include <variant>
|
|
9
|
+
#include <coroutine>
|
|
10
|
+
#include <unordered_map>
|
|
11
|
+
#include <string>
|
|
12
|
+
|
|
13
|
+
namespace jspp
|
|
14
|
+
{
|
|
15
|
+
// Forward declaration of AnyValue
|
|
16
|
+
class AnyValue;
|
|
17
|
+
|
|
18
|
+
enum class PromiseStatus { Pending, Fulfilled, Rejected };
|
|
19
|
+
|
|
20
|
+
struct PromiseState
|
|
21
|
+
{
|
|
22
|
+
PromiseStatus status = PromiseStatus::Pending;
|
|
23
|
+
AnyValue result; // Value if fulfilled, reason if rejected
|
|
24
|
+
std::vector<std::function<void(const AnyValue&)>> onFulfilled;
|
|
25
|
+
std::vector<std::function<void(const AnyValue&)>> onRejected;
|
|
26
|
+
|
|
27
|
+
PromiseState(); // Defined in helpers
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
struct JsPromisePromiseType; // Forward declaration
|
|
31
|
+
|
|
32
|
+
struct JsPromise : HeapObject
|
|
33
|
+
{
|
|
34
|
+
using promise_type = JsPromisePromiseType;
|
|
35
|
+
|
|
36
|
+
std::shared_ptr<PromiseState> state;
|
|
37
|
+
std::unordered_map<std::string, AnyValue> props;
|
|
38
|
+
|
|
39
|
+
JsPromise();
|
|
40
|
+
|
|
41
|
+
JsType get_heap_type() const override { return JsType::Promise; }
|
|
42
|
+
|
|
43
|
+
// --- Promise Logic ---
|
|
44
|
+
void resolve(AnyValue value);
|
|
45
|
+
void reject(AnyValue reason);
|
|
46
|
+
void then(std::function<void(AnyValue)> onFulfilled, std::function<void(AnyValue)> onRejected = nullptr);
|
|
47
|
+
|
|
48
|
+
// --- Methods ---
|
|
49
|
+
std::string to_std_string() const;
|
|
50
|
+
AnyValue get_property(const std::string& key, AnyValue thisVal);
|
|
51
|
+
AnyValue set_property(const std::string& key, AnyValue value, AnyValue thisVal);
|
|
52
|
+
|
|
53
|
+
auto operator co_await() const;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
struct JsPromisePromiseType {
|
|
57
|
+
JsPromise promise;
|
|
58
|
+
|
|
59
|
+
JsPromise get_return_object() { return promise; }
|
|
60
|
+
std::suspend_never initial_suspend() { return {}; }
|
|
61
|
+
std::suspend_never final_suspend() noexcept { return {}; }
|
|
62
|
+
|
|
63
|
+
void return_value(AnyValue val);
|
|
64
|
+
|
|
65
|
+
void unhandled_exception();
|
|
66
|
+
|
|
67
|
+
// await_transform for AnyValue
|
|
68
|
+
auto await_transform(AnyValue value);
|
|
69
|
+
// await_transform for JsPromise
|
|
70
|
+
auto await_transform(const JsPromise& value);
|
|
71
|
+
};
|
|
72
|
+
}
|
|
@@ -23,7 +23,13 @@ namespace jspp
|
|
|
23
23
|
inline AnyValue &get_iterator_fn()
|
|
24
24
|
{
|
|
25
25
|
static AnyValue fn = AnyValue::make_generator([](AnyValue thisVal, std::vector<AnyValue> _) -> jspp::JsIterator<jspp::AnyValue>
|
|
26
|
-
{
|
|
26
|
+
{
|
|
27
|
+
auto arr = thisVal.as_array();
|
|
28
|
+
for (uint64_t idx = 0; idx < arr->length; ++idx)
|
|
29
|
+
{
|
|
30
|
+
co_yield arr->get_property(static_cast<uint32_t>(idx));
|
|
31
|
+
}
|
|
32
|
+
co_return Constants::UNDEFINED; },
|
|
27
33
|
"Symbol.iterator");
|
|
28
34
|
return fn;
|
|
29
35
|
}
|
|
@@ -430,7 +436,13 @@ namespace jspp
|
|
|
430
436
|
inline AnyValue &get_values_fn()
|
|
431
437
|
{
|
|
432
438
|
static AnyValue fn = AnyValue::make_generator([](AnyValue thisVal, std::vector<AnyValue> _) -> jspp::JsIterator<jspp::AnyValue>
|
|
433
|
-
{
|
|
439
|
+
{
|
|
440
|
+
auto arr = thisVal.as_array();
|
|
441
|
+
for (uint64_t idx = 0; idx < arr->length; ++idx)
|
|
442
|
+
{
|
|
443
|
+
co_yield arr->get_property(static_cast<uint32_t>(idx));
|
|
444
|
+
}
|
|
445
|
+
co_return Constants::UNDEFINED; },
|
|
434
446
|
"values");
|
|
435
447
|
return fn;
|
|
436
448
|
}
|
|
@@ -1,201 +1,201 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#include "types.hpp"
|
|
4
|
-
#include "values/iterator.hpp"
|
|
5
|
-
#include "any_value.hpp"
|
|
6
|
-
#include "exception.hpp"
|
|
7
|
-
#include "utils/operators.hpp"
|
|
8
|
-
|
|
9
|
-
namespace jspp
|
|
10
|
-
{
|
|
11
|
-
namespace IteratorPrototypes
|
|
12
|
-
{
|
|
13
|
-
inline AnyValue &get_toString_fn()
|
|
14
|
-
{
|
|
15
|
-
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
16
|
-
{ return AnyValue::make_string(thisVal.as_iterator()->to_std_string()); },
|
|
17
|
-
"toString");
|
|
18
|
-
return fn;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
inline AnyValue &get_iterator_fn()
|
|
22
|
-
{
|
|
23
|
-
static AnyValue fn = AnyValue::make_generator([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
24
|
-
{ return thisVal; },
|
|
25
|
-
"Symbol.iterator");
|
|
26
|
-
return fn;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
inline AnyValue &get_next_fn()
|
|
30
|
-
{
|
|
31
|
-
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
32
|
-
{
|
|
33
|
-
AnyValue val = args.empty() ? Constants::UNDEFINED : args[0];
|
|
34
|
-
auto res = thisVal.as_iterator()->next(val);
|
|
35
|
-
return AnyValue::make_object({{"value", res.value.value_or(Constants::UNDEFINED)}, {"done", AnyValue::make_boolean(res.done)}}); },
|
|
36
|
-
"next");
|
|
37
|
-
return fn;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
inline AnyValue &get_return_fn()
|
|
41
|
-
{
|
|
42
|
-
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
43
|
-
{
|
|
44
|
-
AnyValue val = args.empty() ? Constants::UNDEFINED : args[0];
|
|
45
|
-
auto res = thisVal.as_iterator()->return_(val);
|
|
46
|
-
return AnyValue::make_object({{"value", res.value.value_or(Constants::UNDEFINED)}, {"done", AnyValue::make_boolean(res.done)}}); },
|
|
47
|
-
"return");
|
|
48
|
-
return fn;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
inline AnyValue &get_throw_fn()
|
|
52
|
-
{
|
|
53
|
-
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
54
|
-
{
|
|
55
|
-
AnyValue err = args.empty() ? Constants::UNDEFINED : args[0];
|
|
56
|
-
auto res = thisVal.as_iterator()->throw_(err);
|
|
57
|
-
return AnyValue::make_object({{"value", res.value.value_or(Constants::UNDEFINED)}, {"done", AnyValue::make_boolean(res.done)}}); },
|
|
58
|
-
"throw");
|
|
59
|
-
return fn;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
inline AnyValue &get_toArray_fn()
|
|
63
|
-
{
|
|
64
|
-
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
65
|
-
{ return AnyValue::make_array(thisVal.as_iterator()->to_vector()); },
|
|
66
|
-
"drop");
|
|
67
|
-
return fn;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
inline AnyValue &get_drop_fn()
|
|
71
|
-
{
|
|
72
|
-
static AnyValue fn = AnyValue::make_generator([](
|
|
73
|
-
{
|
|
74
|
-
auto self = thisVal.as_iterator();
|
|
75
|
-
size_t skip_count = 0;
|
|
76
|
-
if (!args.empty()) {
|
|
77
|
-
skip_count = static_cast<size_t>(args[0].as_double());
|
|
78
|
-
}
|
|
79
|
-
size_t skipped = 0;
|
|
80
|
-
while (true)
|
|
81
|
-
{
|
|
82
|
-
auto next_res = self->next();
|
|
83
|
-
if (next_res.done) { break; }
|
|
84
|
-
if (skipped < skip_count)
|
|
85
|
-
{
|
|
86
|
-
skipped++;
|
|
87
|
-
continue;
|
|
88
|
-
}
|
|
89
|
-
co_yield next_res.value.value_or(Constants::UNDEFINED);
|
|
90
|
-
}
|
|
91
|
-
co_return jspp::Constants::UNDEFINED; },
|
|
92
|
-
"drop");
|
|
93
|
-
return fn;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
inline AnyValue &get_take_fn()
|
|
97
|
-
{
|
|
98
|
-
static AnyValue fn = AnyValue::make_generator([](
|
|
99
|
-
{
|
|
100
|
-
auto self = thisVal.as_iterator();
|
|
101
|
-
size_t take_count = 0;
|
|
102
|
-
if (!args.empty()) {
|
|
103
|
-
take_count = static_cast<size_t>(args[0].as_double());
|
|
104
|
-
}
|
|
105
|
-
size_t taken = 0;
|
|
106
|
-
while (true)
|
|
107
|
-
{
|
|
108
|
-
auto next_res = self->next();
|
|
109
|
-
if (next_res.done) { break; }
|
|
110
|
-
if (taken < take_count)
|
|
111
|
-
{
|
|
112
|
-
taken++;
|
|
113
|
-
co_yield next_res.value.value_or(Constants::UNDEFINED);
|
|
114
|
-
}
|
|
115
|
-
if (taken >= take_count)
|
|
116
|
-
{
|
|
117
|
-
// Call the iterator's return() method for early cleanup of resources
|
|
118
|
-
self->return_();
|
|
119
|
-
break;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
co_return jspp::Constants::UNDEFINED; },
|
|
123
|
-
"take");
|
|
124
|
-
return fn;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
inline AnyValue &get_some_fn()
|
|
128
|
-
{
|
|
129
|
-
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
130
|
-
{
|
|
131
|
-
auto self = thisVal.as_iterator();
|
|
132
|
-
if (args.empty() || !args[0].is_function()) throw Exception::make_exception("callback is not a function", "TypeError");
|
|
133
|
-
auto callback = args[0].as_function();
|
|
134
|
-
while (true)
|
|
135
|
-
{
|
|
136
|
-
auto next_res = self->next();
|
|
137
|
-
if (next_res.done) { break; }
|
|
138
|
-
if (is_truthy(callback->call(thisVal, std::span<const AnyValue>((const jspp::AnyValue[]){next_res.value.value_or(Constants::UNDEFINED)}, 1))))
|
|
139
|
-
{
|
|
140
|
-
// Call the iterator's return() method for early cleanup of resources
|
|
141
|
-
self->return_();
|
|
142
|
-
return Constants::TRUE;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
return jspp::Constants::FALSE; },
|
|
146
|
-
"some");
|
|
147
|
-
return fn;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
inline std::optional<AnyValue> get(const std::string &key)
|
|
151
|
-
{
|
|
152
|
-
// --- toString() method ---
|
|
153
|
-
if (key == "toString" || key == WellKnownSymbols::toStringTag->key)
|
|
154
|
-
{
|
|
155
|
-
return get_toString_fn();
|
|
156
|
-
}
|
|
157
|
-
// --- [Symbol.iterator]() method ---
|
|
158
|
-
if (key == WellKnownSymbols::iterator->key)
|
|
159
|
-
{
|
|
160
|
-
return get_iterator_fn();
|
|
161
|
-
}
|
|
162
|
-
// --- next() method ---
|
|
163
|
-
if (key == "next")
|
|
164
|
-
{
|
|
165
|
-
return get_next_fn();
|
|
166
|
-
}
|
|
167
|
-
// --- return() method ---
|
|
168
|
-
if (key == "return")
|
|
169
|
-
{
|
|
170
|
-
return get_return_fn();
|
|
171
|
-
}
|
|
172
|
-
// --- throw() method ---
|
|
173
|
-
if (key == "throw")
|
|
174
|
-
{
|
|
175
|
-
return get_throw_fn();
|
|
176
|
-
}
|
|
177
|
-
// --- toArray() method ---
|
|
178
|
-
if (key == "toArray")
|
|
179
|
-
{
|
|
180
|
-
return get_toArray_fn();
|
|
181
|
-
}
|
|
182
|
-
// --- drop() method ---
|
|
183
|
-
if (key == "drop")
|
|
184
|
-
{
|
|
185
|
-
return get_drop_fn();
|
|
186
|
-
}
|
|
187
|
-
// --- take() method ---
|
|
188
|
-
if (key == "take")
|
|
189
|
-
{
|
|
190
|
-
return get_take_fn();
|
|
191
|
-
}
|
|
192
|
-
// --- some() method ---
|
|
193
|
-
if (key == "some")
|
|
194
|
-
{
|
|
195
|
-
return get_some_fn();
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
return std::nullopt;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "types.hpp"
|
|
4
|
+
#include "values/iterator.hpp"
|
|
5
|
+
#include "any_value.hpp"
|
|
6
|
+
#include "exception.hpp"
|
|
7
|
+
#include "utils/operators.hpp"
|
|
8
|
+
|
|
9
|
+
namespace jspp
|
|
10
|
+
{
|
|
11
|
+
namespace IteratorPrototypes
|
|
12
|
+
{
|
|
13
|
+
inline AnyValue &get_toString_fn()
|
|
14
|
+
{
|
|
15
|
+
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
16
|
+
{ return AnyValue::make_string(thisVal.as_iterator()->to_std_string()); },
|
|
17
|
+
"toString");
|
|
18
|
+
return fn;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
inline AnyValue &get_iterator_fn()
|
|
22
|
+
{
|
|
23
|
+
static AnyValue fn = AnyValue::make_generator([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
24
|
+
{ return thisVal; },
|
|
25
|
+
"Symbol.iterator");
|
|
26
|
+
return fn;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
inline AnyValue &get_next_fn()
|
|
30
|
+
{
|
|
31
|
+
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
32
|
+
{
|
|
33
|
+
AnyValue val = args.empty() ? Constants::UNDEFINED : args[0];
|
|
34
|
+
auto res = thisVal.as_iterator()->next(val);
|
|
35
|
+
return AnyValue::make_object({{"value", res.value.value_or(Constants::UNDEFINED)}, {"done", AnyValue::make_boolean(res.done)}}); },
|
|
36
|
+
"next");
|
|
37
|
+
return fn;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
inline AnyValue &get_return_fn()
|
|
41
|
+
{
|
|
42
|
+
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
43
|
+
{
|
|
44
|
+
AnyValue val = args.empty() ? Constants::UNDEFINED : args[0];
|
|
45
|
+
auto res = thisVal.as_iterator()->return_(val);
|
|
46
|
+
return AnyValue::make_object({{"value", res.value.value_or(Constants::UNDEFINED)}, {"done", AnyValue::make_boolean(res.done)}}); },
|
|
47
|
+
"return");
|
|
48
|
+
return fn;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
inline AnyValue &get_throw_fn()
|
|
52
|
+
{
|
|
53
|
+
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
54
|
+
{
|
|
55
|
+
AnyValue err = args.empty() ? Constants::UNDEFINED : args[0];
|
|
56
|
+
auto res = thisVal.as_iterator()->throw_(err);
|
|
57
|
+
return AnyValue::make_object({{"value", res.value.value_or(Constants::UNDEFINED)}, {"done", AnyValue::make_boolean(res.done)}}); },
|
|
58
|
+
"throw");
|
|
59
|
+
return fn;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
inline AnyValue &get_toArray_fn()
|
|
63
|
+
{
|
|
64
|
+
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
65
|
+
{ return AnyValue::make_array(thisVal.as_iterator()->to_vector()); },
|
|
66
|
+
"drop");
|
|
67
|
+
return fn;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
inline AnyValue &get_drop_fn()
|
|
71
|
+
{
|
|
72
|
+
static AnyValue fn = AnyValue::make_generator([](AnyValue thisVal, std::vector<AnyValue> args) -> JsIterator<AnyValue>
|
|
73
|
+
{
|
|
74
|
+
auto self = thisVal.as_iterator();
|
|
75
|
+
size_t skip_count = 0;
|
|
76
|
+
if (!args.empty()) {
|
|
77
|
+
skip_count = static_cast<size_t>(args[0].as_double());
|
|
78
|
+
}
|
|
79
|
+
size_t skipped = 0;
|
|
80
|
+
while (true)
|
|
81
|
+
{
|
|
82
|
+
auto next_res = self->next();
|
|
83
|
+
if (next_res.done) { break; }
|
|
84
|
+
if (skipped < skip_count)
|
|
85
|
+
{
|
|
86
|
+
skipped++;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
co_yield next_res.value.value_or(Constants::UNDEFINED);
|
|
90
|
+
}
|
|
91
|
+
co_return jspp::Constants::UNDEFINED; },
|
|
92
|
+
"drop");
|
|
93
|
+
return fn;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
inline AnyValue &get_take_fn()
|
|
97
|
+
{
|
|
98
|
+
static AnyValue fn = AnyValue::make_generator([](AnyValue thisVal, std::vector<AnyValue> args) -> JsIterator<AnyValue>
|
|
99
|
+
{
|
|
100
|
+
auto self = thisVal.as_iterator();
|
|
101
|
+
size_t take_count = 0;
|
|
102
|
+
if (!args.empty()) {
|
|
103
|
+
take_count = static_cast<size_t>(args[0].as_double());
|
|
104
|
+
}
|
|
105
|
+
size_t taken = 0;
|
|
106
|
+
while (true)
|
|
107
|
+
{
|
|
108
|
+
auto next_res = self->next();
|
|
109
|
+
if (next_res.done) { break; }
|
|
110
|
+
if (taken < take_count)
|
|
111
|
+
{
|
|
112
|
+
taken++;
|
|
113
|
+
co_yield next_res.value.value_or(Constants::UNDEFINED);
|
|
114
|
+
}
|
|
115
|
+
if (taken >= take_count)
|
|
116
|
+
{
|
|
117
|
+
// Call the iterator's return() method for early cleanup of resources
|
|
118
|
+
self->return_();
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
co_return jspp::Constants::UNDEFINED; },
|
|
123
|
+
"take");
|
|
124
|
+
return fn;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
inline AnyValue &get_some_fn()
|
|
128
|
+
{
|
|
129
|
+
static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
130
|
+
{
|
|
131
|
+
auto self = thisVal.as_iterator();
|
|
132
|
+
if (args.empty() || !args[0].is_function()) throw Exception::make_exception("callback is not a function", "TypeError");
|
|
133
|
+
auto callback = args[0].as_function();
|
|
134
|
+
while (true)
|
|
135
|
+
{
|
|
136
|
+
auto next_res = self->next();
|
|
137
|
+
if (next_res.done) { break; }
|
|
138
|
+
if (is_truthy(callback->call(thisVal, std::span<const AnyValue>((const jspp::AnyValue[]){next_res.value.value_or(Constants::UNDEFINED)}, 1))))
|
|
139
|
+
{
|
|
140
|
+
// Call the iterator's return() method for early cleanup of resources
|
|
141
|
+
self->return_();
|
|
142
|
+
return Constants::TRUE;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return jspp::Constants::FALSE; },
|
|
146
|
+
"some");
|
|
147
|
+
return fn;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
inline std::optional<AnyValue> get(const std::string &key)
|
|
151
|
+
{
|
|
152
|
+
// --- toString() method ---
|
|
153
|
+
if (key == "toString" || key == WellKnownSymbols::toStringTag->key)
|
|
154
|
+
{
|
|
155
|
+
return get_toString_fn();
|
|
156
|
+
}
|
|
157
|
+
// --- [Symbol.iterator]() method ---
|
|
158
|
+
if (key == WellKnownSymbols::iterator->key)
|
|
159
|
+
{
|
|
160
|
+
return get_iterator_fn();
|
|
161
|
+
}
|
|
162
|
+
// --- next() method ---
|
|
163
|
+
if (key == "next")
|
|
164
|
+
{
|
|
165
|
+
return get_next_fn();
|
|
166
|
+
}
|
|
167
|
+
// --- return() method ---
|
|
168
|
+
if (key == "return")
|
|
169
|
+
{
|
|
170
|
+
return get_return_fn();
|
|
171
|
+
}
|
|
172
|
+
// --- throw() method ---
|
|
173
|
+
if (key == "throw")
|
|
174
|
+
{
|
|
175
|
+
return get_throw_fn();
|
|
176
|
+
}
|
|
177
|
+
// --- toArray() method ---
|
|
178
|
+
if (key == "toArray")
|
|
179
|
+
{
|
|
180
|
+
return get_toArray_fn();
|
|
181
|
+
}
|
|
182
|
+
// --- drop() method ---
|
|
183
|
+
if (key == "drop")
|
|
184
|
+
{
|
|
185
|
+
return get_drop_fn();
|
|
186
|
+
}
|
|
187
|
+
// --- take() method ---
|
|
188
|
+
if (key == "take")
|
|
189
|
+
{
|
|
190
|
+
return get_take_fn();
|
|
191
|
+
}
|
|
192
|
+
// --- some() method ---
|
|
193
|
+
if (key == "some")
|
|
194
|
+
{
|
|
195
|
+
return get_some_fn();
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return std::nullopt;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|