@ugo-studio/jspp 0.2.9 → 0.3.1

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 (97) hide show
  1. package/LICENSE +25 -25
  2. package/README.md +20 -12
  3. package/dist/analysis/scope.js +5 -3
  4. package/dist/analysis/typeAnalyzer.js +21 -25
  5. package/dist/cli/index.js +14 -4
  6. package/dist/cli/utils.js +61 -0
  7. package/dist/core/codegen/class-handlers.js +6 -6
  8. package/dist/core/codegen/control-flow-handlers.js +10 -9
  9. package/dist/core/codegen/declaration-handlers.js +10 -3
  10. package/dist/core/codegen/destructuring-handlers.js +9 -4
  11. package/dist/core/codegen/expression-handlers.js +40 -29
  12. package/dist/core/codegen/function-handlers.js +78 -12
  13. package/dist/core/codegen/helpers.js +91 -14
  14. package/dist/core/codegen/index.js +4 -2
  15. package/dist/core/codegen/statement-handlers.js +9 -7
  16. package/package.json +2 -2
  17. package/scripts/precompile-headers.ts +249 -50
  18. package/scripts/setup-compiler.ts +63 -63
  19. package/src/prelude/any_value.cpp +636 -0
  20. package/src/prelude/any_value.hpp +369 -362
  21. package/src/prelude/{exception_helpers.hpp → exception.cpp} +53 -53
  22. package/src/prelude/exception.hpp +27 -27
  23. package/src/prelude/iterator_instantiations.hpp +10 -0
  24. package/src/prelude/{index.hpp → jspp.hpp} +10 -16
  25. package/src/prelude/library/array.cpp +191 -0
  26. package/src/prelude/library/array.hpp +13 -186
  27. package/src/prelude/library/console.cpp +125 -0
  28. package/src/prelude/library/console.hpp +24 -112
  29. package/src/prelude/library/error.cpp +100 -0
  30. package/src/prelude/library/error.hpp +13 -113
  31. package/src/prelude/library/function.cpp +69 -0
  32. package/src/prelude/library/function.hpp +11 -10
  33. package/src/prelude/library/global.cpp +96 -0
  34. package/src/prelude/library/global.hpp +12 -28
  35. package/src/prelude/library/global_usings.hpp +15 -0
  36. package/src/prelude/library/math.cpp +258 -0
  37. package/src/prelude/library/math.hpp +26 -308
  38. package/src/prelude/library/object.cpp +379 -0
  39. package/src/prelude/library/object.hpp +14 -276
  40. package/src/prelude/library/performance.cpp +21 -0
  41. package/src/prelude/library/performance.hpp +5 -20
  42. package/src/prelude/library/process.cpp +38 -0
  43. package/src/prelude/library/process.hpp +11 -39
  44. package/src/prelude/library/promise.cpp +131 -0
  45. package/src/prelude/library/promise.hpp +12 -123
  46. package/src/prelude/library/symbol.cpp +56 -0
  47. package/src/prelude/library/symbol.hpp +11 -52
  48. package/src/prelude/library/timer.cpp +88 -0
  49. package/src/prelude/library/timer.hpp +16 -92
  50. package/src/prelude/runtime.cpp +19 -0
  51. package/src/prelude/types.hpp +184 -179
  52. package/src/prelude/utils/access.hpp +502 -411
  53. package/src/prelude/utils/assignment_operators.hpp +99 -99
  54. package/src/prelude/utils/log_any_value/array.hpp +61 -40
  55. package/src/prelude/utils/log_any_value/function.hpp +39 -39
  56. package/src/prelude/utils/log_any_value/object.hpp +60 -3
  57. package/src/prelude/utils/operators.hpp +351 -336
  58. package/src/prelude/utils/operators_primitive.hpp +336 -336
  59. package/src/prelude/utils/well_known_symbols.hpp +24 -24
  60. package/src/prelude/values/array.cpp +1399 -0
  61. package/src/prelude/values/array.hpp +4 -1
  62. package/src/prelude/values/async_iterator.cpp +251 -0
  63. package/src/prelude/values/async_iterator.hpp +111 -83
  64. package/src/prelude/values/function.cpp +262 -0
  65. package/src/prelude/values/function.hpp +62 -82
  66. package/src/prelude/values/iterator.cpp +309 -0
  67. package/src/prelude/values/iterator.hpp +33 -64
  68. package/src/prelude/values/number.cpp +176 -0
  69. package/src/prelude/values/object.cpp +159 -0
  70. package/src/prelude/values/object.hpp +4 -0
  71. package/src/prelude/values/promise.cpp +479 -0
  72. package/src/prelude/values/promise.hpp +79 -72
  73. package/src/prelude/values/prototypes/array.hpp +46 -1336
  74. package/src/prelude/values/prototypes/async_iterator.hpp +19 -61
  75. package/src/prelude/values/prototypes/function.hpp +7 -46
  76. package/src/prelude/values/prototypes/iterator.hpp +25 -201
  77. package/src/prelude/values/prototypes/number.hpp +23 -210
  78. package/src/prelude/values/prototypes/object.hpp +7 -23
  79. package/src/prelude/values/prototypes/promise.hpp +18 -196
  80. package/src/prelude/values/prototypes/string.hpp +39 -542
  81. package/src/prelude/values/prototypes/symbol.hpp +9 -70
  82. package/src/prelude/values/shape.hpp +52 -52
  83. package/src/prelude/values/string.cpp +485 -0
  84. package/src/prelude/values/string.hpp +25 -26
  85. package/src/prelude/values/symbol.cpp +89 -0
  86. package/src/prelude/values/symbol.hpp +101 -101
  87. package/src/prelude/any_value_access.hpp +0 -170
  88. package/src/prelude/any_value_defines.hpp +0 -190
  89. package/src/prelude/any_value_helpers.hpp +0 -374
  90. package/src/prelude/values/helpers/array.hpp +0 -209
  91. package/src/prelude/values/helpers/async_iterator.hpp +0 -275
  92. package/src/prelude/values/helpers/function.hpp +0 -109
  93. package/src/prelude/values/helpers/iterator.hpp +0 -145
  94. package/src/prelude/values/helpers/object.hpp +0 -104
  95. package/src/prelude/values/helpers/promise.hpp +0 -254
  96. package/src/prelude/values/helpers/string.hpp +0 -61
  97. package/src/prelude/values/helpers/symbol.hpp +0 -21
