@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.
Files changed (35) hide show
  1. package/dist/core/codegen/class-handlers.js +6 -6
  2. package/dist/core/codegen/statement-handlers.js +1 -1
  3. package/package.json +1 -1
  4. package/src/prelude/any_value.hpp +362 -362
  5. package/src/prelude/any_value_access.hpp +170 -170
  6. package/src/prelude/any_value_defines.hpp +189 -189
  7. package/src/prelude/any_value_helpers.hpp +374 -374
  8. package/src/prelude/library/array.hpp +185 -185
  9. package/src/prelude/library/console.hpp +111 -111
  10. package/src/prelude/library/error.hpp +112 -112
  11. package/src/prelude/library/function.hpp +10 -10
  12. package/src/prelude/library/math.hpp +307 -307
  13. package/src/prelude/library/object.hpp +275 -275
  14. package/src/prelude/library/process.hpp +39 -39
  15. package/src/prelude/library/promise.hpp +123 -123
  16. package/src/prelude/library/symbol.hpp +52 -52
  17. package/src/prelude/library/timer.hpp +91 -91
  18. package/src/prelude/types.hpp +178 -178
  19. package/src/prelude/utils/access.hpp +411 -411
  20. package/src/prelude/utils/operators.hpp +336 -336
  21. package/src/prelude/values/array.hpp +0 -1
  22. package/src/prelude/values/async_iterator.hpp +83 -83
  23. package/src/prelude/values/function.hpp +82 -82
  24. package/src/prelude/values/helpers/array.hpp +198 -208
  25. package/src/prelude/values/helpers/async_iterator.hpp +275 -275
  26. package/src/prelude/values/helpers/function.hpp +108 -108
  27. package/src/prelude/values/helpers/iterator.hpp +144 -144
  28. package/src/prelude/values/helpers/promise.hpp +253 -253
  29. package/src/prelude/values/helpers/string.hpp +37 -61
  30. package/src/prelude/values/promise.hpp +72 -72
  31. package/src/prelude/values/prototypes/array.hpp +14 -2
  32. package/src/prelude/values/prototypes/iterator.hpp +201 -201
  33. package/src/prelude/values/prototypes/promise.hpp +196 -196
  34. package/src/prelude/values/prototypes/string.hpp +564 -542
  35. package/src/prelude/values/string.hpp +25 -26
@@ -1,275 +1,275 @@
1
- #pragma once
2
-
3
- #include "types.hpp"
4
- #include "values/async_iterator.hpp"
5
- #include "any_value.hpp"
6
- #include "values/prototypes/async_iterator.hpp"
7
-
8
- // --- JsAsyncIterator methods ---
9
-
10
- template <typename T>
11
- std::string jspp::JsAsyncIterator<T>::to_std_string() const
12
- {
13
- return "[object AsyncGenerator]";
14
- }
15
-
16
- template <typename T>
17
- jspp::AnyValue jspp::JsAsyncIterator<T>::get_property(const std::string &key, AnyValue thisVal)
18
- {
19
- auto it = props.find(key);
20
- if (it == props.end())
21
- {
22
- if constexpr (std::is_same_v<T, AnyValue>)
23
- {
24
- auto proto_it = AsyncIteratorPrototypes::get(key);
25
- if (proto_it.has_value())
26
- {
27
- return AnyValue::resolve_property_for_read(proto_it.value(), thisVal, key);
28
- }
29
- }
30
- return Constants::UNDEFINED;
31
- }
32
- return AnyValue::resolve_property_for_read(it->second, thisVal, key);
33
- }
34
-
35
- template <typename T>
36
- jspp::AnyValue jspp::JsAsyncIterator<T>::set_property(const std::string &key, AnyValue value, AnyValue thisVal)
37
- {
38
- if constexpr (std::is_same_v<T, AnyValue>)
39
- {
40
- auto proto_it = AsyncIteratorPrototypes::get(key);
41
- if (proto_it.has_value())
42
- {
43
- auto proto_value = proto_it.value();
44
- if (proto_value.is_accessor_descriptor())
45
- {
46
- return AnyValue::resolve_property_for_write(proto_value, thisVal, value, key);
47
- }
48
- if (proto_value.is_data_descriptor() && !proto_value.as_data_descriptor()->writable)
49
- {
50
- return AnyValue::resolve_property_for_write(proto_value, thisVal, value, key);
51
- }
52
- }
53
- }
54
-
55
- auto it = props.find(key);
56
- if (it != props.end())
57
- {
58
- return jspp::AnyValue::resolve_property_for_write(it->second, thisVal, value, key);
59
- }
60
- else
61
- {
62
- props[key] = value;
63
- return value;
64
- }
65
- }
66
-
67
- template <typename T>
68
- void jspp::JsAsyncIterator<T>::resume_next()
69
- {
70
- if (!handle || handle.done())
71
- return;
72
- auto &p = handle.promise();
73
- if (p.is_awaiting || p.is_running)
74
- return;
75
- if (p.pending_calls.empty())
76
- return;
77
-
78
- p.is_running = true;
79
-
80
- auto &next_call = p.pending_calls.front();
81
- p.current_input = next_call.second;
82
-
83
- handle.resume();
84
-
85
- p.is_running = false;
86
-
87
- // After yield/return, if more calls are pending, handle them.
88
- if (!p.pending_calls.empty() && !p.is_awaiting && !handle.done())
89
- {
90
- this->ref();
91
- Scheduler::instance().enqueue([this]()
92
- {
93
- this->resume_next();
94
- this->deref();
95
- });
96
- }
97
- }
98
-
99
- template <typename T>
100
- jspp::JsPromise jspp::JsAsyncIterator<T>::next(const T &val)
101
- {
102
- // JsPromise is now a HeapObject.
103
- // We should return it by value (which AnyValue will then wrap).
104
- // Wait, coroutines return JsPromise by value.
105
- JsPromise p;
106
- if (handle)
107
- {
108
- if (handle.done())
109
- {
110
- p.resolve(AnyValue::make_object({{"value", Constants::UNDEFINED}, {"done", Constants::TRUE}}));
111
- }
112
- else
113
- {
114
- handle.promise().pending_calls.push({p, val});
115
- resume_next();
116
- }
117
- }
118
- else
119
- {
120
- p.resolve(AnyValue::make_object({{"value", Constants::UNDEFINED}, {"done", Constants::TRUE}}));
121
- }
122
- return p;
123
- }
124
-
125
- // --- JsAsyncIterator::promise_type methods ---
126
-
127
- template <typename T>
128
- template <typename From>
129
- auto jspp::JsAsyncIterator<T>::promise_type::yield_value(From &&from)
130
- {
131
- if (!pending_calls.empty())
132
- {
133
- auto call = pending_calls.front();
134
- pending_calls.pop();
135
- AnyValue result = AnyValue::make_object({{"value", std::forward<From>(from)}, {"done", Constants::FALSE}});
136
- call.first.resolve(result);
137
- }
138
-
139
- struct YieldAwaiter
140
- {
141
- promise_type &p;
142
- bool await_ready() { return false; }
143
- void await_suspend(std::coroutine_handle<promise_type> h)
144
- {
145
- // Suspended at yield.
146
- }
147
- T await_resume() { return p.current_input; }
148
- };
149
- return YieldAwaiter{*this};
150
- }
151
-
152
- template <typename T>
153
- template <typename From>
154
- void jspp::JsAsyncIterator<T>::promise_type::return_value(From &&from)
155
- {
156
- if (!pending_calls.empty())
157
- {
158
- auto call = pending_calls.front();
159
- pending_calls.pop();
160
- AnyValue result = AnyValue::make_object({{"value", std::forward<From>(from)}, {"done", Constants::TRUE}});
161
- call.first.resolve(result);
162
- }
163
-
164
- while (!pending_calls.empty())
165
- {
166
- auto call = pending_calls.front();
167
- pending_calls.pop();
168
- AnyValue result = AnyValue::make_object({{"value", Constants::UNDEFINED}, {"done", Constants::TRUE}});
169
- call.first.resolve(result);
170
- }
171
- }
172
-
173
- template <typename T>
174
- void jspp::JsAsyncIterator<T>::promise_type::fail_all(const AnyValue &reason)
175
- {
176
- while (!pending_calls.empty())
177
- {
178
- auto call = pending_calls.front();
179
- pending_calls.pop();
180
- call.first.reject(reason);
181
- }
182
- }
183
-
184
- template <typename T>
185
- void jspp::JsAsyncIterator<T>::promise_type::unhandled_exception()
186
- {
187
- try
188
- {
189
- std::rethrow_exception(std::current_exception());
190
- }
191
- catch (const Exception &e)
192
- {
193
- fail_all(e.data);
194
- }
195
- catch (const std::exception &e)
196
- {
197
- fail_all(AnyValue::make_string(e.what()));
198
- }
199
- catch (...)
200
- {
201
- fail_all(AnyValue::make_string("Unknown error in async generator"));
202
- }
203
- }
204
-
205
- template <typename T>
206
- auto jspp::JsAsyncIterator<T>::promise_type::await_transform(AnyValue value)
207
- {
208
- is_awaiting = true;
209
- struct AsyncIterAwaiter
210
- {
211
- AnyValueAwaiter base_awaiter;
212
- promise_type &p_ref;
213
-
214
- bool await_ready() { return base_awaiter.await_ready(); }
215
- void await_suspend(std::coroutine_handle<promise_type> h)
216
- {
217
- if (!base_awaiter.value.is_promise())
218
- {
219
- jspp::Scheduler::instance().enqueue([h]() mutable
220
- {
221
- auto &pr = h.promise();
222
- pr.is_awaiting = false;
223
- pr.is_running = true;
224
- h.resume();
225
- pr.is_running = false;
226
-
227
- if (!h.done() && !pr.is_awaiting && !pr.pending_calls.empty())
228
- {
229
- while (!h.done() && !pr.is_awaiting && !pr.pending_calls.empty())
230
- {
231
- pr.is_running = true;
232
- pr.current_input = pr.pending_calls.front().second;
233
- h.resume();
234
- pr.is_running = false;
235
- }
236
- } });
237
- return;
238
- }
239
- auto p = base_awaiter.value.as_promise();
240
- p->then(
241
- [h](AnyValue v) mutable
242
- {
243
- auto &pr = h.promise();
244
- pr.is_awaiting = false;
245
- pr.is_running = true;
246
- h.resume();
247
- pr.is_running = false;
248
-
249
- if (!h.done() && !pr.is_awaiting && !pr.pending_calls.empty())
250
- {
251
- while (!h.done() && !pr.is_awaiting && !pr.pending_calls.empty())
252
- {
253
- pr.is_running = true;
254
- pr.current_input = pr.pending_calls.front().second;
255
- h.resume();
256
- pr.is_running = false;
257
- }
258
- }
259
- },
260
- [h](AnyValue e) mutable
261
- {
262
- auto &pr = h.promise();
263
- pr.is_awaiting = false;
264
- pr.is_running = true;
265
- h.resume();
266
- pr.is_running = false;
267
- });
268
- }
269
- AnyValue await_resume()
270
- {
271
- return base_awaiter.await_resume();
272
- }
273
- };
274
- return AsyncIterAwaiter{AnyValueAwaiter{std::move(value)}, *this};
275
- }
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+ #include "values/async_iterator.hpp"
5
+ #include "any_value.hpp"
6
+ #include "values/prototypes/async_iterator.hpp"
7
+
8
+ // --- JsAsyncIterator methods ---
9
+
10
+ template <typename T>
11
+ std::string jspp::JsAsyncIterator<T>::to_std_string() const
12
+ {
13
+ return "[object AsyncGenerator]";
14
+ }
15
+
16
+ template <typename T>
17
+ jspp::AnyValue jspp::JsAsyncIterator<T>::get_property(const std::string &key, AnyValue thisVal)
18
+ {
19
+ auto it = props.find(key);
20
+ if (it == props.end())
21
+ {
22
+ if constexpr (std::is_same_v<T, AnyValue>)
23
+ {
24
+ auto proto_it = AsyncIteratorPrototypes::get(key);
25
+ if (proto_it.has_value())
26
+ {
27
+ return AnyValue::resolve_property_for_read(proto_it.value(), thisVal, key);
28
+ }
29
+ }
30
+ return Constants::UNDEFINED;
31
+ }
32
+ return AnyValue::resolve_property_for_read(it->second, thisVal, key);
33
+ }
34
+
35
+ template <typename T>
36
+ jspp::AnyValue jspp::JsAsyncIterator<T>::set_property(const std::string &key, AnyValue value, AnyValue thisVal)
37
+ {
38
+ if constexpr (std::is_same_v<T, AnyValue>)
39
+ {
40
+ auto proto_it = AsyncIteratorPrototypes::get(key);
41
+ if (proto_it.has_value())
42
+ {
43
+ auto proto_value = proto_it.value();
44
+ if (proto_value.is_accessor_descriptor())
45
+ {
46
+ return AnyValue::resolve_property_for_write(proto_value, thisVal, value, key);
47
+ }
48
+ if (proto_value.is_data_descriptor() && !proto_value.as_data_descriptor()->writable)
49
+ {
50
+ return AnyValue::resolve_property_for_write(proto_value, thisVal, value, key);
51
+ }
52
+ }
53
+ }
54
+
55
+ auto it = props.find(key);
56
+ if (it != props.end())
57
+ {
58
+ return jspp::AnyValue::resolve_property_for_write(it->second, thisVal, value, key);
59
+ }
60
+ else
61
+ {
62
+ props[key] = value;
63
+ return value;
64
+ }
65
+ }
66
+
67
+ template <typename T>
68
+ void jspp::JsAsyncIterator<T>::resume_next()
69
+ {
70
+ if (!handle || handle.done())
71
+ return;
72
+ auto &p = handle.promise();
73
+ if (p.is_awaiting || p.is_running)
74
+ return;
75
+ if (p.pending_calls.empty())
76
+ return;
77
+
78
+ p.is_running = true;
79
+
80
+ auto &next_call = p.pending_calls.front();
81
+ p.current_input = next_call.second;
82
+
83
+ handle.resume();
84
+
85
+ p.is_running = false;
86
+
87
+ // After yield/return, if more calls are pending, handle them.
88
+ if (!p.pending_calls.empty() && !p.is_awaiting && !handle.done())
89
+ {
90
+ this->ref();
91
+ Scheduler::instance().enqueue([this]()
92
+ {
93
+ this->resume_next();
94
+ this->deref();
95
+ });
96
+ }
97
+ }
98
+
99
+ template <typename T>
100
+ jspp::JsPromise jspp::JsAsyncIterator<T>::next(const T &val)
101
+ {
102
+ // JsPromise is now a HeapObject.
103
+ // We should return it by value (which AnyValue will then wrap).
104
+ // Wait, coroutines return JsPromise by value.
105
+ JsPromise p;
106
+ if (handle)
107
+ {
108
+ if (handle.done())
109
+ {
110
+ p.resolve(AnyValue::make_object({{"value", Constants::UNDEFINED}, {"done", Constants::TRUE}}));
111
+ }
112
+ else
113
+ {
114
+ handle.promise().pending_calls.push({p, val});
115
+ resume_next();
116
+ }
117
+ }
118
+ else
119
+ {
120
+ p.resolve(AnyValue::make_object({{"value", Constants::UNDEFINED}, {"done", Constants::TRUE}}));
121
+ }
122
+ return p;
123
+ }
124
+
125
+ // --- JsAsyncIterator::promise_type methods ---
126
+
127
+ template <typename T>
128
+ template <typename From>
129
+ auto jspp::JsAsyncIterator<T>::promise_type::yield_value(From &&from)
130
+ {
131
+ if (!pending_calls.empty())
132
+ {
133
+ auto call = pending_calls.front();
134
+ pending_calls.pop();
135
+ AnyValue result = AnyValue::make_object({{"value", std::forward<From>(from)}, {"done", Constants::FALSE}});
136
+ call.first.resolve(result);
137
+ }
138
+
139
+ struct YieldAwaiter
140
+ {
141
+ promise_type &p;
142
+ bool await_ready() { return false; }
143
+ void await_suspend(std::coroutine_handle<promise_type> h)
144
+ {
145
+ // Suspended at yield.
146
+ }
147
+ T await_resume() { return p.current_input; }
148
+ };
149
+ return YieldAwaiter{*this};
150
+ }
151
+
152
+ template <typename T>
153
+ template <typename From>
154
+ void jspp::JsAsyncIterator<T>::promise_type::return_value(From &&from)
155
+ {
156
+ if (!pending_calls.empty())
157
+ {
158
+ auto call = pending_calls.front();
159
+ pending_calls.pop();
160
+ AnyValue result = AnyValue::make_object({{"value", std::forward<From>(from)}, {"done", Constants::TRUE}});
161
+ call.first.resolve(result);
162
+ }
163
+
164
+ while (!pending_calls.empty())
165
+ {
166
+ auto call = pending_calls.front();
167
+ pending_calls.pop();
168
+ AnyValue result = AnyValue::make_object({{"value", Constants::UNDEFINED}, {"done", Constants::TRUE}});
169
+ call.first.resolve(result);
170
+ }
171
+ }
172
+
173
+ template <typename T>
174
+ void jspp::JsAsyncIterator<T>::promise_type::fail_all(const AnyValue &reason)
175
+ {
176
+ while (!pending_calls.empty())
177
+ {
178
+ auto call = pending_calls.front();
179
+ pending_calls.pop();
180
+ call.first.reject(reason);
181
+ }
182
+ }
183
+
184
+ template <typename T>
185
+ void jspp::JsAsyncIterator<T>::promise_type::unhandled_exception()
186
+ {
187
+ try
188
+ {
189
+ std::rethrow_exception(std::current_exception());
190
+ }
191
+ catch (const Exception &e)
192
+ {
193
+ fail_all(e.data);
194
+ }
195
+ catch (const std::exception &e)
196
+ {
197
+ fail_all(AnyValue::make_string(e.what()));
198
+ }
199
+ catch (...)
200
+ {
201
+ fail_all(AnyValue::make_string("Unknown error in async generator"));
202
+ }
203
+ }
204
+
205
+ template <typename T>
206
+ auto jspp::JsAsyncIterator<T>::promise_type::await_transform(AnyValue value)
207
+ {
208
+ is_awaiting = true;
209
+ struct AsyncIterAwaiter
210
+ {
211
+ AnyValueAwaiter base_awaiter;
212
+ promise_type &p_ref;
213
+
214
+ bool await_ready() { return base_awaiter.await_ready(); }
215
+ void await_suspend(std::coroutine_handle<promise_type> h)
216
+ {
217
+ if (!base_awaiter.value.is_promise())
218
+ {
219
+ jspp::Scheduler::instance().enqueue([h]() mutable
220
+ {
221
+ auto &pr = h.promise();
222
+ pr.is_awaiting = false;
223
+ pr.is_running = true;
224
+ h.resume();
225
+ pr.is_running = false;
226
+
227
+ if (!h.done() && !pr.is_awaiting && !pr.pending_calls.empty())
228
+ {
229
+ while (!h.done() && !pr.is_awaiting && !pr.pending_calls.empty())
230
+ {
231
+ pr.is_running = true;
232
+ pr.current_input = pr.pending_calls.front().second;
233
+ h.resume();
234
+ pr.is_running = false;
235
+ }
236
+ } });
237
+ return;
238
+ }
239
+ auto p = base_awaiter.value.as_promise();
240
+ p->then(
241
+ [h](AnyValue v) mutable
242
+ {
243
+ auto &pr = h.promise();
244
+ pr.is_awaiting = false;
245
+ pr.is_running = true;
246
+ h.resume();
247
+ pr.is_running = false;
248
+
249
+ if (!h.done() && !pr.is_awaiting && !pr.pending_calls.empty())
250
+ {
251
+ while (!h.done() && !pr.is_awaiting && !pr.pending_calls.empty())
252
+ {
253
+ pr.is_running = true;
254
+ pr.current_input = pr.pending_calls.front().second;
255
+ h.resume();
256
+ pr.is_running = false;
257
+ }
258
+ }
259
+ },
260
+ [h](AnyValue e) mutable
261
+ {
262
+ auto &pr = h.promise();
263
+ pr.is_awaiting = false;
264
+ pr.is_running = true;
265
+ h.resume();
266
+ pr.is_running = false;
267
+ });
268
+ }
269
+ AnyValue await_resume()
270
+ {
271
+ return base_awaiter.await_resume();
272
+ }
273
+ };
274
+ return AsyncIterAwaiter{AnyValueAwaiter{std::move(value)}, *this};
275
+ }