@@ -1,276 +1,14 @@
1
- #pragma once
2
-
3
- #include "types.hpp"
4
- #include "any_value.hpp"
5
- #include "utils/access.hpp"
6
- #include "exception.hpp"
7
-
8
- // Define Object constructor
9
- inline auto Object = jspp::AnyValue::make_class([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
10
- {
11
- if (args.empty() || args[0].is_undefined() || args[0].is_null()) {
12
- return jspp::AnyValue::make_object({});
13
- }
14
- // Return argument if it is an object
15
- if (args[0].is_object() || args[0].is_array() || args[0].is_function() || args[0].is_promise() || args[0].is_iterator()) {
16
- return args[0];
17
- }
18
- // TODO: Wrapper objects for primitives
19
- return jspp::AnyValue::make_object({}); }, "Object");
20
-
21
- struct ObjectInit
22
- {
23
- ObjectInit()
24
- {
25
- // Object.keys(obj)
26
- Object.define_data_property("keys", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
27
- {
28
- if (args.empty()) throw jspp::Exception::make_exception("Object.keys called on non-object", "TypeError");
29
- auto obj = args[0];
30
- if (obj.is_null() || obj.is_undefined()) throw jspp::Exception::make_exception("Object.keys called on null or undefined", "TypeError");
31
-
32
- auto keys = jspp::Access::get_object_keys(obj);
33
- std::vector<jspp::AnyValue> keyValues;
34
- for(const auto& k : keys) {
35
- keyValues.push_back(jspp::AnyValue::make_string(k));
36
- }
37
- return jspp::AnyValue::make_array(std::move(keyValues)); }, "keys"));
38
-
39
- // Object.values(obj)
40
- Object.define_data_property("values", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
41
- {
42
- if (args.empty()) throw jspp::Exception::make_exception("Object.values called on non-object", "TypeError");
43
- auto obj = args[0];
44
- if (obj.is_null() || obj.is_undefined()) throw jspp::Exception::make_exception("Object.values called on null or undefined", "TypeError");
45
-
46
- auto keys = jspp::Access::get_object_keys(obj);
47
- std::vector<jspp::AnyValue> values;
48
- for(const auto& k : keys) {
49
- values.push_back(obj.get_property_with_receiver(k, obj));
50
- }
51
- return jspp::AnyValue::make_array(std::move(values)); }, "values"));
52
-
53
- // Object.entries(obj)
54
- Object.define_data_property("entries", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
55
- {
56
- if (args.empty()) throw jspp::Exception::make_exception("Object.entries called on non-object", "TypeError");
57
- auto obj = args[0];
58
- if (obj.is_null() || obj.is_undefined()) throw jspp::Exception::make_exception("Object.entries called on null or undefined", "TypeError");
59
-
60
- auto keys = jspp::Access::get_object_keys(obj);
61
- std::vector<jspp::AnyValue> entries;
62
- for(const auto& k : keys) {
63
- std::vector<jspp::AnyValue> entry;
64
- entry.push_back(jspp::AnyValue::make_string(k));
65
- entry.push_back(obj.get_property_with_receiver(k, obj));
66
- entries.push_back(jspp::AnyValue::make_array(std::move(entry)));
67
- }
68
- return jspp::AnyValue::make_array(std::move(entries)); }, "entries"));
69
-
70
- // Object.assign(target, ...sources)
71
- Object.define_data_property("assign", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
72
- {
73
- if (args.empty()) throw jspp::Exception::make_exception("Cannot convert undefined or null to object", "TypeError");
74
- auto target = args[0];
75
- if (target.is_null() || target.is_undefined()) throw jspp::Exception::make_exception("Cannot convert undefined or null to object", "TypeError");
76
-
77
- for (size_t i = 1; i < args.size(); ++i) {
78
- auto source = args[i];
79
- if (source.is_null() || source.is_undefined()) continue;
80
-
81
- auto keys = jspp::Access::get_object_keys(source);
82
- for(const auto& k : keys) {
83
- auto val = source.get_property_with_receiver(k, source);
84
- target.set_own_property(k, val);
85
- }
86
- }
87
- return target; }, "assign"));
88
-
89
- // Object.is(value1, value2)
90
- Object.define_data_property("is", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
91
- {
92
- jspp::AnyValue v1 = args.size() > 0 ? args[0] : jspp::Constants::UNDEFINED;
93
- jspp::AnyValue v2 = args.size() > 1 ? args[1] : jspp::Constants::UNDEFINED;
94
-
95
- if (v1.is_number() && v2.is_number()) {
96
- double d1 = v1.as_double();
97
- double d2 = v2.as_double();
98
- if (std::isnan(d1) && std::isnan(d2)) return jspp::Constants::TRUE;
99
- if (d1 == 0 && d2 == 0) {
100
- return jspp::AnyValue::make_boolean(std::signbit(d1) == std::signbit(d2));
101
- }
102
- return jspp::AnyValue::make_boolean(d1 == d2);
103
- }
104
-
105
- return jspp::is_strictly_equal_to(v1, v2); }, "is"));
106
-
107
- // Object.getPrototypeOf(obj)
108
- Object.define_data_property("getPrototypeOf", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
109
- {
110
- if (args.empty()) throw jspp::Exception::make_exception("Object.getPrototypeOf called on non-object", "TypeError");
111
- auto obj = args[0];
112
-
113
- if (obj.is_object()) {
114
- return obj.as_object()->proto;
115
- }
116
- if (obj.is_array()) {
117
- return obj.as_array()->proto;
118
- }
119
- if (obj.is_function()) {
120
- return obj.as_function()->proto;
121
- }
122
-
123
- return jspp::Constants::Null; }, "getPrototypeOf"));
124
-
125
- // Object.setPrototypeOf(obj, proto)
126
- Object.define_data_property("setPrototypeOf", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
127
- {
128
- if (args.size() < 2) throw jspp::Exception::make_exception("Object.setPrototypeOf requires at least 2 arguments", "TypeError");
129
- auto obj = args[0];
130
- auto proto = args[1];
131
-
132
- if (!proto.is_object() && !proto.is_null()) {
133
- throw jspp::Exception::make_exception("Object prototype may only be an Object or null", "TypeError");
134
- }
135
-
136
- if (obj.is_object()) {
137
- obj.as_object()->proto = proto;
138
- } else if (obj.is_array()) {
139
- obj.as_array()->proto = proto;
140
- } else if (obj.is_function()) {
141
- obj.as_function()->proto = proto;
142
- }
143
-
144
- return obj; }, "setPrototypeOf"));
145
-
146
- // Object.create(proto, [propertiesObject])
147
- Object.define_data_property("create", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
148
- {
149
- if (args.empty()) throw jspp::Exception::make_exception("Object prototype may only be an Object or null", "TypeError");
150
- auto proto = args[0];
151
- if (!proto.is_object() && !proto.is_null()) {
152
- throw jspp::Exception::make_exception("Object prototype may only be an Object or null", "TypeError");
153
- }
154
-
155
- auto newObj = jspp::AnyValue::make_object_with_proto({}, proto);
156
-
157
- if (args.size() > 1 && !args[1].is_undefined()) {
158
- // Object.defineProperties(newObj, propertiesObject)
159
- // TODO: implement defineProperties logic if needed.
160
- }
161
-
162
- return newObj; }, "create"));
163
-
164
- // Object.defineProperty(obj, prop, descriptor)
165
- Object.define_data_property("defineProperty", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
166
- {
167
- if (args.size() < 3) throw jspp::Exception::make_exception("Object.defineProperty requires 3 arguments", "TypeError");
168
- auto obj = args[0];
169
- if (!obj.is_object() && !obj.is_array() && !obj.is_function()) throw jspp::Exception::make_exception("Object.defineProperty called on non-object", "TypeError");
170
-
171
- std::string prop = args[1].to_std_string();
172
- auto descObj = args[2];
173
-
174
- bool enumerable = false;
175
- bool configurable = false;
176
- bool writable = false;
177
-
178
- if (descObj.has_property("enumerable")) enumerable = jspp::is_truthy(descObj.get_own_property("enumerable"));
179
- if (descObj.has_property("configurable")) configurable = jspp::is_truthy(descObj.get_own_property("configurable"));
180
- if (descObj.has_property("writable")) writable = jspp::is_truthy(descObj.get_own_property("writable"));
181
-
182
- bool hasValue = descObj.has_property("value");
183
- bool hasGet = descObj.has_property("get");
184
- bool hasSet = descObj.has_property("set");
185
-
186
- if (hasValue && (hasGet || hasSet)) {
187
- throw jspp::Exception::make_exception("Invalid property descriptor. Cannot both specify accessors and a value or writable attribute", "TypeError");
188
- }
189
-
190
- if (hasValue) {
191
- auto value = descObj.get_own_property("value");
192
- obj.define_data_property(prop, value, writable, enumerable, configurable);
193
- } else {
194
- jspp::AnyValue getter = jspp::Constants::UNDEFINED;
195
- jspp::AnyValue setter = jspp::Constants::UNDEFINED;
196
-
197
- if (hasGet) getter = descObj.get_own_property("get");
198
- if (hasSet) setter = descObj.get_own_property("set");
199
-
200
- if (!getter.is_undefined() && !getter.is_function()) throw jspp::Exception::make_exception("Getter must be a function: " + getter.to_std_string(), "TypeError");
201
- if (!setter.is_undefined() && !setter.is_function()) throw jspp::Exception::make_exception("Setter must be a function", "TypeError");
202
-
203
- if (obj.is_object()) {
204
- auto o_ptr = obj.as_object();
205
- std::optional<std::function<jspp::AnyValue(jspp::AnyValue, std::span<const jspp::AnyValue>)>> getFunc;
206
- std::optional<std::function<jspp::AnyValue(jspp::AnyValue, std::span<const jspp::AnyValue>)>> setFunc;
207
-
208
- if (getter.is_function()) {
209
- getFunc = [getter](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue {
210
- return getter.call(thisVal, args);
211
- };
212
- }
213
- if (setter.is_function()) {
214
- setFunc = [setter](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue {
215
- return setter.call(thisVal, args);
216
- };
217
- }
218
-
219
- auto desc = jspp::AnyValue::make_accessor_descriptor(getFunc, setFunc, enumerable, configurable);
220
- auto offset = o_ptr->shape->get_offset(prop);
221
- if (offset.has_value()) {
222
- o_ptr->storage[offset.value()] = desc;
223
- } else {
224
- o_ptr->shape = o_ptr->shape->transition(prop);
225
- o_ptr->storage.push_back(desc);
226
- }
227
- }
228
- }
229
-
230
- return obj; }, "defineProperty"));
231
-
232
- // Object.hasOwn(obj, prop)
233
- Object.define_data_property("hasOwn", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
234
- {
235
- if (args.empty()) throw jspp::Exception::make_exception("Object.hasOwn called on non-object", "TypeError");
236
- auto obj = args[0];
237
- if (obj.is_null() || obj.is_undefined()) throw jspp::Exception::make_exception("Object.hasOwn called on null or undefined", "TypeError");
238
- std::string prop = args.size() > 1 ? args[1].to_std_string() : "undefined";
239
-
240
- if (obj.is_object()) return jspp::AnyValue::make_boolean(obj.as_object()->shape->get_offset(prop).has_value());
241
- if (obj.is_function()) return jspp::AnyValue::make_boolean(obj.as_function()->props.count(prop));
242
- if (obj.is_array()) {
243
- if (prop == "length") return jspp::Constants::TRUE;
244
- if (jspp::JsArray::is_array_index(prop)) {
245
- uint32_t idx = static_cast<uint32_t>(std::stoull(prop));
246
- auto arr = obj.as_array();
247
- if (idx < arr->dense.size() && !(arr->dense[idx].is_uninitialized())) return jspp::Constants::TRUE;
248
- if (arr->sparse.count(idx)) return jspp::Constants::TRUE;
249
- return jspp::Constants::FALSE;
250
- }
251
- return jspp::AnyValue::make_boolean(obj.as_array()->props.count(prop));
252
- }
253
-
254
- return jspp::Constants::FALSE; }, "hasOwn"));
255
-
256
- // Object.prototype.hasOwnProperty
257
- auto proto = Object.get_own_property("prototype");
258
- proto.define_data_property("hasOwnProperty", jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
259
- {
260
- std::string prop = args.size() > 0 ? args[0].to_std_string() : "undefined";
261
- if (thisVal.is_object()) return jspp::AnyValue::make_boolean(thisVal.as_object()->shape->get_offset(prop).has_value());
262
- if (thisVal.is_function()) return jspp::AnyValue::make_boolean(thisVal.as_function()->props.count(prop));
263
- if (thisVal.is_array()) {
264
- if (prop == "length") return jspp::Constants::TRUE;
265
- if (jspp::JsArray::is_array_index(prop)) {
266
- uint32_t idx = static_cast<uint32_t>(std::stoull(prop));
267
- auto arr = thisVal.as_array();
268
- if (idx < arr->dense.size() && !(arr->dense[idx].is_uninitialized())) return jspp::Constants::TRUE;
269
- if (arr->sparse.count(idx)) return jspp::Constants::TRUE;
270
- return jspp::Constants::FALSE;
271
- }
272
- return jspp::AnyValue::make_boolean(thisVal.as_array()->props.count(prop));
273
- }
274
- return jspp::Constants::FALSE; }, "hasOwnProperty"));
275
- }
276
- } objectInit;
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+ #include "any_value.hpp"
5
+ #include "utils/access.hpp"
6
+ #include "exception.hpp"
7
+
8
+ namespace jspp
9
+ {
10
+ extern AnyValue Object;
11
+ void init_object();
12
+ }
13
+
14
+ using jspp::Object;
@@ -0,0 +1,21 @@
1
+ #include "jspp.hpp"
2
+ #include "library/performance.hpp"
3
+ #include <chrono>
4
+
5
+ namespace jspp
6
+ {
7
+
8
+ AnyValue performance = jspp::AnyValue::make_object({
9
+ {"now",
10
+ jspp::AnyValue::make_function(
11
+ [startTime = std::chrono::steady_clock::now()](jspp::AnyValue, std::span<const jspp::AnyValue>)
12
+ {
13
+ std::chrono::duration<double, std::milli> duration =
14
+ std::chrono::steady_clock::now() - startTime;
15
+
16
+ return jspp::AnyValue::make_number(duration.count());
17
+ },
18
+ "now")},
19
+ });
20
+
21
+ } // namespace jspp
@@ -1,25 +1,10 @@
1
1
  #pragma once
2
2
 
3
- #include <chrono>
4
3
  #include "types.hpp"
5
- #include "values/non_values.hpp"
6
- #include "values/object.hpp"
7
- #include "values/function.hpp"
8
- #include "utils/operators.hpp"
4
+ #include "any_value.hpp"
9
5
 
10
- inline auto performance = jspp::AnyValue::make_object({
11
- {"now",
12
- jspp::AnyValue::make_function(
13
- // [C++14 Feature] Generalized Lambda Capture
14
- // We initialize 'startTime' RIGHT HERE inside the [].
15
- // It acts like a private variable stored inside this specific function.
16
- [startTime = std::chrono::steady_clock::now()](jspp::AnyValue, std::span<const jspp::AnyValue>)
17
- {
18
- // We calculate the diff against the captured startTime
19
- std::chrono::duration<double, std::milli> duration =
20
- std::chrono::steady_clock::now() - startTime;
6
+ namespace jspp {
7
+ extern AnyValue performance;
8
+ }
21
9
 
22
- return jspp::AnyValue::make_number(duration.count());
23
- },
24
- "now")},
25
- });
10
+ using jspp::performance;
@@ -0,0 +1,38 @@
1
+ #include "jspp.hpp"
2
+ #include "library/process.hpp"
3
+
4
+ #ifdef _WIN32
5
+ #define JSPP_PLATFORM "win32"
6
+ #else
7
+ #define JSPP_PLATFORM "linux"
8
+ #endif
9
+
10
+ namespace jspp {
11
+
12
+ AnyValue process = jspp::AnyValue::make_object({
13
+ {"argv", jspp::AnyValue::make_array(std::vector<jspp::AnyValue>{})},
14
+ {"env", jspp::AnyValue::make_object({})},
15
+ {"platform", jspp::AnyValue::make_string(JSPP_PLATFORM)},
16
+ {"exit", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue {
17
+ int code = 0;
18
+ if (!args.empty() && args[0].is_number()) {
19
+ code = static_cast<int>(args[0].as_double());
20
+ }
21
+ std::exit(code);
22
+ return jspp::Constants::UNDEFINED;
23
+ }, "exit")}
24
+ });
25
+
26
+ void setup_process_argv(int argc, char** argv) {
27
+ std::vector<jspp::AnyValue> args;
28
+ if (argc > 0) {
29
+ args.push_back(jspp::AnyValue::make_string(argv[0]));
30
+ args.push_back(jspp::AnyValue::make_string("index.js"));
31
+ for (int i = 1; i < argc; ++i) {
32
+ args.push_back(jspp::AnyValue::make_string(argv[i]));
33
+ }
34
+ }
35
+ process.set_own_property("argv", jspp::AnyValue::make_array(std::move(args)));
36
+ }
37
+
38
+ } // namespace jspp
@@ -1,39 +1,11 @@
1
- #pragma once
2
-
3
- #include "types.hpp"
4
- #include "any_value.hpp"
5
-
6
- #ifdef _WIN32
7
- #define JSPP_PLATFORM "win32"
8
- #else
9
- #define JSPP_PLATFORM "linux"
10
- #endif
11
-
12
- inline auto process = jspp::AnyValue::make_object({
13
- {"argv", jspp::AnyValue::make_array(std::vector<jspp::AnyValue>{})},
14
- {"env", jspp::AnyValue::make_object({})},
15
- {"platform", jspp::AnyValue::make_string(JSPP_PLATFORM)},
16
- {"exit", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue {
17
- int code = 0;
18
- if (!args.empty() && args[0].is_number()) {
19
- code = static_cast<int>(args[0].as_double());
20
- }
21
- std::exit(code);
22
- return jspp::Constants::UNDEFINED;
23
- }, "exit")}
24
- });
25
-
26
- namespace jspp {
27
- inline void setup_process_argv(int argc, char** argv) {
28
- std::vector<jspp::AnyValue> args;
29
- if (argc > 0) {
30
- args.push_back(jspp::AnyValue::make_string(argv[0]));
31
- args.push_back(jspp::AnyValue::make_string("index.js"));
32
- for (int i = 1; i < argc; ++i) {
33
- args.push_back(jspp::AnyValue::make_string(argv[i]));
34
- }
35
- }
36
- process.set_own_property("argv", jspp::AnyValue::make_array(std::move(args)));
37
- }
38
- }
39
-
1
+ #pragma once
2
+
3
+ #include "types.hpp"
4
+ #include "any_value.hpp"
5
+
6
+ namespace jspp {
7
+ extern AnyValue process;
8
+ void setup_process_argv(int argc, char** argv);
9
+ }
10
+
11
+ using jspp::process;
@@ -0,0 +1,131 @@
1
+ #include "jspp.hpp"
2
+ #include "library/promise.hpp"
3
+
4
+ namespace jspp
5
+ {
6
+ jspp::AnyValue Promise = jspp::AnyValue::make_function(
7
+ std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
8
+ {
9
+ if (args.empty() || !args[0].is_function())
10
+ {
11
+ throw jspp::Exception::make_exception("Promise resolver undefined is not a function", "TypeError");
12
+ }
13
+ auto executor = args[0].as_function();
14
+
15
+ jspp::JsPromise promise;
16
+ auto state = promise.state; // Share state
17
+
18
+ // resolve function
19
+ auto resolveFn = jspp::AnyValue::make_function(
20
+ std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([state](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
21
+ {
22
+ jspp::JsPromise p; p.state = state;
23
+ p.resolve(args.empty() ? jspp::Constants::UNDEFINED : args[0]);
24
+ return jspp::Constants::UNDEFINED;
25
+ }), "resolve");
26
+
27
+ // reject function
28
+ auto rejectFn = jspp::AnyValue::make_function(
29
+ std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([state](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
30
+ {
31
+ jspp::JsPromise p; p.state = state;
32
+ p.reject(args.empty() ? jspp::Constants::UNDEFINED : args[0]);
33
+ return jspp::Constants::UNDEFINED;
34
+ }), "reject");
35
+
36
+ try
37
+ {
38
+ const jspp::AnyValue executorArgs[] = {resolveFn, rejectFn};
39
+ executor->call(jspp::Constants::UNDEFINED, std::span<const jspp::AnyValue>(executorArgs, 2));
40
+ }
41
+ catch (const jspp::Exception &e)
42
+ {
43
+ promise.reject(e.data);
44
+ }
45
+ catch (...)
46
+ {
47
+ promise.reject(jspp::AnyValue::make_string("Unknown error during Promise execution"));
48
+ }
49
+
50
+ return jspp::AnyValue::make_promise(promise); }),
51
+ "Promise");
52
+
53
+ struct PromiseInit
54
+ {
55
+ PromiseInit()
56
+ {
57
+ Promise.define_data_property("resolve", jspp::AnyValue::make_function(
58
+ std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
59
+ {
60
+ jspp::JsPromise p;
61
+ p.resolve(args.empty() ? jspp::Constants::UNDEFINED : args[0]);
62
+ return jspp::AnyValue::make_promise(p); }),
63
+ "resolve"));
64
+
65
+ Promise.define_data_property("reject", jspp::AnyValue::make_function(
66
+ std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
67
+ {
68
+ jspp::JsPromise p;
69
+ p.reject(args.empty() ? jspp::Constants::UNDEFINED : args[0]);
70
+ return jspp::AnyValue::make_promise(p); }),
71
+ "reject"));
72
+
73
+ Promise.define_data_property("all", jspp::AnyValue::make_function(
74
+ std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
75
+ {
76
+ if (args.empty() || !args[0].is_array()) {
77
+ jspp::JsPromise p; p.reject(jspp::AnyValue::make_string("Promise.all argument must be an array"));
78
+ return jspp::AnyValue::make_promise(p);
79
+ }
80
+
81
+ auto arr = args[0].as_array();
82
+ size_t len = static_cast<size_t>(arr->length);
83
+ if (len == 0) {
84
+ jspp::JsPromise p; p.resolve(jspp::AnyValue::make_array(std::vector<jspp::AnyValue>()));
85
+ return jspp::AnyValue::make_promise(p);
86
+ }
87
+
88
+ jspp::JsPromise masterPromise;
89
+ auto masterState = masterPromise.state;
90
+
91
+ auto results = std::make_shared<std::vector<jspp::AnyValue>>(len, jspp::Constants::UNDEFINED);
92
+ auto count = std::make_shared<size_t>(len);
93
+ auto rejected = std::make_shared<bool>(false);
94
+
95
+ for (size_t i = 0; i < len; ++i) {
96
+ jspp::AnyValue item = arr->get_property(static_cast<uint32_t>(i));
97
+
98
+ auto handleResult = [masterState, results, count, i, rejected](jspp::AnyValue res) {
99
+ if (*rejected) return;
100
+ (*results)[i] = res;
101
+ (*count)--;
102
+ if (*count == 0) {
103
+ jspp::JsPromise p; p.state = masterState;
104
+ p.resolve(jspp::AnyValue::make_array(std::move(*results)));
105
+ }
106
+ };
107
+
108
+ auto handleReject = [masterState, rejected](jspp::AnyValue reason) {
109
+ if (*rejected) return;
110
+ *rejected = true;
111
+ jspp::JsPromise p; p.state = masterState;
112
+ masterState->status = jspp::PromiseStatus::Rejected;
113
+ p.reject(reason);
114
+ };
115
+
116
+ if (item.is_promise()) {
117
+ item.as_promise()->then(handleResult, handleReject);
118
+ } else {
119
+ handleResult(item);
120
+ }
121
+ }
122
+
123
+ return jspp::AnyValue::make_promise(masterPromise); }),
124
+ "all"));
125
+ }
126
+ };
127
+ void init_promise()
128
+ {
129
+ static PromiseInit promiseInit;
130
+ }
131
+ }